Merge branch 'develop' into spike/JAL-4047/JAL-4048_columns_in_sequenceID spike/JAL-4047/JAL-4048_columns_in_sequenceID
authorJames Procter <j.procter@dundee.ac.uk>
Thu, 14 Sep 2023 09:16:21 +0000 (10:16 +0100)
committerJames Procter <j.procter@dundee.ac.uk>
Thu, 14 Sep 2023 09:16:21 +0000 (10:16 +0100)
555 files changed:
.gitignore
THIRDPARTYLIBS
build.gradle
examples/AlphaFold/AF-Q5VSL9-F1-predicted_aligned_error_v4_2023.json [deleted file]
examples/argfiles/test_fab41-B.txt [new file with mode: 0644]
examples/argfiles/test_fab41-autocounter.txt [new file with mode: 0644]
examples/argfiles/test_fab41.txt [new file with mode: 0644]
examples/argfiles/test_fab41_nostructureviewers.txt [new file with mode: 0644]
examples/test_fab41.result/argfile.txt [new file with mode: 0644]
examples/testdata/7WKP-rna1.xml [new file with mode: 0644]
getdown/lib/FJVL_VERSION
getdown/lib/JVL_VERSION
getdown/lib/getdown-core.jar
getdown/lib/getdown-launcher-local.jar
getdown/lib/getdown-launcher.jar
getdown/src/getdown/ant/pom.xml
getdown/src/getdown/core/pom.xml
getdown/src/getdown/core/src/main/java/com/threerings/getdown/util/LaunchUtil.java
getdown/src/getdown/core/src/main/java/jalview/bin/HiDPISetting.java
getdown/src/getdown/core/src/main/java/jalview/bin/MemorySetting.java
getdown/src/getdown/core/src/main/java/jalview/bin/ScreenInfo.java
getdown/src/getdown/core/src/main/java/jalview/util/ChannelProperties.java
getdown/src/getdown/core/src/main/java/jalview/util/LaunchUtils.java
getdown/src/getdown/core/src/main/java/jalview/util/StringUtils.java
getdown/src/getdown/launcher/pom.xml
getdown/src/getdown/mvn_cmd
getdown/src/getdown/pom.xml
gradle.properties
help/help/help.jhm
help/help/helpTOC.xml
help/help/html/colourSchemes/index.html
help/help/html/features/annotationsFormat.html
help/help/html/features/biojsmsa.html
help/help/html/features/clarguments-advanced.html [new file with mode: 0644]
help/help/html/features/clarguments-argfiles.html [new file with mode: 0644]
help/help/html/features/clarguments-basic.html [new file with mode: 0644]
help/help/html/features/clarguments-old.html [new file with mode: 0644]
help/help/html/features/clarguments-reference.html [new file with mode: 0644]
help/help/html/features/clarguments.html
help/help/html/features/commandline.html
help/help/html/features/featuresFormat.html
help/help/html/features/groovy.html
help/help/html/features/importvcf.html
help/help/html/io/export.html
help/help/html/logging.html
help/help/html/memory.html
help/help/html/menus/alignmentMenu.html
help/help/html/menus/alwcolour.html
help/help/html/privacy.html
help/help/icons/jalview_docs_logo.png [new file with mode: 0644]
help/markdown/releases/release-2_11_2_7.md [new file with mode: 0644]
help/markdown/releases/release-2_11_3_0.md
help/markdown/whatsnew/whatsnew-2_11_2_7.md [new file with mode: 0644]
help/markdown/whatsnew/whatsnew-2_11_3_0.md
j11lib/JGoogleAnalytics_0.3.jar [deleted file]
j11lib/flatlaf-3.0.jar [deleted file]
j11lib/flatlaf-3.2.jar [new file with mode: 0644]
j11lib/flatlaf-extras-3.0.jar [deleted file]
j11lib/flatlaf-extras-3.2.jar [new file with mode: 0644]
j11lib/getdown-core.jar
j11lib/jfreesvg-2.1.jar [deleted file]
j11lib/jfreesvg-3.4.3.jar [new file with mode: 0644]
j11lib/slf4j-api-1.7.32.jar [deleted file]
j11lib/slf4j-api-1.7.36.jar [new file with mode: 0644]
j11lib/slf4j-nop-1.7.36.jar [new file with mode: 0644]
j8lib/JGoogleAnalytics_0.3.jar [deleted file]
j8lib/flatlaf-3.0.jar [deleted file]
j8lib/flatlaf-3.2.jar [new file with mode: 0644]
j8lib/flatlaf-extras-3.0.jar [deleted file]
j8lib/flatlaf-extras-3.2.jar [new file with mode: 0644]
j8lib/getdown-core.jar
j8lib/jfreesvg-2.1.jar [deleted file]
j8lib/jfreesvg-3.4.3.jar [new file with mode: 0644]
j8lib/slf4j-api-1.7.32.jar [deleted file]
j8lib/slf4j-api-1.7.36.jar [new file with mode: 0644]
j8lib/slf4j-nop-1.7.36.jar [new file with mode: 0644]
resources/lang/Messages.properties
resources/lang/Messages_es.properties
schemas/vamsas.xsd
src/jalview/analysis/AAFrequency.java
src/jalview/analysis/AlignSeq.java
src/jalview/analysis/AlignmentSorter.java
src/jalview/analysis/AlignmentUtils.java
src/jalview/analysis/AnnotationSorter.java
src/jalview/analysis/AverageDistanceEngine.java
src/jalview/analysis/Conservation.java
src/jalview/analysis/CrossRef.java
src/jalview/analysis/Dna.java
src/jalview/analysis/GeneticCodes.java
src/jalview/analysis/Grouping.java
src/jalview/analysis/ParseProperties.java
src/jalview/analysis/Rna.java
src/jalview/analysis/SeqsetUtils.java
src/jalview/analysis/StructureFrequency.java
src/jalview/analysis/TreeEngine.java
src/jalview/analysis/TreeModel.java
src/jalview/analysis/scoremodels/FeatureDistanceModel.java
src/jalview/analysis/scoremodels/ScoreMatrix.java
src/jalview/analysis/scoremodels/ScoreModels.java
src/jalview/analytics/Plausible.java [new file with mode: 0644]
src/jalview/api/AlignViewportI.java
src/jalview/api/RotatableCanvasI.java
src/jalview/api/SequenceRenderer.java
src/jalview/api/structures/JalviewStructureDisplayI.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AlignViewport.java
src/jalview/appletgui/AlignmentPanel.java
src/jalview/appletgui/AppletJmol.java
src/jalview/appletgui/ExtJmol.java
src/jalview/appletgui/PCAPanel.java
src/jalview/appletgui/PairwiseAlignPanel.java
src/jalview/appletgui/RedundancyPanel.java
src/jalview/appletgui/RotatableCanvas.java
src/jalview/appletgui/SeqCanvas.java
src/jalview/appletgui/SeqPanel.java
src/jalview/appletgui/SequenceRenderer.java
src/jalview/appletgui/TreeCanvas.java
src/jalview/appletgui/TreePanel.java
src/jalview/bin/ArgParser.java [deleted file]
src/jalview/bin/ArgsParser.java
src/jalview/bin/Cache.java
src/jalview/bin/Commands.java
src/jalview/bin/Console.java
src/jalview/bin/GetMemory.java
src/jalview/bin/HiDPISetting.java
src/jalview/bin/Jalview.java
src/jalview/bin/JalviewLite.java
src/jalview/bin/JalviewLiteURLRetrieve.java
src/jalview/bin/JalviewTaskbar.java
src/jalview/bin/Launcher.java
src/jalview/bin/MemorySetting.java
src/jalview/bin/argparser/Arg.java [new file with mode: 0644]
src/jalview/bin/argparser/ArgParser.java [new file with mode: 0644]
src/jalview/bin/argparser/ArgValue.java [new file with mode: 0644]
src/jalview/bin/argparser/ArgValues.java [new file with mode: 0644]
src/jalview/bin/argparser/ArgValuesMap.java [new file with mode: 0644]
src/jalview/bin/argparser/BootstrapArgs.java [new file with mode: 0644]
src/jalview/bin/argparser/SubVals.java [new file with mode: 0644]
src/jalview/commands/EditCommand.java
src/jalview/datamodel/AlignedCodonFrame.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentAnnotation.java
src/jalview/datamodel/AlignmentView.java
src/jalview/datamodel/BinaryNode.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/datamodel/ContactListI.java
src/jalview/datamodel/ContactListImpl.java
src/jalview/datamodel/ContactListProviderI.java
src/jalview/datamodel/ContactMapHolder.java
src/jalview/datamodel/ContactMatrix.java
src/jalview/datamodel/ContactMatrixI.java
src/jalview/datamodel/ContactRange.java
src/jalview/datamodel/DBRefSource.java
src/jalview/datamodel/GroupSet.java [new file with mode: 0644]
src/jalview/datamodel/GroupSetI.java [new file with mode: 0644]
src/jalview/datamodel/HiddenSequences.java
src/jalview/datamodel/SearchResults.java
src/jalview/datamodel/SeqDistanceContactMatrix.java
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/datamodel/SequenceI.java
src/jalview/datamodel/SequenceNode.java
src/jalview/datamodel/annotations/AnnotationRowBuilder.java
src/jalview/datamodel/features/FeatureMatcher.java
src/jalview/datamodel/features/FeatureMatcherSet.java
src/jalview/datamodel/features/FeatureStore.java
src/jalview/datamodel/features/SequenceFeatures.java
src/jalview/ext/ensembl/EnsemblGene.java
src/jalview/ext/ensembl/EnsemblLookup.java
src/jalview/ext/ensembl/EnsemblMap.java
src/jalview/ext/ensembl/EnsemblRestClient.java
src/jalview/ext/ensembl/EnsemblSeqProxy.java
src/jalview/ext/htsjdk/HtsContigDb.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/ext/paradise/Annotate3D.java
src/jalview/ext/pymol/PymolManager.java
src/jalview/ext/rbvi/chimera/ChimeraListener.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/fts/core/FTSDataColumnPreferences.java
src/jalview/fts/core/GFTSPanel.java
src/jalview/fts/service/alphafold/AlphafoldRestClient.java
src/jalview/fts/service/pdb/PDBFTSRestClient.java
src/jalview/fts/service/threedbeacons/TDBeaconsFTSPanel.java
src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java
src/jalview/fts/service/uniprot/UniProtFTSRestClient.java
src/jalview/gui/AlignExportOptions.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/AnnotationColourChooser.java
src/jalview/gui/AnnotationColumnChooser.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/AppJmol.java
src/jalview/gui/AppJmolBinding.java
src/jalview/gui/AppVarna.java
src/jalview/gui/AppVarnaBinding.java
src/jalview/gui/AssociatePdbFileWithSeq.java
src/jalview/gui/BlogReader.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/ColourMenuHelper.java
src/jalview/gui/Console.java
src/jalview/gui/CrossRefAction.java
src/jalview/gui/Desktop.java
src/jalview/gui/EditNameDialog.java
src/jalview/gui/FeatureEditor.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/FeatureTypeSettings.java
src/jalview/gui/Help.java
src/jalview/gui/IdCanvas.java
src/jalview/gui/IdwidthAdjuster.java
src/jalview/gui/ImageExporter.java
src/jalview/gui/JDatabaseTree.java
src/jalview/gui/JvOptionPane.java
src/jalview/gui/LineartOptions.java
src/jalview/gui/OptsAndParamsPage.java
src/jalview/gui/OverviewCanvas.java
src/jalview/gui/PCAPanel.java
src/jalview/gui/PaintRefresher.java
src/jalview/gui/PairwiseAlignPanel.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/Preferences.java
src/jalview/gui/ProgressBar.java
src/jalview/gui/PymolBindingModel.java
src/jalview/gui/QuitHandler.java
src/jalview/gui/RedundancyPanel.java
src/jalview/gui/RestInputParamEditDialog.java
src/jalview/gui/RestServiceEditorPane.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqCanvas.java.broken
src/jalview/gui/SeqPanel.java
src/jalview/gui/SequenceFetcher.java
src/jalview/gui/SequenceRenderer.java
src/jalview/gui/SplashScreen.java
src/jalview/gui/SplitFrame.java
src/jalview/gui/StructureChooser.java
src/jalview/gui/StructureViewer.java
src/jalview/gui/StructureViewerBase.java
src/jalview/gui/TextColourChooser.java
src/jalview/gui/TreeCanvas.java
src/jalview/gui/TreePanel.java
src/jalview/gui/UserDefinedColours.java
src/jalview/gui/VamsasApplication.java
src/jalview/gui/WebserviceInfo.java
src/jalview/gui/WsJobParameters.java
src/jalview/gui/structurechooser/PDBStructureChooserQuerySource.java
src/jalview/gui/structurechooser/StructureChooserQuerySource.java
src/jalview/gui/structurechooser/TDBResultAnalyser.java
src/jalview/gui/structurechooser/ThreeDBStructureChooserQuerySource.java
src/jalview/httpserver/AbstractRequestHandler.java
src/jalview/httpserver/HttpServer.java
src/jalview/io/AlignFile.java
src/jalview/io/AnnotationFile.java
src/jalview/io/AppletFormatAdapter.java
src/jalview/io/BackupFilenameFilter.java
src/jalview/io/BackupFiles.java
src/jalview/io/BioJsHTMLOutput.java
src/jalview/io/ClustalFile.java
src/jalview/io/FeaturesFile.java
src/jalview/io/FileFormat.java
src/jalview/io/FileFormats.java
src/jalview/io/FileLoader.java
src/jalview/io/FileParse.java
src/jalview/io/HTMLOutput.java
src/jalview/io/HtmlSvgOutput.java
src/jalview/io/IdentifyFile.java
src/jalview/io/JPredFile.java
src/jalview/io/JSONFile.java
src/jalview/io/JalviewFileChooser.java
src/jalview/io/JalviewFileFilter.java
src/jalview/io/JalviewFileView.java
src/jalview/io/MSFfile.java
src/jalview/io/NewickFile.java
src/jalview/io/PContactPredictionFile.java
src/jalview/io/PIRFile.java
src/jalview/io/PfamFile.java
src/jalview/io/PhylipFile.java
src/jalview/io/RnamlFile.java
src/jalview/io/SequenceAnnotationReport.java
src/jalview/io/SimpleBlastFile.java
src/jalview/io/StockholmFile.java
src/jalview/io/StructureFile.java
src/jalview/io/TCoffeeScoreFile.java
src/jalview/io/VamsasAppDatastore.java
src/jalview/io/WSWUBlastClient.java
src/jalview/io/cache/JvCacheableInputBox.java
src/jalview/io/exceptions/ImageOutputException.java [new file with mode: 0644]
src/jalview/io/gff/ExonerateHelper.java
src/jalview/io/gff/Gff3Helper.java
src/jalview/io/gff/GffHelperBase.java
src/jalview/io/gff/SequenceOntologyLite.java
src/jalview/io/packed/JalviewDataset.java
src/jalview/io/packed/ParsePackedSet.java
src/jalview/io/vamsas/Sequencemapping.java
src/jalview/io/vamsas/Tree.java
src/jalview/io/vcf/VCFLoader.java
src/jalview/javascript/JSFunctionExec.java
src/jalview/javascript/JsSelectionSender.java
src/jalview/javascript/MouseOverListener.java
src/jalview/javascript/MouseOverStructureListener.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/jbgui/GAlignmentPanel.java
src/jalview/jbgui/GCutAndPasteHtmlTransfer.java
src/jalview/jbgui/GCutAndPasteTransfer.java
src/jalview/jbgui/GDesktop.java
src/jalview/jbgui/GPCAPanel.java
src/jalview/jbgui/GPreferences.java
src/jalview/jbgui/GRnaStructureViewer.java
src/jalview/jbgui/GSplitFrame.java
src/jalview/jbgui/GStructureChooser.java
src/jalview/jbgui/GStructureViewer.java
src/jalview/jbgui/GTreePanel.java
src/jalview/log/JLogger.java
src/jalview/math/Matrix.java
src/jalview/math/RotatableMatrix.java
src/jalview/project/Jalview2XML.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/renderer/AnnotationRendererFactory.java
src/jalview/renderer/ContactGeometry.java
src/jalview/renderer/ContactMapRenderer.java
src/jalview/renderer/OverviewResColourFinder.java
src/jalview/renderer/api/AnnotationRowRendererI.java
src/jalview/renderer/seqfeatures/FeatureRenderer.java
src/jalview/rest/RestHandler.java
src/jalview/schemes/ColourSchemeLoader.java
src/jalview/schemes/ColourSchemes.java
src/jalview/schemes/Consensus.java
src/jalview/schemes/CovariationColourScheme.java
src/jalview/schemes/FeatureColour.java
src/jalview/schemes/JalviewColourScheme.java
src/jalview/schemes/RNAHelicesColour.java
src/jalview/schemes/ResidueProperties.java
src/jalview/schemes/UserColourScheme.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/structures/models/AAStructureBindingModel.java
src/jalview/urls/IdentifiersUrlProvider.java
src/jalview/urls/UrlProvider.java
src/jalview/util/AWTConsole.java
src/jalview/util/ArrayUtils.java
src/jalview/util/ChannelProperties.java
src/jalview/util/ColorUtils.java
src/jalview/util/Comparison.java
src/jalview/util/DBRefUtils.java
src/jalview/util/FileUtils.java [new file with mode: 0644]
src/jalview/util/GroupUrlLink.java
src/jalview/util/HttpUtils.java
src/jalview/util/ImageMaker.java
src/jalview/util/LaunchUtils.java
src/jalview/util/Log4j.java
src/jalview/util/Platform.java
src/jalview/util/StringUtils.java
src/jalview/util/UrlLink.java
src/jalview/util/dialogrunner/DialogRunnerI.java
src/jalview/util/imagemaker/BitmapImageSizing.java [new file with mode: 0644]
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/viewmodel/ViewportRanges.java
src/jalview/viewmodel/styles/ViewStyle.java
src/jalview/workers/AlignCalcManager.java
src/jalview/workers/AlignmentAnnotationFactory.java
src/jalview/workers/ConsensusThread.java
src/jalview/ws/AWSThread.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/JobStateSummary.java
src/jalview/ws/datamodel/MappableContactMatrixI.java [new file with mode: 0644]
src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java [new file with mode: 0644]
src/jalview/ws/datamodel/alphafold/PAEContactMatrix.java
src/jalview/ws/dbsources/EBIAlfaFold.java
src/jalview/ws/dbsources/EbiFileRetrievedProxy.java
src/jalview/ws/dbsources/EmblXmlSource.java
src/jalview/ws/dbsources/Pdb.java
src/jalview/ws/ebi/EBIFetchClient.java
src/jalview/ws/jws1/Annotate3D.java
src/jalview/ws/jws1/Discoverer.java
src/jalview/ws/jws1/JPredThread.java
src/jalview/ws/jws1/MsaWSThread.java
src/jalview/ws/jws1/SeqSearchWSThread.java
src/jalview/ws/jws2/AbstractJabaCalcWorker.java
src/jalview/ws/jws2/JabaParamStore.java
src/jalview/ws/jws2/JabaWsServerQuery.java
src/jalview/ws/jws2/JabawsCalcWorker.java
src/jalview/ws/jws2/JabawsMsaInterfaceAlignCalcWorker.java
src/jalview/ws/jws2/Jws2Discoverer.java
src/jalview/ws/jws2/MsaWSThread.java
src/jalview/ws/jws2/ParameterUtils.java
src/jalview/ws/jws2/jabaws2/Jws2Instance.java
src/jalview/ws/rest/InputType.java
src/jalview/ws/rest/RestClient.java
src/jalview/ws/rest/RestJobThread.java
src/jalview/ws/seqfetcher/ASequenceFetcher.java
src/jalview/ws/sifts/SiftsClient.java
src/jalview/ws/utils/UrlDownloadClient.java
src/jalview/xml/binding/embl/EntrySetType.java
src/jalview/xml/binding/embl/EntryType.java
src/jalview/xml/binding/embl/ObjectFactory.java
src/jalview/xml/binding/embl/ROOT.java
src/jalview/xml/binding/embl/XrefType.java
src/jalview/xml/binding/jalview/AlcodonFrame.java
src/jalview/xml/binding/jalview/Annotation.java
src/jalview/xml/binding/jalview/AnnotationColourScheme.java
src/jalview/xml/binding/jalview/AnnotationElement.java
src/jalview/xml/binding/jalview/DoubleMatrix.java
src/jalview/xml/binding/jalview/DoubleVector.java
src/jalview/xml/binding/jalview/Feature.java
src/jalview/xml/binding/jalview/FeatureMatcher.java
src/jalview/xml/binding/jalview/FeatureMatcherSet.java
src/jalview/xml/binding/jalview/FilterBy.java
src/jalview/xml/binding/jalview/JalviewModel.java
src/jalview/xml/binding/jalview/JalviewUserColours.java
src/jalview/xml/binding/jalview/MapListType.java
src/jalview/xml/binding/jalview/Mapping.java
src/jalview/xml/binding/jalview/MatrixType.java
src/jalview/xml/binding/jalview/NoValueColour.java
src/jalview/xml/binding/jalview/ObjectFactory.java
src/jalview/xml/binding/jalview/PcaDataType.java
src/jalview/xml/binding/jalview/Pdbentry.java
src/jalview/xml/binding/jalview/Property.java
src/jalview/xml/binding/jalview/Sequence.java
src/jalview/xml/binding/jalview/SequenceSet.java
src/jalview/xml/binding/jalview/SequenceType.java
src/jalview/xml/binding/jalview/ThresholdType.java
src/jalview/xml/binding/jalview/VAMSAS.java
src/jalview/xml/binding/jalview/WebServiceParameterSet.java
src/jalview/xml/binding/jalview/package-info.java
src/jalview/xml/binding/uniprot/CitationType.java
src/jalview/xml/binding/uniprot/CofactorType.java
src/jalview/xml/binding/uniprot/CommentType.java
src/jalview/xml/binding/uniprot/ConsortiumType.java
src/jalview/xml/binding/uniprot/DbReferenceType.java
src/jalview/xml/binding/uniprot/Entry.java
src/jalview/xml/binding/uniprot/EventType.java
src/jalview/xml/binding/uniprot/EvidenceType.java
src/jalview/xml/binding/uniprot/EvidencedStringType.java
src/jalview/xml/binding/uniprot/FeatureType.java
src/jalview/xml/binding/uniprot/GeneLocationType.java
src/jalview/xml/binding/uniprot/GeneNameType.java
src/jalview/xml/binding/uniprot/GeneType.java
src/jalview/xml/binding/uniprot/ImportedFromType.java
src/jalview/xml/binding/uniprot/InteractantType.java
src/jalview/xml/binding/uniprot/IsoformType.java
src/jalview/xml/binding/uniprot/KeywordType.java
src/jalview/xml/binding/uniprot/LocationType.java
src/jalview/xml/binding/uniprot/MoleculeType.java
src/jalview/xml/binding/uniprot/NameListType.java
src/jalview/xml/binding/uniprot/ObjectFactory.java
src/jalview/xml/binding/uniprot/OrganismNameType.java
src/jalview/xml/binding/uniprot/OrganismType.java
src/jalview/xml/binding/uniprot/PersonType.java
src/jalview/xml/binding/uniprot/PhysiologicalReactionType.java
src/jalview/xml/binding/uniprot/PositionType.java
src/jalview/xml/binding/uniprot/PropertyType.java
src/jalview/xml/binding/uniprot/ProteinExistenceType.java
src/jalview/xml/binding/uniprot/ProteinType.java
src/jalview/xml/binding/uniprot/ReactionType.java
src/jalview/xml/binding/uniprot/ReferenceType.java
src/jalview/xml/binding/uniprot/SequenceType.java
src/jalview/xml/binding/uniprot/SourceDataType.java
src/jalview/xml/binding/uniprot/SourceType.java
src/jalview/xml/binding/uniprot/StatusType.java
src/jalview/xml/binding/uniprot/SubcellularLocationType.java
src/jalview/xml/binding/uniprot/Uniprot.java
src/jalview/xml/binding/uniprot/package-info.java
src/mc_view/PDBChain.java
src/mc_view/PDBfile.java
test/files/annotation_label_width/sample.a2m [new file with mode: 0644]
test/files/annotation_label_width/test_fab41_nostructureviewers.txt [new file with mode: 0644]
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/analysis/AverageDistanceEngineTest.java
test/jalview/analysis/TestAlignSeq.java
test/jalview/bin/ArgsParserTest.java
test/jalview/bin/CommandLineOperations.java
test/jalview/bin/CommandLineOperationsNG.java [new file with mode: 0644]
test/jalview/bin/CommandsTest.java [new file with mode: 0644]
test/jalview/bin/CommandsTest2.java [new file with mode: 0644]
test/jalview/bin/HiDPISettingTest1.java
test/jalview/bin/argparser/ArgParserTest.java [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/argfile.autocounter [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/argfile0.txt [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/argfile1.txt [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/argfile2.txt [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir1/argfile.txt [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir1/test1.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir1/test2.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir2/argfile.txt [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir2/test1.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir2/test2.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir2/test3.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir3/subdir/subdirfile.txt [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir3/subdir/test0.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir3/subdir/test1.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir3/subdir/test2.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir3/subdir/test3.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/test1.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/test2.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/test3.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/testProps.jvprops [new file with mode: 0644]
test/jalview/bin/commandsTest.jvprops [new file with mode: 0644]
test/jalview/bin/commandsTest2.argfile1 [new file with mode: 0644]
test/jalview/bin/commandsTest2.argfile2 [new file with mode: 0644]
test/jalview/bin/commandsTest2.jvprops1 [new file with mode: 0644]
test/jalview/bin/commandsTest2.jvprops2 [new file with mode: 0644]
test/jalview/bin/test1-3.fa [new file with mode: 0644]
test/jalview/bin/uniref50-output.blc [new file with mode: 0644]
test/jalview/bin/uniref50-output.fa [new file with mode: 0644]
test/jalview/datamodel/AlignmentAnnotationTests.java
test/jalview/datamodel/AlignmentTest.java
test/jalview/datamodel/ContactRangeTest.java
test/jalview/datamodel/PAEContactMatrixTest.java [new file with mode: 0644]
test/jalview/datamodel/SequenceTest.java
test/jalview/ext/jmol/JmolViewerTest.java
test/jalview/ext/rbvi/chimera/JalviewChimeraView.java
test/jalview/gui/AlignFrameTest.java
test/jalview/gui/AlignViewportTest.java
test/jalview/gui/AlignmentPanelTest.java
test/jalview/gui/AnnotationLabelsTest2.java [new file with mode: 0644]
test/jalview/gui/FeatureSettingsTest.java
test/jalview/gui/FreeUpMemoryTest.java
test/jalview/gui/QuitHandlerTest.java
test/jalview/gui/SeqPanelTest.java
test/jalview/gui/StructureChooserTest.java
test/jalview/gui/structurechooser/StructureChooserQuerySourceTest.java
test/jalview/io/AnnotatedPDBFileInputTest.java
test/jalview/io/BackupFilesTest.java
test/jalview/io/CrossRef2xmlTests.java
test/jalview/io/Jalview2xmlBase.java
test/jalview/io/JalviewExportPropertiesTests.java
test/jalview/io/RNAMLfileTest.java
test/jalview/io/StockholmFileTest.java
test/jalview/io/cache/JvCacheableInputBoxTest.java
test/jalview/project/Jalview2xmlTests.java
test/jalview/renderer/OverviewRendererTest.java
test/jalview/renderer/OverviewResColourFinderTest.java
test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java
test/jalview/renderer/seqfeatures/FeatureRendererTest.java
test/jalview/schemes/ColourSchemesTest.java
test/jalview/structure/StructureSelectionManagerTest.java
test/jalview/testProps.jvprops
test/jalview/util/FileUtilsTest.java [new file with mode: 0644]
test/jalview/util/imagemaker/BitmapImageSizeTest.java [new file with mode: 0644]
test/jalview/ws/dbsources/EBIAlphaFoldTest.java
test/jalview/ws/sifts/SiftsClientTest.java
utils/biotools/Jalview.json [new file with mode: 0644]
utils/biotools/README.md [new file with mode: 0644]
utils/conda/jalview.sh [new file with mode: 0755]
utils/debian/build_gradle.patch
utils/debian/debian/jalview-mailcap
utils/debian/debian/wrappers/jalview
utils/debian/debian_build.gradle
utils/eclipse/jalview
utils/getdown/bin/jalview.ps1
utils/getdown/bin/jalview.sh
utils/install4j/install4j10_template.install4j
utils/jalviewjs/chromium_test/jalview_bin_Jalview-stderr.html [new file with mode: 0644]

index 616d27d..59c4a99 100644 (file)
@@ -34,6 +34,7 @@ TESTNG
 /utils/install4j/jalview-installers-*.install4j
 /utils/install4j/jalview-install4j-conf.install4j
 *.swp
+*.kate-swp
 /bin
 /.j2s
 /template.html
index 3ec73d3..e52f3f6 100644 (file)
@@ -42,7 +42,7 @@ jetty-http-9.2.10.v20150310.jar
 jetty-io-9.2.10.v20150310.jar
 jetty-server-9.2.10.v20150310.jar
 jetty-util-9.2.10.v20150310.jar
-jfreesvg-2.1.jar       GPL v3 licensed library from the JFree suite - http://www.jfree.org/jfreesvg/
+jfreesvg-3.4.3.jar     GPL v3 licensed library from the JFree suite - last release with Java 1.8 compatibility http://www.jfree.org/jfreesvg/
 JGoogleAnalytics_0.3.jar       APL 2.0 License - http://code.google.com/p/jgoogleanalytics/
 jhall.jar
 Jmol-NO_LOG4J-14.31.53.jar     GPL/LGPLv2 built manually from commit https://github.com/BobHanson/Jmol-SwingJS/commit/a6a2fb767e3fc2a73e72d926a11fd93a0e4c9f23 (excluded jspecview/application to compile)
@@ -58,7 +58,8 @@ miglayout-4.0-swing.jar       BSD - http://www.migcalendar.com/miglayout/versions/4.0/
 regex.jar
 saaj.jar
 servlet-api-3.1.jar
-slf4j-api-1.7.32.jar   MIT license - https://opensource.org/licenses/mit-license.php
+slf4j-api-1.7.36.jar   MIT license - https://opensource.org/licenses/mit-license.php - downloaded from https://repo1.maven.org/maven2/org/slf4j/
+slf4j-nop-1.7.36.jar   MIT license - https://opensource.org/licenses/mit-license.php - downloaded from https://repo1.maven.org/maven2/org/slf4j/
 vamsas-client.jar
 VARNAv3-93.jar GPL licenced software by K�vin Darty, Alain Denise and Yann Ponty - http://varna.lri.fr
 wsdl4j.jar
index 87ca397..c4ed582 100644 (file)
@@ -10,6 +10,10 @@ import org.gradle.plugins.ide.eclipse.model.Output
 import org.gradle.plugins.ide.eclipse.model.Library
 import java.security.MessageDigest
 import java.util.regex.Matcher
+import java.util.concurrent.Executors
+import java.util.concurrent.Future
+import java.util.concurrent.ScheduledExecutorService
+import java.util.concurrent.TimeUnit
 import groovy.transform.ExternalizeMethods
 import groovy.util.XmlParser
 import groovy.xml.XmlUtil
@@ -50,7 +54,7 @@ plugins {
   id "com.diffplug.gradle.spotless" version "3.28.0"
   id 'com.github.johnrengelman.shadow' version '4.0.3'
   id 'com.install4j.gradle' version '10.0.3'
-  id 'com.dorongold.task-tree' version '2.1.0' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
+  id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
   id 'com.palantir.git-version' version '0.13.0' apply false
 }
 
@@ -568,11 +572,16 @@ ext {
   jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
   jalviewjsJ2sProps = null
   jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
+  jalviewjsStderrLaunchFilename = "${jalviewjsSiteDir}/"+(file(jalviewjs_stderr_launch).getName())
 
   eclipseWorkspace = null
   eclipseBinary = string("")
   eclipseVersion = string("")
   eclipseDebug = false
+
+  jalviewjsChromiumUserDir = "${jalviewjsBuildDir}/${jalviewjs_chromium_user_dir}"
+  jalviewjsChromiumProfileDir = "${ext.jalviewjsChromiumUserDir}/${jalviewjs_chromium_profile_name}"
+
   // ENDEXT
 }
 
@@ -1064,7 +1073,7 @@ compileJava {
   // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
   sourceCompatibility = compile_source_compatibility
   targetCompatibility = compile_target_compatibility
-  options.compilerArgs = additional_compiler_args
+  options.compilerArgs += additional_compiler_args
   options.encoding = "UTF-8"
   doFirst {
     print ("Setting target compatibility to "+compile_target_compatibility+"\n")
@@ -1076,7 +1085,7 @@ compileJava {
 compileTestJava {
   sourceCompatibility = compile_source_compatibility
   targetCompatibility = compile_target_compatibility
-  options.compilerArgs = additional_compiler_args
+  options.compilerArgs += additional_compiler_args
   doFirst {
     print ("Setting target compatibility to "+targetCompatibility+"\n")
   }
@@ -1732,26 +1741,117 @@ task prepare {
 
 compileJava.dependsOn prepare
 run.dependsOn compileJava
-//run.dependsOn prepare
+compileTestJava.dependsOn compileJava
+
 
 
-//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
 test {
-  dependsOn prepare
+  group = "Verification"
+  description = "Runs all testTaskN tasks)"
 
   if (useClover) {
     dependsOn cloverClasses
-   } else { //?
-    dependsOn compileJava //?
+  } else { //?
+    dependsOn testClasses
+  }
+
+  // not running tests in this task
+  exclude "**/*"
+}
+/* testTask0 is the main test task */
+task testTask0(type: Test) {
+  group = "Verification"
+  description = "The main test task. Runs all non-testTaskN-labelled tests (unless excluded)"
+  useTestNG() {
+    includeGroups testng_groups.split(",")
+    excludeGroups testng_excluded_groups.split(",")
+    tasks.withType(Test).matching {it.name.startsWith("testTask") && it.name != name}.all {t -> excludeGroups t.name}
+    preserveOrder true
+    useDefaultListeners=true
   }
+}
 
+/* separated tests */
+task testTask1(type: Test) {
+  group = "Verification"
+  description = "Tests that need to be isolated from the main test run"
   useTestNG() {
-    includeGroups testng_groups
-    excludeGroups testng_excluded_groups
+    includeGroups name
+    excludeGroups testng_excluded_groups.split(",")
     preserveOrder true
     useDefaultListeners=true
   }
+}
+
+/* insert more testTaskNs here -- change N to next digit or other string */
+/*
+task testTaskN(type: Test) {
+  group = "Verification"
+  description = "Tests that need to be isolated from the main test run"
+  useTestNG() {
+    includeGroups name
+    excludeGroups testng_excluded_groups.split(",")
+    preserveOrder true
+    useDefaultListeners=true
+  }
+}
+*/
+
+/*
+ * adapted from https://medium.com/@wasyl/pretty-tests-summary-in-gradle-744804dd676c
+ * to summarise test results from all Test tasks
+ */
+/* START of test tasks results summary */
+import groovy.time.TimeCategory
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.api.tasks.testing.logging.TestLogEvent
+rootProject.ext.testsResults = [] // Container for tests summaries
+
+tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { testTask ->
+
+  // from original test task
+  if (useClover) {
+    dependsOn cloverClasses
+  } else { //?
+    dependsOn testClasses //?
+  }
+
+  // run main tests first
+  if (!testTask.name.equals("testTask0"))
+    testTask.mustRunAfter "testTask0"
 
+  testTask.testLogging { logging ->
+    events TestLogEvent.FAILED
+//      TestLogEvent.SKIPPED,
+//      TestLogEvent.STANDARD_OUT,
+//      TestLogEvent.STANDARD_ERROR
+
+    exceptionFormat TestExceptionFormat.FULL
+    showExceptions true
+    showCauses true
+    showStackTraces true
+
+    info.events = [ TestLogEvent.FAILED ]
+  }
+
+  if (OperatingSystem.current().isMacOsX()) {
+    testTask.systemProperty "apple.awt.UIElement", "true"
+    testTask.environment "JAVA_TOOL_OPTIONS", "-Dapple.awt.UIElement=true"
+  }
+
+
+  ignoreFailures = true // Always try to run all tests for all modules
+
+  afterSuite { desc, result ->
+    if (desc.parent)
+      return // Only summarize results for whole modules
+
+    def resultsInfo = [testTask.project.name, testTask.name, result, TimeCategory.minus(new Date(result.endTime), new Date(result.startTime)), testTask.reports.html.entryPoint]
+
+    rootProject.ext.testsResults.add(resultsInfo)
+  }
+
+  // from original test task
   maxHeapSize = "1024m"
 
   workingDir = jalviewDir
@@ -1770,12 +1870,144 @@ test {
   jvmArgs += additional_compiler_args
 
   doFirst {
+    // this is not perfect yet -- we should only add the commandLineIncludePatterns to the
+    // testTasks that include the tests, and exclude all from the others.
+    // get --test argument
+    filter.commandLineIncludePatterns = test.filter.commandLineIncludePatterns
+    // do something with testTask.getCandidateClassFiles() to see if the test should silently finish because of the
+    // commandLineIncludePatterns not matching anything.  Instead we are doing setFailOnNoMatchingTests(false) below
+
+
     if (useClover) {
       println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
     }
   }
+
+
+  /* don't fail on no matching tests (so --tests will run across all testTasks) */
+  testTask.filter.setFailOnNoMatchingTests(false)
+
+  /* ensure the "test" task dependsOn all the testTasks */
+  test.dependsOn testTask
 }
 
+gradle.buildFinished {
+    def allResults = rootProject.ext.testsResults
+
+    if (!allResults.isEmpty()) {
+        printResults allResults
+        allResults.each {r ->
+          if (r[2].resultType == TestResult.ResultType.FAILURE)
+            throw new GradleException("Failed tests!")
+        }
+    }
+}
+
+private static String colString(styler, col, colour, text) {
+  return col?"${styler[colour](text)}":text
+}
+
+private static String getSummaryLine(s, pn, tn, rt, rc, rs, rf, rsk, t, col) {
+  def colour = 'black'
+  def text = rt
+  def nocol = false
+  if (rc == 0) {
+    text = "-----"
+    nocol = true
+  } else {
+    switch(rt) {
+      case TestResult.ResultType.SUCCESS:
+        colour = 'green'
+        break;
+      case TestResult.ResultType.FAILURE:
+        colour = 'red'
+        break;
+      default:
+        nocol = true
+        break;
+    }
+  }
+  StringBuilder sb = new StringBuilder()
+  sb.append("${pn}")
+  if (tn != null)
+    sb.append(":${tn}")
+  sb.append(" results: ")
+  sb.append(colString(s, col && !nocol, colour, text))
+  sb.append(" (")
+  sb.append("${rc} tests, ")
+  sb.append(colString(s, col && rs > 0, 'green', rs))
+  sb.append(" successes, ")
+  sb.append(colString(s, col && rf > 0, 'red', rf))
+  sb.append(" failures, ")
+  sb.append("${rsk} skipped) in ${t}")
+  return sb.toString()
+}
+
+private static void printResults(allResults) {
+
+    // styler from https://stackoverflow.com/a/56139852
+    def styler = 'black red green yellow blue magenta cyan white'.split().toList().withIndex(30).collectEntries { key, val -> [(key) : { "\033[${val}m${it}\033[0m" }] }
+
+    def maxLength = 0
+    def failedTests = false
+    def summaryLines = []
+    def totalcount = 0
+    def totalsuccess = 0
+    def totalfail = 0
+    def totalskip = 0
+    def totaltime = TimeCategory.getSeconds(0)
+    // sort on project name then task name
+    allResults.sort {a, b -> a[0] == b[0]? a[1]<=>b[1]:a[0] <=> b[0]}.each {
+      def projectName = it[0]
+      def taskName = it[1]
+      def result = it[2]
+      def time = it[3]
+      def report = it[4]
+      def summaryCol = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, true)
+      def summaryPlain = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, false)
+      def reportLine = "Report file: ${report}"
+      def ls = summaryPlain.length()
+      def lr = reportLine.length()
+      def m = [ls, lr].max()
+      if (m > maxLength)
+        maxLength = m
+      def info = [ls, summaryCol, reportLine]
+      summaryLines.add(info)
+      failedTests |= result.resultType == TestResult.ResultType.FAILURE
+      totalcount += result.testCount
+      totalsuccess += result.successfulTestCount
+      totalfail += result.failedTestCount
+      totalskip += result.skippedTestCount
+      totaltime += time
+    }
+    def totalSummaryCol = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, true)
+    def totalSummaryPlain = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, false)
+    def tls = totalSummaryPlain.length()
+    if (tls > maxLength)
+      maxLength = tls
+    def info = [tls, totalSummaryCol, null]
+    summaryLines.add(info)
+
+    def allSummaries = []
+    for(sInfo : summaryLines) {
+      def ls = sInfo[0]
+      def summary = sInfo[1]
+      def report = sInfo[2]
+
+      StringBuilder sb = new StringBuilder()
+      sb.append("│" + summary + " " * (maxLength - ls) + "│")
+      if (report != null) {
+        sb.append("\n│" + report + " " * (maxLength - report.length()) + "│")
+      }
+      allSummaries += sb.toString()
+    }
+
+    println "┌${"${"─" * maxLength}"}┐"
+    println allSummaries.join("\n├${"${"─" * maxLength}"}┤\n")
+    println "└${"${"─" * maxLength}"}┘"
+}
+/* END of test tasks results summary */
+
 
 task compileLinkCheck(type: JavaCompile) {
   options.fork = true
@@ -2018,8 +2250,8 @@ task getdownWebsite() {
       props.put("getdown_txt_ui.instant_background_image", "${getdownImagesBuildDir}/${getdown_instant_background_image}")
       props.put("getdown_txt_ui.error_background", "${getdownImagesBuildDir}/${getdown_error_background}")
       props.put("getdown_txt_ui.progress_image", "${getdownImagesBuildDir}/${getdown_progress_image}")
-      props.put("getdown_txt_ui.icon", "${getdownImagesBuildDir}/${getdown_icon}")
-      props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesBuildDir}/${getdown_mac_dock_icon}")
+      props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
+      props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
     }
 
     props.put("getdown_txt_title", jalview_name)
@@ -2568,6 +2800,7 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) {
     'WRAPPER_LINK': getdownWrapperLink,
     'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
     'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
+    'BATCH_WRAPPER_SCRIPT': getdown_batch_wrapper_script,
     'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
     'INSTALLER_NAME': install4jInstallerName,
     'INSTALL4J_UTILS_DIR': install4j_utils_dir,
@@ -3981,8 +4214,157 @@ task eclipseAutoBuildTask {
 }
 
 
+task jalviewjsCopyStderrLaunchFile(type: Copy) {
+  from file(jalviewjs_stderr_launch)
+  into jalviewjsSiteDir
+
+  inputs.file jalviewjs_stderr_launch
+  outputs.file jalviewjsStderrLaunchFilename
+}
+
+task cleanJalviewjsChromiumUserDir {
+  doFirst {
+    delete jalviewjsChromiumUserDir
+  }
+  outputs.dir jalviewjsChromiumUserDir
+  // always run when depended on
+  outputs.upToDateWhen { !file(jalviewjsChromiumUserDir).exists() }
+}
+
+task jalviewjsChromiumProfile {
+  dependsOn cleanJalviewjsChromiumUserDir
+  mustRunAfter cleanJalviewjsChromiumUserDir
+
+  def firstRun = file("${jalviewjsChromiumUserDir}/First Run")
+
+  doFirst {
+    mkdir jalviewjsChromiumProfileDir
+    firstRun.text = ""
+  }
+  outputs.file firstRun
+}
+
+task jalviewjsLaunchTest {
+  group "Test"
+  description "Check JalviewJS opens in a browser"
+  dependsOn jalviewjsBuildSite
+  dependsOn jalviewjsCopyStderrLaunchFile
+  dependsOn jalviewjsChromiumProfile
+
+  def macOS = OperatingSystem.current().isMacOsX()
+  def chromiumBinary = macOS ? jalviewjs_macos_chromium_binary : jalviewjs_chromium_binary
+  if (chromiumBinary.startsWith("~/")) {
+    chromiumBinary = System.getProperty("user.home") + chromiumBinary.substring(1)
+  }
+  
+  def stdout
+  def stderr
+  doFirst {
+    def timeoutms = Integer.valueOf(jalviewjs_chromium_overall_timeout) * 1000
+    
+    def binary = file(chromiumBinary)
+    if (!binary.exists()) {
+      throw new StopExecutionException("Could not find chromium binary '${chromiumBinary}'. Cannot run task ${name}.")
+    }
+    stdout = new ByteArrayOutputStream()
+    stderr = new ByteArrayOutputStream()
+    def execStdout
+    def execStderr
+    if (jalviewjs_j2s_to_console.equals("true")) {
+      execStdout = new org.apache.tools.ant.util.TeeOutputStream(
+        stdout,
+        System.out)
+      execStderr = new org.apache.tools.ant.util.TeeOutputStream(
+        stderr,
+        System.err)
+    } else {
+      execStdout = stdout
+      execStderr = stderr
+    }
+    def execArgs = [
+      "--no-sandbox", // --no-sandbox IS USED BY THE THORIUM APPIMAGE ON THE BUILDSERVER
+      "--headless=new",
+      "--disable-gpu",
+      "--timeout=${timeoutms}",
+      "--virtual-time-budget=${timeoutms}",
+      "--user-data-dir=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_chromium_user_dir}",
+      "--profile-directory=${jalviewjs_chromium_profile_name}",
+      "--allow-file-access-from-files",
+      "--enable-logging=stderr",
+      "file://${jalviewDirAbsolutePath}/${jalviewjsStderrLaunchFilename}"
+    ]
+    
+    if (true || macOS) {
+      ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
+      Future f1 = executor.submit(
+        () -> {
+          exec {
+            standardOutput = execStdout
+            errorOutput = execStderr
+            executable(chromiumBinary)
+            args(execArgs)
+            println "COMMAND: '"+commandLine.join(" ")+"'"
+          }
+          executor.shutdownNow()
+        }
+      )
+
+      def noChangeBytes = 0
+      def noChangeIterations = 0
+      executor.scheduleAtFixedRate(
+        () -> {
+          String stderrString = stderr.toString()
+          // shutdown the task if we have a success string
+          if (stderrString.contains(jalviewjs_desktop_init_string)) {
+            f1.cancel()
+            Thread.sleep(1000)
+            executor.shutdownNow()
+          }
+          // if no change in stderr for 10s then also end
+          if (noChangeIterations >= jalviewjs_chromium_idle_timeout) {
+            executor.shutdownNow()
+          }
+          if (stderrString.length() == noChangeBytes) {
+            noChangeIterations++
+          } else {
+            noChangeBytes = stderrString.length()
+            noChangeIterations = 0
+          }
+        },
+        1, 1, TimeUnit.SECONDS)
+
+      executor.schedule(new Runnable(){
+        public void run(){
+          f1.cancel()
+          executor.shutdownNow()
+        }
+      }, timeoutms, TimeUnit.MILLISECONDS)
+
+      executor.awaitTermination(timeoutms+10000, TimeUnit.MILLISECONDS)
+      executor.shutdownNow()
+    }
+
+  }
+  
+  doLast {
+    def found = false
+    stderr.toString().eachLine { line ->
+      if (line.contains(jalviewjs_desktop_init_string)) {
+        println("Found line '"+line+"'")
+        found = true
+        return
+      }
+    }
+    if (!found) {
+      throw new GradleException("Could not find evidence of Desktop launch in JalviewJS.")
+    }
+  }
+}
+  
+
 task jalviewjs {
   group "JalviewJS"
-  description "Build the site"
+  description "Build the JalviewJS site and run the launch test"
   dependsOn jalviewjsBuildSite
+  dependsOn jalviewjsLaunchTest
 }
diff --git a/examples/AlphaFold/AF-Q5VSL9-F1-predicted_aligned_error_v4_2023.json b/examples/AlphaFold/AF-Q5VSL9-F1-predicted_aligned_error_v4_2023.json
deleted file mode 100644 (file)
index 8861037..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[{"predicted_aligned_error":[[0,1,3,5,5,6,8,10,13,14,15,17,18,18,20,21,23,22,23,25,24,24,27,26,26,28,28,27,28,27,27,28,27,28,28,28,27,28,28,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,28,30,29,29,30,30,30,30,29,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,31,30,31,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,30,30,30,30,31,30,30,31,31,30,31,31,30,30,30,30,31,31,30,31,31,30,31,30,31,30,30,31,30,30,30,30,30,31,30,30,30,30,30,31,31,30,31,31,31,30,30,31,31,31,31,31,31,31,30,31,31,30,31,30,30,30,30,31,30,30,31,31,30,30,31,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,31,31,30,30,30,31,31,30,31,31,31,30,30,31,31,30,31,30,31,31,31,31,30,30,31,30,30,30,31,30,30,31,30,31,31,31,31,31,31,31,31,31,30,30,31,30,29,30,30,29,29,30,30,30,31,30,30,31,30,30,30,31,29,30,31,30,29,30,29,30,30,31,30,31,30,31,31,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,30,30,30,30,30,30,31,30,30,31,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,31,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,29,30,30,30,30,30,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,28,29,29,30,30,29,30,30,30,30,30,30,31,31,30,30,31,30,30,30,31,30,29,30,30,29,28,30,31,29,30,31,30,30,30,31,30,30,31,30,30,30,30,30,30,29,30,30,29,30,31,31,30,30,30,30,31,30,31,31,31,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,31,31,31,30,30,31,31,30,31,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,30,29,30,30,28,29,29,30,30,29,30,31,31,30,31,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,31,30,31,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,31,30,31,31,30,30,30,30,30,30,30,30,30,30,31,30,31,30,31,30,30,30,31,30,30,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,31,30,30,31,31,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,28,30,30,29,29,30,30,29,30,31,29,29,30,30,29,30,30,30,29,30,30,30,29,28,28,27,28,28,27,27,28,28,28,28,28,28,28,28,28,28,27,28,29,28,28,27,27,28,25,26,23,28,28,26,27,26,29,27,28,27,29,28,28,28,29,28,28,29,28,28,28,29,28,27,28,27],[1,0,1,3,4,5,6,7,9,12,13,15,16,17,17,19,20,21,22,23,23,24,25,25,26,27,27,27,27,27,28,28,28,28,29,28,29,29,29,29,29,29,29,29,29,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,30,30,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,30,31,31,30,29,30,29,30,30,30,29,30,30,29,29,30,30,30,30,31,31,31,30,30,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,29,30,30,29,29,30,30,30,31,30,30,30,30,30,31,30,29,30,31,30,29,30,29,30,30,30,30,31,30,31,31,30,30,31,31,30,30,31,31,30,30,31,31,30,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,31,31,31,30,31,31,30,31,31,31,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,31,30,31,31,30,30,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,30,31,31,30,30,30,31,31,30,31,31,30,30,30,30,30,30,30,29,29,29,30,30,29,30,30,30,30,30,30,31,31,30,30,31,30,30,30,31,30,29,29,30,29,28,30,30,29,30,30,30,30,30,31,30,30,30,30,29,30,30,30,30,29,29,29,29,29,30,30,31,30,30,31,30,31,31,31,31,30,30,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,30,30,30,30,30,30,29,29,30,30,30,29,30,31,31,30,31,30,30,31,30,31,31,31,30,31,30,31,30,31,30,31,31,31,31,31,31,31,30,31,31,31,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,30,31,31,30,31,31,30,30,31,30,30,31,31,30,29,31,31,30,30,31,30,30,31,31,30,30,30,30,30,30,30,30,31,31,30,30,30,31,30,30,30,31,31,30,30,31,31,30,31,30,31,31,31,31,31,31,30,31,30,31,30,30,31,30,30,30,31,30,31,30,30,30,31,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,31,30,30,30,30,29,29,27,30,30,29,29,30,30,29,30,30,29,29,30,30,28,30,30,30,29,30,30,30,28,28,27,27,28,28,26,27,28,28,28,28,28,28,28,28,28,28,28,27,27,28,27,27,26,28,25,25,25,27,27,26,27,27,28,26,27,27,28,26,27,26,28,28,27,27,28,28,28,29,28,28,29,28],[2,1,0,1,3,4,5,5,7,10,11,12,14,15,17,18,20,20,21,21,22,23,24,24,26,26,25,26,26,26,27,27,26,27,27,27,27,27,27,27,28,27,28,28,29,29,29,29,29,29,29,29,29,30,29,30,30,30,29,29,30,28,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,31,31,30,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,30,30,31,30,31,31,31,30,31,31,30,30,31,31,31,31,31,30,30,31,31,31,31,31,30,31,31,30,30,30,30,30,30,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,29,30,31,30,29,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,31,30,30,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,30,30,30,29,29,29,30,30,30,30,30,30,30,29,30,30,29,30,30,30,28,30,29,30,30,30,30,31,30,31,31,30,30,30,30,30,30,31,30,30,31,31,30,30,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,31,30,30,30,30,31,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,31,30,31,31,31,30,30,30,30,30,30,30,30,31,31,30,30,31,31,31,31,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,30,30,31,30,30,30,30,29,30,29,29,28,29,30,30,29,30,30,30,30,30,30,31,31,30,30,31,30,30,30,30,29,29,29,30,29,28,30,30,29,30,31,30,30,30,30,29,30,30,30,29,29,29,29,29,28,29,29,29,30,30,30,30,30,30,30,30,31,31,30,30,30,30,31,30,31,31,30,30,31,30,30,30,31,30,30,31,30,30,30,31,30,30,30,31,30,30,30,30,30,30,31,30,30,30,30,30,31,31,30,30,31,30,30,30,30,29,30,30,30,29,30,30,28,29,29,30,30,29,30,31,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,31,30,30,31,31,31,31,30,31,31,31,31,30,31,30,30,30,30,30,30,31,30,30,30,30,30,30,31,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,30,30,31,31,30,30,30,30,30,31,31,29,30,30,30,30,30,30,31,31,30,30,30,30,31,30,31,30,30,31,31,30,30,31,30,31,30,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,27,30,30,28,30,30,30,28,30,30,29,29,30,30,28,30,30,30,29,30,30,30,28,29,28,26,28,27,26,27,29,28,29,28,28,28,28,27,28,28,28,27,28,28,28,27,26,28,24,26,24,28,28,26,26,27,28,27,28,28,28,28,28,28,28,28,29,29,28,29,27,29,28,28,29,28],[3,3,2,0,1,2,4,5,6,7,9,11,13,13,15,16,18,18,19,20,21,22,23,23,26,26,25,26,27,26,28,28,26,27,28,28,27,28,28,28,29,28,28,29,29,30,30,29,29,30,30,30,29,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,31,31,30,31,31,31,30,31,31,31,31,30,30,31,31,31,31,31,31,30,31,31,31,31,31,30,31,30,31,30,31,31,31,31,31,31,30,30,31,31,31,31,31,30,30,31,31,30,31,31,30,31,31,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,29,30,30,30,31,31,30,30,30,30,30,30,31,30,30,31,30,29,29,29,30,30,31,30,31,30,31,31,30,31,31,31,30,30,31,31,30,31,31,31,30,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,31,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,30,29,30,30,30,30,30,31,31,31,30,30,31,30,30,30,31,30,29,30,30,29,28,30,30,29,30,31,30,30,31,30,29,30,30,30,30,30,30,30,30,29,29,30,29,30,30,31,31,30,30,31,30,30,31,30,31,30,30,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29,31,30,30,29,30,30,28,29,29,30,30,29,30,31,30,30,31,30,30,31,30,30,30,31,30,31,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,30,30,31,30,30,31,30,30,31,30,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,30,31,31,31,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,27,30,30,28,29,30,30,28,29,30,30,28,30,30,29,29,30,30,29,29,30,30,29,29,28,26,28,28,27,28,28,29,29,29,28,28,29,28,28,28,28,28,28,28,28,28,25,27,25,27,26,28,28,27,27,28,27,27,29,27,27,28,27,26,27,27,28,27,27,28,27,28,28,27,28,28],[4,4,3,2,0,1,3,4,5,5,6,8,10,11,13,14,17,17,18,19,20,20,22,22,24,24,25,26,26,26,27,27,27,27,28,28,28,28,28,28,29,28,29,29,29,30,29,29,29,30,30,30,30,29,29,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,31,30,31,30,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,30,29,30,29,30,30,29,29,30,30,29,30,31,30,30,30,31,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,30,30,31,30,30,30,30,30,30,30,30,30,29,30,30,30,28,30,29,30,30,30,30,30,30,31,31,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,31,30,30,30,31,30,30,30,30,30,31,30,30,30,29,30,31,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,31,30,31,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,30,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,31,31,30,30,31,30,31,30,30,30,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,31,30,31,31,31,30,30,30,30,30,30,30,30,29,29,30,29,28,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,29,29,29,29,29,29,29,29,30,30,31,30,30,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,30,30,30,29,30,30,30,30,30,30,29,29,29,30,30,30,30,30,31,30,30,31,30,31,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,31,31,30,31,30,31,31,31,31,30,31,31,30,30,31,30,30,31,30,30,30,31,30,30,31,31,30,30,31,30,30,31,31,30,30,30,30,30,30,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,30,30,30,29,29,27,30,30,28,29,30,30,28,30,31,29,28,30,30,28,29,30,30,29,30,30,30,29,29,27,28,28,28,27,28,29,28,29,29,28,29,29,28,29,28,29,28,29,29,29,28,28,28,26,27,26,28,28,28,29,28,29,29,28,28,29,28,27,27,29,29,28,29,28,29,29,30,29,28,30,29],[4,4,4,3,2,0,1,3,3,5,5,6,8,10,11,13,16,16,18,19,19,21,21,21,24,23,23,26,25,25,26,27,25,26,27,26,28,27,28,27,28,28,29,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,31,31,31,30,30,31,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,29,30,30,30,30,31,30,30,31,30,30,31,30,29,30,30,30,28,29,29,30,30,31,30,31,30,31,31,30,30,31,31,30,30,31,30,30,31,31,31,30,30,31,30,30,30,30,31,30,31,31,31,31,30,30,31,30,30,30,30,31,31,31,30,30,30,30,31,31,31,30,30,30,31,30,31,30,30,30,30,31,30,30,30,30,30,30,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,30,30,30,31,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,31,31,30,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,28,29,29,30,29,29,30,29,30,30,30,31,31,31,30,30,30,30,29,30,30,30,29,30,30,29,28,30,30,29,30,31,30,29,31,31,29,30,30,30,30,30,29,29,30,29,28,29,28,30,30,31,31,30,30,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,29,30,30,28,29,29,30,30,29,30,31,31,30,31,31,30,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,31,31,30,31,31,31,30,30,30,31,30,30,31,30,30,30,30,31,30,31,30,30,30,31,29,30,30,30,29,31,30,30,29,30,30,30,30,30,30,31,30,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,30,31,30,31,30,31,30,30,30,30,30,30,30,30,31,31,31,31,30,31,31,30,31,31,31,30,31,31,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,28,27,30,30,27,29,30,30,28,30,30,29,28,30,30,28,29,30,30,29,30,30,30,29,29,27,26,28,28,26,28,29,29,29,28,28,29,29,28,28,29,28,28,29,29,28,28,27,28,26,27,27,29,28,28,28,28,29,28,29,29,29,28,29,28,28,28,29,28,28,29,28,29,29,28,28,29],[5,5,5,4,3,1,0,1,2,3,4,5,6,8,10,11,14,15,16,18,19,19,21,21,23,23,24,26,26,26,27,27,27,27,28,28,28,28,28,28,28,28,29,29,29,30,30,29,29,29,29,29,30,29,29,30,30,30,30,29,30,29,30,29,30,30,30,30,30,30,31,30,30,30,31,30,30,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,30,29,29,30,30,28,29,30,30,30,30,31,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,30,30,30,30,31,30,31,31,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,31,31,30,31,30,30,31,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,30,30,31,30,31,31,30,31,31,30,31,31,30,30,30,30,30,30,30,31,31,31,31,31,31,30,31,30,30,31,30,30,31,31,30,30,31,30,30,30,31,30,30,30,30,30,30,29,31,31,31,31,31,30,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,29,30,30,30,30,30,31,31,31,29,30,30,30,30,30,30,30,29,30,30,29,29,29,30,29,30,30,30,30,31,30,29,30,30,30,30,30,29,30,29,29,29,29,29,29,30,30,31,30,30,31,30,31,31,31,30,30,30,31,30,31,31,30,31,31,31,30,31,31,30,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,29,30,30,28,29,29,30,30,29,29,30,30,30,30,30,30,31,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,30,30,30,30,31,30,30,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,29,30,30,29,29,30,30,30,29,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,31,30,30,31,31,30,31,30,31,30,30,31,30,30,30,30,30,30,30,29,29,29,28,28,29,29,28,29,29,30,27,29,30,29,28,29,29,28,29,29,29,29,29,30,29,29,28,28,28,27,29,28,29,29,29,29,29,29,29,29,29,29,29,28,28,28,29,28,28,27,28,25,28,28,29,28,28,29,28,28,28,29,27,28,29,28,27,28,29,29,29,28,29,28,29,29,28,29,29],[8,5,5,4,3,2,1,0,1,2,4,5,5,6,9,10,12,15,15,18,19,19,21,21,23,23,24,25,25,26,27,26,26,27,27,27,27,27,28,27,28,27,28,28,29,29,29,28,29,29,29,29,29,29,29,30,30,30,30,29,30,29,30,29,30,30,30,30,30,30,31,30,31,30,30,30,30,30,31,30,31,31,31,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,29,30,30,29,29,30,29,29,30,29,29,29,29,28,29,30,30,30,29,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,29,30,30,30,30,29,29,30,30,29,30,30,29,30,30,30,28,29,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,31,30,30,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,30,31,31,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,30,31,31,31,31,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,31,31,31,30,30,30,29,30,30,30,29,29,29,29,28,28,29,30,29,29,30,30,29,30,30,29,29,30,30,29,30,28,29,29,29,28,28,28,29,30,30,30,30,30,30,30,31,31,31,31,30,30,31,30,31,31,30,31,31,30,30,31,31,30,30,31,30,30,30,31,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,29,30,30,30,29,30,30,29,29,30,29,28,29,28,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,30,30,30,31,30,30,31,30,30,30,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,31,31,31,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,30,31,30,31,30,30,30,30,30,30,30,29,29,26,30,30,28,29,30,29,28,29,30,28,28,29,30,28,29,30,29,29,30,30,29,29,29,28,28,28,28,28,28,29,28,29,29,28,29,29,29,29,29,28,28,28,29,28,29,28,28,26,27,26,28,28,28,28,27,28,29,28,27,29,28,29,27,28,29,29,29,28,29,28,29,29,28,30,29],[9,7,5,5,4,3,3,2,0,1,2,3,4,4,6,7,10,10,12,15,15,17,19,19,21,21,22,23,23,23,25,25,24,26,26,25,26,26,26,26,27,26,27,28,28,29,29,28,28,29,29,29,29,30,29,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,30,30,31,30,31,31,31,30,31,30,30,30,30,30,30,31,31,30,31,31,30,31,31,31,30,31,31,31,30,31,31,30,31,31,30,31,31,30,30,30,31,30,31,31,31,31,31,30,30,31,31,31,30,31,31,31,31,30,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,30,30,30,31,30,30,31,30,29,30,30,30,29,30,29,30,30,29,29,30,29,28,29,30,30,30,29,30,30,31,30,30,31,30,30,30,31,31,30,30,31,30,30,31,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,30,30,29,29,29,30,30,30,29,30,30,29,29,30,30,29,29,30,29,28,29,29,30,29,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,29,29,29,30,29,29,30,29,29,30,29,30,29,29,29,30,29,29,29,29,30,29,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,30,31,31,31,31,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,30,29,29,29,29,29,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,28,29,29,28,28,29,28,29,29,29,29,29,29,30,29,30,30,30,31,30,30,30,30,29,29,30,30,29,28,29,30,29,27,29,29,29,30,30,29,29,30,30,29,30,30,30,30,30,28,29,29,28,27,29,27,29,30,30,30,30,30,30,30,31,31,30,30,30,30,31,30,31,31,30,31,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,29,30,30,30,29,30,29,29,30,30,29,30,29,29,28,30,30,28,28,27,29,30,28,29,30,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,31,31,31,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,28,29,30,29,28,30,30,28,28,29,29,30,30,30,30,30,30,30,30,30,31,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,29,29,29,29,28,28,25,29,30,27,27,30,29,27,28,30,28,27,29,29,27,28,30,29,28,29,30,29,28,29,28,26,28,28,27,28,28,28,29,29,28,29,29,29,29,29,28,28,29,29,28,29,28,28,26,27,27,29,28,28,28,27,28,28,28,28,28,28,28,27,28,28,29,28,28,28,28,28,29,28,28,28],[11,9,8,5,5,4,3,2,1,0,1,2,3,4,5,5,10,11,11,15,14,15,19,19,19,21,21,22,23,23,26,25,24,25,26,26,27,26,26,26,27,27,27,27,28,28,28,28,28,29,28,28,29,28,28,29,29,29,29,28,29,29,29,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,31,30,30,31,31,30,30,31,30,30,30,30,31,30,30,31,31,30,30,31,30,30,31,31,30,30,31,30,30,30,31,30,30,31,31,30,31,30,30,30,31,31,31,31,31,30,30,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,30,30,30,31,30,30,30,30,29,30,30,30,29,30,29,29,30,29,29,30,29,28,29,30,30,30,29,30,31,31,30,30,31,30,30,31,31,30,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,29,30,30,30,30,29,29,30,30,29,30,30,28,29,30,30,28,29,29,30,30,30,30,31,30,31,31,30,30,30,30,29,29,31,30,30,30,31,30,30,31,31,30,31,31,30,30,31,31,30,30,30,30,31,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,29,29,29,30,29,29,29,29,29,30,29,29,29,28,29,30,29,29,29,29,29,30,29,30,30,30,29,30,29,29,29,29,30,29,29,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,29,30,31,30,29,30,30,29,29,30,30,30,30,30,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,30,30,30,31,30,30,30,29,30,30,29,30,30,30,29,29,29,29,29,30,29,30,30,29,30,29,30,30,30,30,30,30,31,30,29,30,30,29,29,30,30,29,28,29,29,29,27,29,30,28,30,30,29,29,30,30,29,30,30,30,29,30,29,29,29,28,27,29,27,28,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,29,30,29,29,30,30,29,29,28,29,29,28,27,29,29,29,28,29,29,26,28,27,29,29,28,29,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,29,29,29,29,29,29,29,29,29,30,29,28,29,28,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,29,28,28,28,28,28,26,28,29,27,28,28,29,26,27,29,28,27,28,29,27,28,29,28,28,29,30,29,29,29,28,28,28,29,27,28,28,29,29,30,29,30,29,29,30,29,28,29,28,29,28,28,28,27,26,28,27,27,28,28,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,28,29,28],[14,11,10,9,6,5,5,4,3,1,0,1,3,3,4,4,6,9,10,11,13,13,17,18,17,18,20,21,20,21,23,22,22,24,24,25,25,25,25,25,25,25,27,26,27,28,27,27,28,28,28,28,28,28,27,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,31,31,30,31,31,30,30,30,30,30,30,30,31,30,31,31,30,30,31,31,30,30,31,30,30,31,31,30,31,31,30,30,31,30,30,30,30,30,30,30,31,30,31,30,30,31,30,31,30,31,31,31,31,31,31,30,31,30,31,30,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,29,30,30,29,28,30,27,29,29,28,28,29,29,27,29,30,28,29,29,30,30,30,30,29,30,30,30,30,31,31,30,30,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,29,29,29,30,30,30,29,29,30,29,29,30,29,28,29,30,29,27,28,29,29,29,30,30,30,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,29,30,30,30,31,31,29,30,31,31,30,30,31,30,30,30,31,30,30,30,30,30,31,30,31,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,29,29,30,30,30,29,29,30,30,30,29,30,29,29,30,30,29,30,30,30,29,30,29,30,29,29,30,29,29,29,30,30,30,30,30,29,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,31,30,30,30,30,30,30,31,31,31,30,30,31,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,30,31,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,29,29,30,29,29,30,30,30,29,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,29,28,28,29,28,27,29,29,27,29,30,29,28,30,30,29,29,30,29,30,29,28,29,28,27,27,28,27,28,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,29,29,30,30,28,30,30,28,29,30,29,27,28,26,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,29,29,30,29,29,30,30,28,28,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,31,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,29,29,28,25,29,29,27,29,29,29,27,29,30,28,28,30,29,27,29,30,29,29,30,30,29,29,29,28,28,29,28,28,28,30,30,29,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,27,28,27,29,29,29,28,29,29,29,28,29,29,28,28,28,29,28,29,29,29,29,29,30,29,29,30,29],[14,13,11,11,10,6,6,5,4,3,1,0,1,3,3,4,5,6,8,11,11,12,16,17,18,20,19,21,22,21,23,23,22,24,24,25,24,25,25,25,25,26,26,26,27,28,28,27,28,29,28,27,28,29,28,29,29,29,29,29,30,29,29,29,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,31,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,31,31,30,30,31,30,31,31,30,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,30,30,30,30,30,30,31,30,29,30,30,29,29,30,29,30,30,28,29,30,29,27,29,30,29,29,29,30,30,31,30,29,30,30,30,30,31,30,29,30,31,30,30,31,31,30,30,31,30,30,30,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,30,30,30,30,30,29,30,30,29,29,29,30,30,30,29,30,30,29,29,30,29,29,29,30,29,28,28,29,30,29,30,30,30,29,30,30,29,29,30,30,29,29,30,30,29,30,30,30,29,31,30,29,31,30,29,30,31,30,30,31,30,30,30,31,30,30,30,30,31,31,30,30,30,30,29,30,31,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,29,29,30,29,29,29,29,30,30,29,29,29,28,29,30,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,30,30,30,30,30,30,30,31,30,31,30,31,30,31,30,30,30,29,30,28,29,31,29,28,30,30,29,29,30,30,30,30,30,30,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,31,30,30,30,30,30,28,29,30,29,28,30,30,28,29,29,29,28,29,30,27,29,30,29,30,29,29,30,29,30,30,30,30,30,29,30,30,29,30,30,30,29,29,29,29,28,28,29,29,28,29,30,29,29,30,29,29,29,30,29,30,30,28,28,29,27,25,29,27,29,29,29,30,30,30,30,30,30,30,30,29,30,30,30,30,31,30,30,30,30,30,30,30,30,29,30,31,30,29,30,30,29,29,30,30,28,29,30,29,28,30,30,29,29,30,30,29,29,30,30,29,30,28,28,29,29,28,29,29,28,29,29,29,27,28,26,29,29,28,29,30,30,29,30,30,29,30,30,30,30,30,29,30,30,30,30,30,30,31,31,31,30,30,30,31,31,30,31,31,31,30,31,30,30,30,30,30,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,30,29,30,29,29,29,29,30,28,29,29,28,29,29,28,28,30,29,28,29,29,27,28,28,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,29,30,30,29,30,30,30,28,30,30,29,28,30,29,29,28,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,30,29,29,29,28,28,28,27,27,25,29,29,26,27,28,28,26,28,29,28,27,29,28,27,29,30,28,28,29,30,29,28,29,28,27,29,28,27,28,29,30,29,29,29,29,30,30,30,29,29,29,29,29,29,28,28,28,26,28,27,28,28,28,27,28,29,28,28,28,28,28,28,28,29,27,29,27,28,28,28,29,29,27,29,29],[17,14,14,13,11,9,7,6,5,4,3,1,0,1,3,3,4,6,6,9,10,11,14,15,16,18,19,19,19,20,23,21,22,23,23,25,25,24,25,24,26,26,27,26,27,28,27,26,28,28,27,27,28,28,25,28,29,28,28,28,29,28,28,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,31,30,31,30,30,30,31,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,30,30,30,29,29,30,28,30,29,28,29,30,29,28,29,30,29,29,29,30,30,31,30,30,30,31,30,31,31,31,30,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,29,30,30,30,30,30,30,30,30,29,29,30,30,27,29,29,29,28,29,29,30,29,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,31,30,30,31,31,30,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,30,31,31,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,29,29,29,30,30,29,29,30,30,30,29,29,29,29,30,30,29,29,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,30,31,29,30,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,30,31,30,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,29,30,31,30,29,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,30,30,30,30,29,30,30,30,29,29,29,29,28,28,29,29,27,29,29,29,28,29,29,28,29,29,29,29,29,28,28,28,27,26,28,27,28,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,30,31,31,30,30,31,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,29,29,29,28,29,29,28,28,29,29,27,29,27,28,29,28,29,30,30,29,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,28,29,30,29,29,30,30,29,29,29,28,29,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,31,30,30,29,30,30,29,29,29,30,30,30,30,30,29,29,31,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,30,30,30,30,30,30,30,30,29,29,29,28,28,25,29,30,27,28,29,29,27,28,29,28,28,29,29,27,29,30,29,29,30,30,29,29,29,29,28,28,29,29,28,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,29,29,28,27,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,29],[18,15,13,14,13,11,10,6,5,5,4,3,1,0,1,2,4,4,6,8,8,9,12,13,14,16,17,20,19,19,22,21,20,23,23,24,22,24,24,24,25,24,25,25,26,28,27,27,27,29,28,26,28,29,28,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,31,30,30,30,30,30,31,30,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,30,31,30,30,30,30,30,31,31,30,31,30,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,30,30,31,30,30,30,31,30,30,31,30,29,29,30,28,30,30,29,29,30,29,28,29,30,29,29,29,30,30,31,30,29,31,31,30,30,31,30,29,30,31,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,30,29,30,29,30,30,30,29,30,30,29,29,30,29,29,30,30,29,28,28,29,30,29,30,30,30,29,30,30,30,29,30,30,29,29,31,30,29,30,31,30,30,31,30,30,31,31,29,30,31,30,30,31,31,30,30,31,30,30,31,30,31,31,30,30,31,31,30,30,31,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,30,30,30,29,29,29,29,29,30,29,29,30,29,29,30,29,29,30,29,30,29,29,29,29,29,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,31,30,31,30,30,31,30,30,31,30,31,30,30,31,30,31,31,30,30,31,30,30,30,30,30,29,29,30,29,28,30,30,29,29,30,30,29,30,30,30,30,30,29,30,30,29,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,30,29,29,30,28,30,30,30,30,30,30,30,30,31,30,31,31,30,30,30,30,29,30,30,30,29,29,29,30,29,28,30,29,28,30,30,29,28,30,30,28,29,30,29,29,29,28,28,29,26,25,28,26,29,29,29,30,29,30,30,30,30,31,31,30,30,30,31,30,31,31,30,31,31,30,30,30,30,30,30,31,30,29,30,30,30,29,30,30,28,29,30,30,29,30,30,30,29,30,30,30,29,30,30,30,30,29,30,30,29,29,30,29,29,29,30,29,27,28,26,29,30,28,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,30,30,29,29,30,29,30,30,29,29,30,30,28,30,30,28,28,29,29,29,29,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,29,29,29,30,29,29,30,30,30,29,31,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,29,29,28,27,26,29,29,27,28,29,29,28,29,29,28,28,29,29,28,29,30,29,29,30,30,30,29,30,28,28,29,28,28,29,30,30,30,29,30,29,30,29,30,30,29,30,30,30,29,29,29,29,28,27,29,30,29,28,28,29,28,29,29,29,28,28,29,28,29,28,29,28,29,29,28,29,29,28,29,29],[21,18,16,15,15,13,12,10,6,5,5,4,3,1,0,1,2,4,4,5,7,8,9,11,12,15,16,16,18,19,19,21,21,23,22,24,23,25,25,24,25,25,26,25,27,28,27,26,27,28,26,26,28,28,25,28,29,28,28,28,29,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,30,30,30,30,30,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,31,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,29,30,30,29,29,30,29,28,30,30,29,29,29,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,29,30,30,29,29,30,29,28,29,30,29,28,29,29,30,30,30,30,30,30,30,31,30,30,30,30,30,29,31,31,30,31,31,31,30,31,31,30,31,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,28,29,29,30,29,30,30,30,30,30,30,29,29,29,30,29,30,30,30,30,30,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,30,31,29,30,31,30,30,31,31,30,30,30,31,30,30,30,30,30,31,30,30,30,30,31,30,31,31,30,31,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,29,30,31,30,29,31,31,30,30,30,30,30,30,31,30,31,30,30,30,30,30,31,30,31,30,31,31,30,30,30,30,29,30,30,30,29,29,30,30,29,28,29,29,28,29,29,29,28,30,29,28,29,29,29,29,29,28,28,28,27,25,28,27,29,29,30,30,30,30,30,30,30,31,31,30,30,30,30,30,31,31,30,31,31,30,30,31,31,30,30,31,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,31,30,30,30,29,30,29,29,28,29,28,29,29,29,29,28,28,27,29,29,28,29,29,30,28,30,30,29,30,30,30,30,30,30,30,30,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,30,31,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,29,30,30,29,30,29,30,29,29,30,30,28,29,29,29,28,29,29,28,29,28,29,29,29,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,29,30,30,30,30,29,31,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,30,30,30,30,29,29,30,28,28,28,28,27,26,28,29,26,28,29,28,28,28,29,28,28,30,29,28,30,30,29,29,30,30,30,29,30,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,30,28,29,28,30,30,29,29,29,30,29,30,30,30,30,29,29,30,30,30,30,29,30,30,30,29,30,30,30],[20,18,16,15,14,14,13,12,9,7,5,4,4,3,1,0,1,3,5,5,6,7,9,10,10,13,14,15,16,17,19,19,19,21,21,22,21,23,23,23,24,24,25,24,26,27,26,26,26,29,27,26,28,28,27,28,29,29,28,29,29,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,30,30,30,31,30,30,31,30,30,31,31,30,30,31,30,30,31,31,31,30,31,30,30,31,31,30,31,30,30,30,30,30,30,30,30,30,30,31,31,30,31,30,30,30,31,31,30,31,31,30,30,30,31,30,31,31,30,30,31,30,31,31,30,30,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,30,30,30,31,30,30,31,30,29,30,30,29,30,30,29,30,30,29,29,30,29,27,29,30,28,29,29,30,30,30,30,29,30,30,30,30,31,31,29,30,31,31,30,31,31,30,30,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,29,30,29,29,30,30,28,28,28,29,30,29,30,30,30,29,30,30,30,29,30,30,29,30,31,30,30,30,30,31,30,31,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,31,30,30,30,31,31,29,30,31,31,30,30,30,30,30,30,29,30,29,30,29,29,29,29,30,30,30,30,30,29,29,30,29,28,29,29,30,28,30,29,29,29,29,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,31,30,30,30,29,30,29,29,31,29,28,30,30,29,28,30,30,29,30,30,30,29,30,29,30,29,29,30,30,31,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,30,31,30,30,30,30,30,30,29,29,30,30,28,30,30,29,29,30,30,28,29,30,29,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,29,29,29,30,29,28,29,30,28,29,30,29,28,30,29,28,29,30,29,29,29,28,27,29,25,25,28,26,29,29,29,30,29,30,30,29,30,31,31,30,30,30,30,30,31,31,30,30,30,30,29,30,30,30,30,31,30,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,29,29,29,29,28,29,26,29,30,27,29,30,30,28,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,31,30,30,30,30,30,31,31,31,31,31,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,29,30,29,29,29,29,29,29,29,29,29,30,28,30,30,29,27,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,28,29,29,29,28,29,30,29,28,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,29,29,29,29,28,28,28,27,26,29,30,27,28,29,29,27,29,29,28,28,29,29,28,30,29,29,29,30,30,30,29,30,29,28,29,29,29,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,29,29,29,29,28,29,29,30,29,29,28,29,29,29,29,29,29,29,29,29,30,28,29,28,29,29,29,29,29,29,30,29],[22,22,20,18,18,16,16,15,12,9,7,5,5,5,3,2,0,1,3,4,5,5,6,7,9,10,13,13,14,16,16,18,19,19,19,21,21,22,24,23,24,23,25,24,26,27,26,25,26,27,25,26,27,26,24,27,28,27,27,28,28,28,28,28,29,29,29,30,29,29,30,29,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,30,31,30,30,29,30,28,30,30,29,29,30,29,27,29,30,29,28,29,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,29,30,30,30,30,30,29,29,29,30,29,28,29,29,29,28,28,29,30,29,30,29,30,29,30,30,30,29,30,30,29,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,30,31,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,30,29,30,29,29,29,29,29,29,28,29,29,29,29,30,29,29,29,29,29,29,29,29,29,28,29,29,29,30,29,29,29,28,29,30,29,29,29,29,29,30,29,30,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,30,30,29,29,31,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,31,30,30,30,31,31,30,30,31,31,30,31,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,29,29,29,30,29,28,29,29,28,27,28,29,27,28,28,28,28,29,28,27,28,29,28,29,28,27,27,28,25,24,27,25,28,29,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,29,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,29,29,29,30,29,29,30,30,29,30,30,30,29,29,29,29,29,28,28,29,29,28,28,29,29,27,28,27,28,29,27,28,29,29,29,29,29,29,30,29,29,30,30,29,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,29,28,29,29,29,29,28,29,28,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,29,29,29,29,28,28,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,30,28,29,29,30,29,29,28,28,27,27,27,27,26,25,27,28,25,27,29,29,27,28,29,28,27,29,29,27,29,29,29,29,29,29,29,29,29,28,29,28,29,29,28,30,30,30,30,29,30,30,30,30,30,29,30,29,30,29,29,29,29,27,29,29,30,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,28,29,30,30,30,29,30,30],[22,20,19,18,17,16,16,14,13,12,8,7,5,4,3,2,1,0,1,2,4,4,4,5,6,8,9,10,13,14,14,16,17,18,19,19,19,21,21,21,22,22,23,23,24,25,25,24,25,26,25,25,27,27,25,28,28,27,27,28,29,28,29,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,29,30,30,29,30,29,30,30,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,30,30,31,30,30,30,30,30,30,31,31,30,31,31,30,30,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,30,30,31,30,30,29,30,29,29,29,29,28,29,28,27,29,30,28,28,28,29,30,30,29,29,30,30,30,30,31,30,30,30,31,31,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,29,28,30,28,28,26,27,28,29,28,29,29,30,28,29,30,29,29,30,30,29,29,31,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,31,31,30,31,31,31,30,30,30,30,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,28,29,29,29,29,29,29,28,29,30,29,28,29,29,28,28,29,29,28,29,29,29,28,27,28,29,28,28,28,28,28,28,28,28,29,29,29,28,28,29,29,29,29,29,29,29,29,30,30,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,30,30,30,29,30,31,30,29,30,30,29,29,30,30,29,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,30,30,30,30,30,30,30,30,29,29,29,29,28,27,29,29,27,28,29,29,27,29,29,27,28,28,28,28,27,27,26,26,24,23,26,25,28,28,29,29,29,29,29,29,30,30,30,30,30,29,30,29,30,30,29,30,30,30,29,30,30,29,29,30,29,28,29,30,29,28,30,30,28,29,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,28,28,29,29,26,27,25,29,29,27,28,29,29,27,29,29,28,29,29,30,30,29,29,30,30,29,30,29,30,30,30,31,30,30,31,31,31,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,30,29,29,30,30,29,28,30,30,29,29,30,29,29,29,29,28,29,29,27,29,30,27,26,28,28,29,29,28,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,28,28,29,28,28,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,28,28,28,27,25,24,29,28,25,28,29,28,27,29,29,28,29,30,29,28,30,30,29,30,30,30,30,30,30,29,29,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,29,28,30,29,29,29,29,29,29,28,29,29,28,29,29,29,28,29,29,29,29,29,30,29,29,30,30],[22,21,20,20,19,17,17,16,14,14,11,9,7,5,5,4,3,2,0,1,2,3,4,4,5,7,8,8,11,12,13,15,16,17,17,19,17,20,21,20,21,21,22,23,24,25,25,24,24,27,25,24,26,27,25,26,28,27,26,27,28,27,28,29,29,30,30,29,30,29,30,28,30,29,29,29,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,31,30,30,30,30,30,30,30,29,30,31,30,30,30,30,30,30,31,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,30,30,31,31,30,30,31,31,30,31,31,30,30,31,30,31,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,29,30,30,29,29,30,29,27,30,30,28,28,29,30,30,30,29,29,30,30,30,29,30,30,29,30,31,30,30,31,31,30,30,30,30,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,29,30,30,29,29,30,29,29,28,27,29,30,28,29,30,30,29,30,30,30,29,30,29,29,29,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,29,29,30,30,29,30,30,30,30,29,28,29,29,28,28,28,27,29,28,28,27,29,29,28,28,29,28,28,28,29,28,27,28,28,28,28,28,28,26,27,27,28,27,27,28,28,27,28,28,28,28,27,28,27,27,27,27,28,28,28,28,28,28,28,29,28,28,29,29,29,29,28,29,29,30,30,29,29,30,30,30,29,30,30,30,30,29,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,28,28,30,29,27,29,30,29,28,29,30,29,29,30,29,29,29,29,30,29,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,29,30,29,29,30,30,28,30,30,29,29,30,30,28,29,30,29,29,30,30,30,30,29,30,29,31,29,30,31,30,30,30,30,29,30,30,29,29,29,29,29,28,28,29,29,28,29,29,29,28,29,28,27,28,29,28,28,28,27,25,27,23,24,27,26,28,28,28,29,29,29,30,29,29,30,30,29,30,29,30,29,30,30,30,30,31,30,29,30,30,29,29,30,30,29,30,30,29,28,30,30,29,29,30,30,29,29,30,29,29,30,30,29,30,30,29,30,29,29,29,29,29,27,29,29,29,28,29,29,27,28,26,29,29,26,28,29,29,28,29,29,28,29,30,29,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,28,29,29,29,28,29,29,28,29,28,28,28,28,27,28,28,29,28,29,28,28,27,28,29,29,28,28,29,29,29,29,29,30,30,30,29,30,30,30,29,30,29,29,29,30,28,29,29,29,28,29,28,28,27,27,27,27,28,29,28,28,28,30,29,29,29,29,29,29,30,29,29,29,30,30,29,30,29,28,28,28,29,29,27,27,27,26,26,27,27,26,25,25,28,25,26,28,28,26,27,29,27,27,29,28,27,29,29,29,29,30,29,29,29,29,29,28,28,29,29,29,29,29,29,30,29,30,30,30,29,30,30,30,29,30,29,29,29,30,29,28,28,30,29,29,29,29,29,29,30,30,29,29,30,29,30,28,29,28,29,29,29,29,29,30,29,30],[22,21,21,20,20,19,18,17,15,14,13,11,9,6,4,4,3,2,1,0,1,2,3,4,4,5,7,8,10,10,11,13,15,16,16,18,18,19,21,21,21,21,23,22,23,24,23,23,23,24,23,23,25,25,23,26,26,25,25,26,27,26,27,28,28,30,29,29,29,29,30,29,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,30,31,31,31,31,31,30,30,30,30,30,30,31,31,31,31,30,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,29,29,30,29,28,29,28,26,28,30,27,28,29,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,30,31,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,28,30,29,29,27,28,29,30,29,30,29,30,29,30,30,29,29,30,30,29,29,31,30,30,30,31,31,30,30,30,30,30,30,30,30,30,31,30,31,31,30,31,31,31,31,31,30,31,30,30,30,30,30,29,30,30,30,29,30,30,30,30,29,29,29,28,29,29,28,26,28,28,28,27,28,29,28,28,29,29,28,28,29,29,28,29,29,29,29,29,29,28,28,28,29,28,28,28,28,28,29,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,30,29,29,29,29,30,30,29,29,29,30,30,29,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,30,31,29,29,31,30,28,30,31,30,29,30,30,30,30,30,30,30,30,29,31,30,30,31,30,31,31,30,30,30,30,30,30,30,30,31,31,30,31,31,31,30,31,31,31,31,30,31,30,31,29,30,31,30,29,30,31,29,30,31,30,30,30,31,30,30,30,30,31,30,30,31,30,31,31,31,31,30,30,30,30,29,30,30,29,29,29,29,29,28,27,28,29,28,29,28,29,28,29,28,26,28,29,28,29,26,26,25,27,24,23,25,25,27,28,29,29,29,29,30,29,30,30,30,29,30,29,30,29,30,30,29,30,31,30,29,30,30,29,29,30,29,29,29,30,29,28,30,30,29,29,30,29,29,29,30,29,29,30,30,29,29,31,30,30,29,29,29,29,29,28,29,29,28,28,29,29,27,28,27,29,29,27,28,29,29,27,29,28,28,29,29,29,29,29,29,29,29,30,30,29,30,31,30,31,31,30,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,27,28,28,27,28,29,29,28,28,28,29,28,29,29,29,29,29,29,29,29,30,30,30,30,30,29,30,30,29,30,30,30,29,29,29,28,29,29,29,29,27,28,28,28,28,29,28,28,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,31,30,29,29,29,29,29,28,27,28,26,27,27,27,25,24,27,28,25,28,28,28,27,28,28,28,28,29,28,27,30,30,29,29,30,30,29,29,30,29,29,29,30,30,30,30,30,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,29,29,29,30,29,30,29,29,30,29,29,30,30,29,30,30,30,29,30,30,29,30,29,30,30,30,30,30],[22,21,21,20,21,20,19,17,16,15,12,13,10,8,6,5,4,2,2,1,0,1,2,3,3,4,5,6,8,8,10,12,14,15,16,16,16,18,19,19,20,20,21,22,23,24,23,21,22,24,22,22,25,25,21,25,27,24,25,26,28,26,27,27,28,30,29,30,29,29,30,28,30,30,29,29,30,30,30,29,30,30,29,29,30,30,29,29,29,30,30,29,30,30,31,30,30,31,30,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,30,30,31,30,30,30,30,30,29,30,31,30,30,30,30,30,31,31,30,31,31,31,30,31,31,30,31,30,31,30,31,30,31,31,30,30,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,30,29,29,30,28,28,29,28,28,28,28,26,28,29,26,28,29,29,30,29,29,29,30,30,29,29,30,30,29,30,31,30,29,30,31,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,30,30,30,30,30,30,30,29,29,29,29,28,28,29,28,28,27,27,29,29,27,29,29,30,28,28,30,29,28,30,30,29,28,30,30,30,30,30,30,30,30,30,29,30,31,29,30,31,30,30,30,31,30,30,31,31,30,30,30,30,31,30,30,30,31,30,30,30,30,29,30,30,29,30,29,29,30,29,28,29,28,26,28,29,28,27,29,29,28,27,29,28,27,28,29,28,27,28,28,28,28,28,28,28,27,28,28,27,28,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,30,29,29,29,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,29,30,29,30,30,30,29,30,30,30,30,30,30,30,31,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,31,31,31,30,30,30,30,29,30,30,30,29,29,29,30,28,27,29,29,27,28,29,29,27,29,28,27,27,28,28,28,27,27,24,27,22,22,26,25,28,28,28,29,28,29,29,28,30,29,29,29,29,28,29,28,29,29,29,29,30,29,29,29,30,29,29,30,29,28,29,30,28,28,30,30,28,29,30,29,28,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,29,28,30,29,27,28,29,28,26,27,27,28,28,27,27,29,29,27,28,29,28,29,29,29,30,29,28,30,29,29,30,29,30,30,30,30,30,30,30,31,30,30,31,31,31,30,30,30,29,30,30,29,29,30,29,29,30,30,30,30,30,30,29,30,30,29,29,30,29,29,29,30,29,28,29,29,29,28,29,29,29,28,29,29,29,29,27,28,29,28,26,29,29,27,25,27,28,28,28,27,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,29,30,30,28,29,30,29,28,29,29,29,28,27,28,28,28,29,29,29,29,29,30,29,30,29,30,30,29,30,30,30,30,30,30,30,30,29,30,29,29,29,29,28,29,28,28,28,26,23,23,28,28,24,27,28,27,27,29,29,28,29,30,29,29,30,30,29,30,30,30,30,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,29,30,30,29,29,29,29,30,29,30,29,29,30,29,30,29,30,29,30,30,30,30,30,30,30,30],[23,21,21,21,21,21,21,19,17,16,14,12,12,8,8,5,5,3,2,2,1,0,1,2,3,4,4,5,7,8,8,11,12,14,15,17,16,18,19,19,20,20,20,21,22,23,23,21,22,24,23,21,24,25,21,25,26,24,24,26,27,26,27,27,27,29,29,29,29,29,30,28,29,30,29,29,30,29,30,29,30,30,29,29,30,29,28,29,29,29,30,29,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,29,29,30,30,29,30,30,30,29,30,30,29,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,30,30,31,30,30,29,30,30,29,30,30,30,29,29,30,29,30,29,29,29,30,29,28,29,29,27,27,29,30,30,30,29,29,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,30,31,30,30,30,31,30,30,30,31,30,29,30,30,30,30,30,30,30,29,30,30,30,30,29,29,29,29,30,29,29,30,29,28,28,27,29,30,28,29,30,30,28,30,30,29,29,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,28,30,30,30,29,29,29,29,29,29,28,29,28,27,27,27,25,28,27,27,26,28,28,27,27,29,28,27,28,28,27,27,28,27,27,27,27,27,26,26,26,27,25,26,27,27,26,28,27,28,27,27,27,27,26,26,26,26,27,26,26,27,27,28,28,27,27,28,28,29,28,28,28,28,29,29,28,29,29,29,29,29,29,29,30,29,29,30,29,29,30,29,30,29,29,30,29,30,30,30,29,30,30,29,29,30,30,28,28,30,29,27,29,30,29,28,29,30,29,29,29,29,28,29,29,30,30,30,30,30,30,30,30,30,29,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,29,30,29,29,30,30,29,30,30,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,29,31,30,30,31,30,30,30,30,29,30,30,30,29,29,29,30,28,27,29,29,28,29,29,29,28,29,29,28,28,29,29,28,27,27,23,26,22,22,26,25,28,27,29,29,29,29,29,28,30,30,30,28,30,29,30,29,30,30,29,29,30,30,29,30,30,29,28,30,29,28,29,30,29,28,30,30,28,29,30,29,29,30,30,29,29,30,30,29,30,30,30,30,30,29,30,30,29,29,29,29,28,28,29,28,25,28,25,29,29,25,29,29,29,27,29,29,27,28,29,29,29,29,28,30,29,29,30,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,30,30,30,30,29,30,29,30,29,30,30,29,29,30,30,28,29,29,29,28,29,29,29,28,28,28,29,29,27,28,29,26,26,28,28,26,25,26,28,29,27,28,29,29,29,29,29,29,30,29,29,30,30,29,29,29,29,29,29,29,28,29,29,29,28,29,28,28,27,27,27,26,28,28,28,28,28,29,28,29,28,29,29,29,29,28,28,29,29,29,29,30,29,28,29,28,29,28,27,27,27,25,25,27,25,25,22,26,27,24,26,28,27,27,28,29,28,28,30,29,28,29,29,29,29,29,29,29,29,30,29,28,29,29,30,29,29,30,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,29,29,30,30,29,29,29,30,29,29,30,29,29,30,29,30,28,30,29,30,29,29,30,30,30,30,30],[23,22,21,21,21,20,20,20,18,16,16,13,13,9,9,6,5,4,3,2,2,1,0,1,2,3,4,4,6,7,7,10,11,12,13,16,16,18,20,20,20,20,20,21,22,23,22,20,22,23,20,20,24,24,20,24,25,23,24,25,26,25,25,26,27,29,28,29,29,29,30,28,30,29,29,29,30,30,30,30,30,31,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,31,30,30,30,30,30,30,31,31,30,30,30,30,30,31,30,30,31,31,30,30,31,31,30,31,31,30,31,31,31,30,30,30,30,30,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,30,29,30,30,29,28,29,29,27,28,29,27,28,29,29,30,30,29,29,30,31,30,30,31,31,30,30,31,31,30,31,31,30,31,31,31,30,31,30,31,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,30,30,30,31,30,30,30,30,30,30,30,30,29,29,30,29,28,28,27,29,30,28,29,29,30,29,30,30,30,29,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,30,31,31,30,30,30,30,29,30,30,30,29,29,29,29,29,29,28,29,28,28,28,27,25,27,27,27,27,28,28,27,27,28,28,27,28,28,28,27,28,28,28,28,28,28,27,27,27,28,27,27,28,27,27,28,28,29,28,28,28,28,28,28,28,28,28,29,28,28,29,29,29,29,28,29,29,29,29,29,28,28,29,29,29,29,29,29,29,29,30,29,30,30,29,30,30,29,29,29,29,29,29,30,29,30,30,30,29,30,30,30,30,30,31,29,29,31,30,28,30,31,30,29,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,31,31,30,31,30,31,29,30,31,30,29,30,31,29,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,30,30,31,30,29,30,30,30,29,29,29,29,29,28,29,29,27,29,28,28,27,29,28,26,28,29,27,29,25,25,23,26,22,22,25,25,28,28,29,29,29,29,30,29,30,30,30,29,30,28,30,29,30,30,29,30,30,29,29,30,30,29,29,30,29,28,29,30,29,28,29,30,28,29,30,29,29,28,29,29,28,29,30,29,29,30,30,30,29,29,29,29,28,28,29,28,28,28,29,28,25,28,26,28,28,26,28,28,28,27,28,28,27,29,29,28,29,29,28,29,29,29,30,29,30,30,30,31,30,30,31,31,31,30,31,31,31,31,30,30,30,30,30,29,30,30,30,29,30,29,29,30,30,30,29,30,30,30,29,30,30,29,29,29,29,29,29,28,29,28,28,28,28,28,28,28,27,28,28,28,27,26,27,28,28,27,27,27,28,27,28,28,28,29,28,28,29,28,30,29,30,30,30,29,30,29,29,30,29,29,28,29,29,27,28,28,27,28,27,26,28,27,28,28,28,28,28,29,28,28,29,29,29,29,29,29,29,29,30,30,29,30,30,28,29,28,29,29,27,26,27,25,26,26,27,26,24,27,27,26,27,28,28,27,28,28,27,28,29,28,28,29,29,29,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[23,22,22,21,21,21,21,20,18,18,15,15,13,11,10,8,7,4,4,3,2,2,1,0,1,2,3,4,4,6,7,8,10,12,13,16,15,17,18,18,19,19,20,21,21,23,22,21,21,23,21,21,24,25,20,24,26,23,24,25,27,25,26,27,27,29,29,30,29,29,30,29,30,30,29,29,30,30,30,30,30,31,30,29,30,30,28,29,29,30,30,29,29,30,30,30,30,31,30,30,31,31,30,31,31,30,30,31,31,30,30,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,31,31,30,30,31,31,30,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,29,30,30,28,29,29,28,28,28,28,26,28,29,26,28,29,29,29,30,29,29,30,30,30,29,30,31,30,30,31,31,29,31,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,30,30,31,30,30,30,30,30,29,29,29,29,28,29,29,27,28,27,29,29,27,29,29,30,28,28,30,29,29,30,30,29,29,31,30,30,30,30,31,30,31,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,30,31,31,30,30,30,30,29,29,30,29,30,29,29,29,29,28,29,27,26,27,28,28,27,28,29,27,26,29,28,27,28,29,27,27,28,28,28,29,28,28,28,27,28,28,28,28,28,28,28,28,29,28,28,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,30,31,30,30,31,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,29,30,30,30,31,30,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,31,30,30,31,30,30,31,31,31,31,30,31,31,31,31,31,30,31,30,30,30,30,30,29,30,29,30,29,27,29,29,27,29,29,28,27,28,28,26,27,28,28,28,26,26,23,25,22,22,24,26,28,28,28,29,28,29,29,29,30,29,29,28,29,28,29,28,29,29,29,29,30,29,28,29,30,29,29,30,29,28,29,30,28,28,30,30,28,29,30,29,29,29,30,29,29,30,30,29,30,30,30,31,30,30,30,30,30,29,29,30,29,28,29,28,26,28,26,29,28,27,27,29,29,27,28,29,28,28,29,29,29,29,27,30,29,29,30,29,30,30,30,30,30,30,30,31,31,30,31,31,31,30,30,30,29,30,29,28,29,30,29,28,30,29,30,30,30,30,29,30,30,29,29,30,30,29,29,30,29,28,29,29,29,28,29,30,29,29,29,29,30,29,29,29,29,28,26,29,29,26,25,27,28,29,27,28,29,29,28,29,30,29,30,30,30,30,30,29,30,30,29,29,30,30,28,29,30,29,29,29,30,29,28,28,29,28,29,29,29,29,28,30,30,28,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,28,30,29,29,29,29,28,28,28,26,24,23,29,29,25,29,29,28,28,30,30,29,29,30,30,29,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,31,31,31,30,30,31,31,30,30,31,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,29,31,30,30,30,30,30,31,30,31,31],[23,22,22,23,21,22,22,21,21,20,17,16,15,12,13,9,9,6,5,4,3,2,2,1,0,1,2,3,5,5,6,8,9,11,13,15,14,17,17,18,19,19,19,20,21,22,22,20,21,23,22,20,23,24,20,23,24,24,24,25,26,25,26,26,26,29,29,29,29,29,30,28,29,30,29,29,30,30,30,29,30,30,29,28,29,29,28,29,29,29,30,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,31,30,29,30,30,29,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,30,30,30,31,30,30,30,30,29,30,31,30,30,30,30,30,29,29,29,29,29,29,28,28,30,26,27,29,29,29,30,29,29,30,30,30,29,30,30,29,29,30,30,29,30,31,30,30,30,30,30,30,30,31,31,31,30,31,31,31,30,31,31,31,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,28,29,27,29,30,28,29,29,30,28,29,30,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,31,30,30,30,30,31,30,30,30,30,29,29,30,30,29,29,29,29,29,29,28,28,28,28,27,26,25,26,27,26,26,27,28,27,26,28,28,27,28,28,28,27,28,28,28,28,27,28,26,26,26,27,26,27,27,27,26,28,28,28,28,28,27,27,27,27,27,27,27,27,27,27,28,28,28,28,27,28,28,29,29,28,29,28,29,29,28,29,29,29,29,29,30,29,30,29,29,30,29,29,30,29,30,29,29,30,29,30,30,30,30,29,30,30,29,30,30,29,29,30,30,29,29,30,29,29,29,30,29,28,29,29,28,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,31,30,31,31,30,30,30,30,29,30,30,30,30,30,30,30,29,28,30,30,28,30,30,29,27,30,29,27,27,29,28,27,26,26,22,25,21,22,25,25,28,27,29,29,29,29,29,28,30,30,30,28,29,29,29,28,30,30,28,28,30,29,27,30,30,28,28,30,29,28,29,30,29,27,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,27,28,25,29,29,25,28,29,29,27,29,29,27,28,28,29,29,28,28,30,29,28,30,28,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,28,29,30,29,28,29,29,30,30,30,30,29,30,29,30,29,30,30,29,29,30,30,28,29,30,29,28,29,30,29,28,29,29,29,29,29,29,29,28,27,29,29,27,25,25,28,29,27,28,29,29,28,29,29,29,29,29,30,30,30,29,29,29,30,29,29,29,29,29,29,29,28,29,29,28,27,27,28,27,28,29,28,28,28,29,28,28,29,28,29,29,28,29,29,29,29,29,30,29,29,29,29,29,28,28,28,27,28,27,27,27,25,26,25,28,28,26,28,29,28,28,29,29,28,29,30,30,29,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,29,29,30,30,29,30,30,29,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30],[25,24,24,23,22,23,22,21,20,20,18,17,17,13,12,10,11,9,6,5,4,3,3,2,1,0,1,2,4,5,4,7,9,10,12,14,13,16,17,17,19,19,19,20,20,22,21,20,20,22,20,19,23,24,18,23,25,22,22,24,26,24,25,26,26,29,28,30,28,29,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,28,30,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,30,30,30,30,30,30,30,31,31,30,31,31,30,30,31,31,30,31,31,30,30,31,31,30,31,31,30,30,30,30,30,30,30,30,30,31,31,30,31,31,30,30,31,31,30,31,31,31,30,31,31,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,31,30,30,30,30,30,30,30,30,29,30,29,28,29,29,27,27,29,30,30,30,29,30,30,31,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,29,29,30,30,28,29,28,30,30,29,30,30,30,29,30,30,30,29,30,30,30,29,30,31,30,30,30,31,30,30,30,30,30,31,30,30,31,31,30,30,31,31,30,31,31,31,30,31,30,31,30,30,30,30,29,30,30,30,29,29,30,30,29,29,28,29,28,28,28,27,25,27,27,26,27,28,27,27,27,28,27,27,27,28,27,27,27,28,28,28,27,28,26,26,27,28,26,26,28,27,28,29,27,28,28,28,28,27,27,28,27,28,28,28,28,28,28,28,28,28,28,29,29,29,28,28,28,28,29,28,28,29,29,29,29,29,30,29,30,29,29,30,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,31,30,29,31,30,28,30,31,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,31,30,31,30,31,30,30,31,30,30,31,31,30,30,31,31,30,30,30,30,30,30,30,31,30,30,31,30,31,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,28,29,29,29,27,30,28,27,28,29,28,28,26,27,22,26,22,22,25,26,28,28,29,29,29,30,30,28,30,30,30,29,29,29,29,28,30,30,28,29,30,30,29,30,30,29,29,30,29,28,29,30,29,28,30,30,29,29,30,30,29,28,30,29,29,29,30,30,29,30,30,30,29,29,30,30,29,29,29,28,28,29,30,28,27,29,26,29,29,26,29,29,28,27,29,28,27,29,29,29,29,29,28,30,29,29,30,29,30,30,30,30,30,30,30,31,31,30,30,30,31,31,30,31,30,30,29,29,30,30,30,29,30,29,29,30,30,29,29,30,30,30,29,30,30,29,29,29,29,29,29,29,29,29,28,29,29,29,28,28,28,28,28,29,28,27,28,29,28,27,27,26,28,28,27,27,28,28,28,29,29,29,30,29,29,30,30,30,30,29,29,29,29,29,29,29,29,28,29,29,27,29,28,27,28,27,28,28,28,28,28,29,28,28,29,28,29,29,29,29,29,29,30,30,30,30,30,28,29,29,29,28,28,27,28,25,26,27,27,27,26,27,28,28,28,28,28,28,29,29,28,29,29,29,29,30,29,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,31,30,30,30,31,30,31,31,31,30,30,30,30,30,30,30,30,31,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,31,31,31],[26,25,25,25,24,24,24,23,22,21,20,18,17,15,13,13,12,11,8,6,5,4,4,4,3,2,0,1,3,4,4,5,7,9,11,12,13,15,16,16,18,18,19,20,21,22,21,20,21,22,20,20,23,23,19,24,25,23,23,25,27,25,26,27,27,29,28,29,30,29,30,30,30,30,30,30,30,31,31,30,31,31,30,30,30,30,29,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,29,29,29,28,29,30,26,27,29,29,30,30,29,30,30,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,29,30,29,29,29,28,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,30,30,29,29,29,29,29,27,25,26,29,28,26,29,29,28,26,28,28,28,28,29,27,27,29,28,28,29,28,29,28,28,29,28,28,29,29,28,29,29,29,30,29,29,30,29,29,29,30,30,30,30,30,29,30,30,30,29,29,30,30,30,30,29,29,29,30,29,29,30,29,30,30,30,30,29,30,30,29,30,29,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,30,31,30,30,30,30,30,31,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,29,30,30,28,29,30,29,28,29,29,27,28,29,28,28,26,26,24,25,23,22,26,27,29,29,29,29,29,29,29,28,30,30,29,29,29,28,30,28,29,30,29,29,30,29,29,30,30,29,29,30,29,28,29,30,29,29,30,30,29,29,30,30,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,28,29,27,30,30,27,29,29,29,27,29,29,28,28,29,29,29,29,28,30,29,29,30,29,30,30,30,30,31,30,31,31,31,30,31,31,31,31,30,30,30,30,30,29,29,30,29,28,30,29,29,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,29,27,27,29,30,28,28,29,29,28,29,30,29,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,29,28,30,29,29,30,29,29,29,30,30,29,30,30,30,30,30,30,31,30,31,31,31,31,31,30,30,30,30,30,30,30,30,28,28,29,28,27,27,29,30,28,30,30,29,29,30,30,30,30,31,30,30,31,31,30,30,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,30,30,31,31,30,30,31,31,30,31,31,30,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31],[26,24,24,25,23,26,24,23,24,22,21,22,19,17,17,14,14,12,12,10,7,6,5,4,4,3,2,0,1,3,4,5,5,7,10,12,13,15,15,16,18,18,18,19,21,21,21,19,21,23,21,19,23,23,20,24,25,24,23,26,27,25,26,28,27,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,30,30,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,30,30,30,30,30,29,29,29,30,26,27,29,29,30,30,30,30,30,31,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,30,30,29,30,28,30,30,28,30,30,30,30,30,30,30,30,30,31,30,29,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,30,30,30,30,30,29,29,29,28,28,28,26,24,24,28,28,25,28,29,28,25,29,29,28,28,29,28,27,29,28,28,29,28,28,27,26,28,28,28,28,28,28,28,29,29,29,29,29,29,28,29,29,29,28,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,29,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,31,31,30,30,31,31,29,30,31,30,30,30,31,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,31,30,30,31,31,31,30,31,31,31,31,31,31,30,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,31,30,29,30,30,29,30,30,29,28,30,29,28,28,30,29,28,26,27,24,25,22,23,27,27,30,28,30,29,29,30,30,28,30,30,30,28,30,28,30,28,30,30,28,28,30,30,28,30,30,29,29,30,30,28,29,30,30,29,30,30,30,29,30,31,30,30,31,30,30,30,30,30,30,31,31,31,31,30,30,30,30,30,31,30,30,30,30,30,28,29,27,30,30,27,29,30,29,27,30,30,27,28,29,29,30,28,29,30,30,29,30,30,31,30,30,30,31,30,31,31,30,30,30,31,31,31,30,30,30,30,29,29,30,30,30,29,30,29,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,29,29,30,30,30,30,29,30,30,29,30,30,29,29,30,30,28,27,26,29,30,27,28,29,29,28,29,30,29,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,28,29,30,29,28,29,29,29,29,29,29,28,29,30,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,29,30,29,29,29,29,28,29,28,28,28,27,28,27,29,30,28,29,30,29,29,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,31,30,31,31,30,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31],[27,26,26,26,25,26,25,23,24,24,22,22,21,18,18,16,15,15,12,12,10,6,6,6,4,4,3,2,0,1,2,4,5,5,7,10,10,14,15,15,16,17,18,19,20,21,21,20,20,22,20,19,22,23,18,23,25,22,21,24,26,24,25,26,26,29,29,30,29,29,30,29,30,30,30,30,30,30,30,30,31,31,30,29,30,30,29,30,30,30,30,30,30,31,31,30,30,31,30,30,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,30,30,30,29,29,30,27,27,30,29,30,30,30,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,29,30,28,30,31,29,30,30,31,30,30,31,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,30,30,30,29,29,28,29,28,27,28,26,25,26,27,27,27,28,28,28,26,28,28,27,26,28,27,26,28,28,28,28,28,28,27,26,28,28,27,27,28,28,28,29,28,29,29,29,29,28,29,29,28,29,29,28,28,28,29,29,29,28,29,29,29,29,29,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,29,29,30,29,30,30,30,30,30,30,31,31,31,31,31,31,30,30,31,31,30,31,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,30,30,30,30,30,30,29,30,30,29,28,30,29,27,29,29,28,28,26,27,23,26,22,23,27,28,29,28,30,29,29,30,30,29,30,30,30,28,30,29,29,27,30,30,28,29,31,30,28,30,30,29,29,31,30,29,29,30,30,29,30,30,29,29,30,30,30,29,30,30,30,30,31,30,30,31,31,31,31,30,31,30,30,30,30,30,30,29,29,29,28,29,28,30,30,27,29,29,29,28,30,28,28,28,29,29,29,29,29,30,29,29,30,29,30,30,30,31,31,30,31,31,31,30,31,31,31,31,30,31,30,30,29,28,30,30,29,27,30,29,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,30,30,29,29,30,29,29,29,30,30,30,29,30,29,29,29,30,29,29,29,28,29,29,27,29,28,28,28,29,29,29,30,29,29,30,30,30,29,30,29,30,29,30,29,29,29,29,29,29,29,30,28,29,29,28,29,29,29,29,29,30,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,28,29,28,28,28,28,30,29,28,30,30,29,29,30,30,30,30,31,30,30,31,31,30,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[27,27,27,26,26,26,25,26,24,24,23,22,22,20,19,17,16,15,14,13,11,10,8,6,5,5,4,3,2,0,1,3,3,4,5,7,9,13,14,15,16,17,18,19,20,20,20,19,20,22,21,20,22,22,21,23,24,23,23,25,26,25,25,26,27,29,28,29,29,29,30,29,30,30,30,29,30,30,30,29,31,31,30,29,30,30,28,29,29,30,30,29,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,30,30,29,30,29,28,29,30,26,27,29,29,29,30,30,30,30,31,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,29,30,29,29,30,28,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,30,30,30,30,29,29,28,28,29,27,24,24,28,28,25,26,29,28,27,28,28,28,27,29,28,26,28,28,29,29,29,29,28,28,28,29,28,29,28,29,28,29,29,30,29,29,30,29,29,29,29,30,29,29,29,29,29,29,30,29,29,29,30,30,30,29,29,29,30,30,29,30,29,30,29,29,30,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,31,30,30,30,31,29,29,30,29,28,29,29,26,27,28,28,27,26,26,25,26,24,24,27,27,29,29,29,29,29,29,29,29,29,30,29,29,29,28,29,27,29,30,28,28,30,29,28,29,30,29,29,30,29,28,29,30,29,29,30,30,29,29,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,30,31,31,30,29,30,30,30,29,30,30,29,29,28,30,30,28,29,30,29,27,29,30,28,28,29,29,29,28,28,30,29,28,30,29,30,30,30,30,30,30,30,31,30,30,30,31,31,30,30,30,29,29,29,27,29,29,29,27,29,29,29,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,30,30,29,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,28,28,29,29,27,28,29,29,27,29,29,29,30,30,30,30,30,30,30,30,29,29,30,30,29,30,30,30,29,30,30,30,29,29,30,29,29,30,30,28,29,31,30,29,30,30,30,31,30,31,30,30,30,30,31,31,31,30,30,30,30,30,30,30,30,28,28,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31],[27,26,27,27,25,27,26,25,25,25,23,24,22,21,21,20,19,17,16,15,13,11,10,7,6,5,4,3,3,1,0,1,3,4,6,6,10,11,13,14,16,17,17,19,19,20,20,20,20,21,21,19,22,22,20,23,24,23,23,24,25,25,25,26,26,29,29,29,29,29,30,28,30,30,29,29,30,30,30,29,30,30,29,29,30,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,30,31,31,31,30,31,31,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,30,31,31,30,30,31,31,30,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,30,31,30,30,30,30,29,30,29,29,29,30,27,27,30,29,29,30,30,29,30,31,30,30,30,30,30,30,31,31,30,31,31,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,30,28,30,30,29,30,29,30,29,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,29,30,30,30,29,30,30,29,29,28,29,28,27,29,27,26,25,24,27,28,26,26,28,28,25,28,28,28,26,29,29,27,29,29,29,28,28,28,27,26,27,28,27,28,28,28,28,29,29,29,29,29,28,29,28,29,28,28,29,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,30,29,30,30,29,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,31,31,30,31,31,30,30,31,31,30,31,31,31,30,31,30,30,31,31,30,31,31,30,31,31,31,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,29,28,30,29,27,27,29,29,27,26,26,23,25,22,24,27,28,30,28,30,28,30,30,29,28,30,30,30,28,29,29,30,27,30,30,28,28,30,29,27,29,30,28,28,30,29,28,29,30,30,28,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,31,31,30,31,30,30,30,30,30,30,29,30,30,29,29,28,30,30,28,28,30,29,27,29,29,27,27,28,29,29,28,29,30,29,28,29,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,28,29,30,29,26,29,28,29,29,30,29,29,30,30,30,28,29,29,29,28,30,29,28,29,30,30,28,29,30,30,29,30,30,30,30,29,30,30,30,29,29,29,29,28,27,29,29,27,28,29,30,28,29,29,28,29,29,29,30,30,29,29,29,29,29,29,30,29,29,29,30,29,29,29,29,28,29,29,28,29,29,29,28,29,29,29,28,29,28,29,30,29,29,29,30,30,30,30,30,30,29,30,29,29,29,29,28,29,28,29,29,28,28,28,29,29,28,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31],[29,28,28,28,27,28,27,26,26,26,24,24,23,22,22,20,21,18,16,17,15,13,12,11,7,6,5,4,3,3,1,0,1,3,4,5,6,7,11,12,15,15,16,18,19,19,19,18,19,20,19,18,21,21,19,21,23,21,22,22,24,23,23,25,25,28,28,29,29,28,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,31,30,30,30,30,31,30,31,31,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,29,30,28,28,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,29,30,31,30,30,30,31,30,30,31,31,30,30,31,30,30,31,31,31,30,31,31,31,31,30,30,30,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,30,30,30,29,29,30,29,29,29,28,28,28,28,28,27,25,26,26,26,27,27,27,28,26,28,28,27,27,28,27,26,28,28,28,28,28,28,26,27,28,28,27,27,28,28,28,29,28,30,28,29,29,28,29,29,29,28,29,29,29,29,29,29,29,28,29,29,29,29,29,28,29,28,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,28,29,30,29,29,29,29,29,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,30,31,31,29,31,31,30,30,31,31,30,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,28,29,30,29,28,25,28,24,27,24,24,28,28,30,29,30,29,30,30,30,29,30,30,29,28,29,28,29,27,30,30,28,29,30,30,28,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,31,30,30,30,31,31,31,30,31,30,30,30,30,30,30,30,30,30,29,30,29,30,30,28,29,30,29,27,29,29,27,29,28,29,28,28,29,30,29,29,30,29,30,30,30,30,30,30,30,31,31,30,30,31,31,31,30,30,29,30,29,28,29,30,29,26,29,29,29,30,29,29,29,30,30,30,29,29,30,30,29,30,29,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,29,29,30,30,29,29,29,28,29,29,28,29,29,29,28,29,29,28,30,29,30,30,30,29,29,29,29,30,29,30,29,30,29,29,30,30,29,30,29,29,29,28,28,29,29,28,28,29,28,29,29,28,29,30,29,29,29,30,30,30,30,30,30,29,30,29,30,29,29,29,29,28,29,29,28,28,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,30,30,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[29,28,28,28,28,28,28,27,26,26,25,24,25,22,23,22,21,19,19,17,16,15,13,12,9,8,6,5,4,3,3,1,0,1,3,4,6,6,7,10,13,14,15,17,18,19,19,19,20,20,19,20,22,22,20,22,24,23,23,24,25,24,25,26,27,29,28,29,29,29,30,30,30,31,30,30,30,31,30,30,31,31,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,29,30,27,28,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,29,30,31,30,30,30,31,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,30,30,30,30,30,29,28,29,29,27,26,26,29,28,26,28,29,28,26,29,29,28,27,29,27,27,29,29,28,30,29,29,29,28,29,29,29,29,29,29,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,28,29,29,29,28,26,27,23,27,23,25,28,29,30,29,30,29,30,30,30,29,30,30,29,29,29,28,29,27,29,30,28,28,30,30,28,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,29,30,31,29,30,30,30,28,30,30,28,29,29,30,29,28,29,30,29,29,29,29,30,30,30,30,31,30,31,31,31,30,31,31,31,31,30,30,29,30,29,28,29,29,29,27,29,29,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,31,30,31,31,30,30,30,31,30,29,28,30,30,28,29,30,30,28,30,30,29,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,31,31,30,30,30,30,29,30,30,30,29,29,30,30,30,30,30,30,31,30,30,30,31,31,31,31,31,31,30,31,30,31,30,30,30,30,30,30,30,29,29,30,30,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[28,28,28,28,27,29,28,27,27,27,26,26,25,24,24,23,22,20,19,19,17,16,14,12,12,10,8,6,5,5,4,3,2,0,1,3,4,5,5,7,10,12,13,15,17,18,18,18,19,20,19,20,21,22,20,22,23,22,23,24,25,25,25,26,27,29,29,29,30,29,30,30,30,30,30,30,30,30,31,30,31,31,30,30,31,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,29,29,30,28,28,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,30,30,30,30,30,29,28,29,29,28,26,26,29,28,26,28,29,28,26,29,29,28,27,29,28,27,29,28,29,29,28,29,28,28,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,29,30,30,29,30,29,30,29,29,30,29,30,30,30,30,29,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,29,31,30,29,29,30,29,29,27,28,25,28,25,26,28,29,30,29,31,29,30,30,30,29,30,30,30,29,29,29,30,27,30,30,29,28,31,30,29,30,30,30,30,31,30,30,30,31,30,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,31,29,30,30,30,28,30,30,29,29,29,30,30,29,29,30,30,29,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,28,29,30,30,27,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,30,31,30,30,31,30,31,31,30,31,31,30,30,30,30,30,30,29,30,30,28,29,30,30,28,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,30,31,31,30,31,30,30,30,30,30,29,30,31,30,29,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,30,31,30,31,30,30,30,30,29,29,30,29,29,30,30,31,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[29,29,29,30,29,30,28,28,28,28,26,27,26,26,26,25,24,22,22,22,21,18,17,16,14,14,13,10,7,6,5,4,3,2,0,1,3,4,5,5,7,10,12,14,16,17,18,18,19,20,20,20,21,22,20,22,23,22,22,23,24,24,24,25,26,28,29,29,29,29,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,30,30,30,31,30,30,31,31,31,30,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,28,29,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,30,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,29,29,29,28,28,28,27,26,26,28,27,26,28,28,28,26,29,28,27,26,28,28,26,28,27,29,28,28,28,27,27,28,29,27,28,28,28,28,29,28,30,29,29,29,29,29,29,29,28,28,28,28,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,29,30,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,30,31,30,29,30,30,29,29,28,29,26,28,26,26,29,30,30,29,30,30,30,30,30,29,30,30,30,29,29,29,30,27,30,30,28,29,31,30,29,30,31,30,30,31,30,29,30,31,31,30,30,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,29,30,31,29,30,30,30,29,30,30,29,29,29,30,29,29,29,30,29,29,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,30,30,29,30,29,29,29,30,29,28,30,29,30,30,30,30,30,30,30,31,29,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,31,30,31,30,30,30,30,30,30,30,29,30,30,29,30,30,30,29,30,30,29,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,29,30,30,29,30,30,30,29,29,30,29,30,30,29,30,30,30,30,30,31,31,30,31,31,31,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[29,29,29,29,28,29,28,27,28,27,26,26,26,25,26,24,24,23,21,22,20,19,19,17,16,15,14,12,9,8,6,4,4,2,1,0,1,3,4,4,5,6,9,12,14,15,16,18,19,19,18,19,21,22,20,22,23,22,23,23,24,24,24,26,26,29,29,29,29,30,30,30,30,30,30,30,30,31,30,30,31,31,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,28,28,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,31,31,30,31,31,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,30,30,30,29,29,29,28,29,28,27,26,25,28,28,26,27,29,28,26,28,29,28,27,29,28,26,28,28,29,29,28,29,28,28,28,29,28,28,29,29,29,29,29,30,29,30,30,29,29,30,29,29,29,29,29,29,30,29,29,29,29,30,29,30,29,29,29,29,30,29,29,29,29,30,29,29,30,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,30,30,31,30,29,30,30,29,30,28,28,25,28,25,27,28,29,30,30,30,30,30,30,30,29,30,30,29,29,29,29,30,27,30,30,29,28,30,30,28,31,31,30,30,31,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,31,29,30,30,30,29,30,30,29,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,30,30,30,29,30,29,28,29,30,29,28,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,31,30,30,31,30,30,30,30,30,30,29,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,29,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,30,30,30,30,31,30,30,30,31,30,30,30,30,30,29,30,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,29,29,29,29,30,29,29,29,29,28,28,28,28,28,26,25,25,24,23,23,22,22,19,17,17,16,14,12,10,9,6,5,4,3,2,0,1,3,4,5,5,7,10,13,15,16,17,17,17,18,19,19,21,20,21,22,22,22,23,24,24,24,25,26,29,29,29,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,30,31,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,28,28,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,29,29,28,29,28,27,26,24,28,28,26,26,29,28,25,28,29,28,25,29,27,26,28,28,28,29,28,29,28,28,29,29,28,29,29,29,29,29,30,31,29,29,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,30,29,30,29,29,29,28,30,29,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,29,29,30,30,28,28,28,27,28,26,28,29,30,31,30,31,29,30,30,30,29,30,30,30,30,29,29,29,27,29,30,29,29,31,30,29,30,30,30,30,31,30,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,29,31,31,29,30,29,30,30,28,30,30,30,29,30,30,30,30,30,30,31,30,31,31,30,30,31,31,30,30,30,30,29,30,29,28,29,29,29,27,29,29,29,30,30,30,30,30,31,31,30,31,31,30,30,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,29,30,31,29,30,30,30,29,30,30,29,30,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,30,31,31,31,30,30,31,30,30,31,30,30,30,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,29,30,29,30,28,28,29,28,28,28,27,27,28,27,26,25,24,23,22,22,22,20,18,18,17,15,14,12,8,7,6,5,4,3,2,0,1,3,4,5,5,7,10,13,14,16,16,17,17,18,19,21,19,21,22,22,22,22,23,23,24,25,26,28,29,29,29,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,31,31,30,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,29,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,30,31,31,30,31,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,31,30,30,30,30,30,29,29,29,28,28,27,27,26,26,28,27,26,27,28,28,26,28,28,27,26,29,28,26,28,28,28,29,28,28,28,27,28,29,28,28,28,29,29,29,28,30,29,30,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,29,29,29,29,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,30,31,30,30,30,30,29,29,28,28,26,29,26,28,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,27,30,30,29,28,31,30,29,30,31,30,30,31,31,30,30,31,31,30,30,31,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,29,30,30,30,29,30,30,30,30,29,30,30,28,30,30,30,29,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,30,30,30,29,30,30,28,28,30,29,27,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,31,30,31,31,30,30,30,30,30,30,29,30,30,29,30,30,30,29,30,30,29,30,30,30,30,31,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,29,30,31,30,30,30,31,31,31,31,31,31,30,30,30,30,30,30,30,31,30,30,30,30,30,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,29,30,29,29,29,29,29,29,28,28,28,28,27,26,26,25,24,23,23,22,20,20,19,17,16,15,11,10,7,5,5,4,3,2,0,1,3,4,5,5,7,11,13,15,15,16,17,19,19,20,20,22,22,22,23,23,23,24,24,25,26,28,29,29,30,30,31,30,31,31,31,30,31,31,31,30,31,31,30,31,31,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,29,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,30,29,28,29,28,27,27,25,28,28,27,26,29,28,26,28,28,28,27,29,28,27,28,28,29,29,28,29,28,29,29,29,28,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,30,29,29,29,28,30,29,29,30,29,29,30,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,29,30,30,29,29,29,28,26,29,27,29,29,30,31,30,31,29,30,30,30,29,30,30,30,29,29,28,29,27,29,29,29,28,31,30,29,30,31,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,29,31,31,30,30,29,30,30,28,30,30,30,29,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,30,30,30,29,30,30,27,28,29,29,27,29,30,30,30,30,30,30,31,31,31,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,29,30,31,30,29,30,31,29,30,30,31,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,30,30,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,29,29,30,29,28,29,28,28,28,28,27,27,26,25,24,24,24,23,20,21,20,18,18,16,13,13,10,7,5,5,5,3,2,0,1,3,4,5,5,8,12,14,14,15,17,18,18,19,19,21,21,22,22,22,23,23,23,24,26,28,29,29,29,30,30,30,31,31,31,30,30,31,31,30,31,31,31,31,31,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,29,28,29,28,27,27,25,28,28,27,27,29,29,26,28,29,28,27,29,28,27,28,27,29,29,29,29,28,28,29,29,28,29,29,29,29,30,29,30,30,30,29,30,30,30,30,29,29,29,29,30,29,29,29,29,29,29,29,29,30,29,29,29,30,29,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,29,30,30,29,29,29,29,27,29,27,29,29,30,31,30,31,29,30,30,30,29,30,30,30,29,29,29,30,27,29,30,28,28,30,30,28,30,31,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,31,30,30,30,29,30,30,27,30,30,29,29,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,30,30,29,30,29,28,28,29,29,26,29,29,30,29,30,30,30,31,31,31,30,30,30,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,29,30,31,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,29,30,29,29,29,29,29,29,28,27,27,26,26,25,24,24,23,22,22,21,19,19,17,14,14,12,9,6,5,5,5,3,2,0,1,3,4,5,6,8,12,13,13,15,16,17,18,19,21,21,21,23,23,23,23,23,25,25,28,29,29,30,29,30,30,30,30,31,30,30,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,28,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,29,29,28,29,28,28,27,24,28,28,27,27,29,28,26,28,29,28,27,29,28,27,28,27,29,29,28,29,28,28,29,29,28,29,29,29,29,29,29,30,29,30,30,29,29,30,29,29,29,29,29,30,29,29,29,29,29,30,29,30,29,29,29,28,30,29,29,29,28,29,29,28,30,29,29,29,29,29,29,29,30,30,29,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,29,29,28,29,28,29,29,30,31,30,31,29,30,30,30,29,30,30,30,29,29,29,29,27,29,29,29,28,31,30,29,30,30,30,30,31,30,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,30,30,29,30,30,27,30,30,30,29,30,30,30,30,30,30,31,30,31,31,30,30,31,31,30,30,30,30,29,30,29,27,28,29,29,26,29,29,29,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,31,29,30,30,30,28,30,30,29,30,30,30,31,30,30,30,31,30,30,31,31,31,31,31,31,30,31,31,31,30,30,31,30,30,31,30,30,30,31,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,29,30,29,29,29,29,28,28,28,28,27,26,26,24,24,24,23,22,23,22,20,20,18,15,16,16,13,9,7,6,5,6,3,2,0,1,3,4,5,6,9,11,13,14,14,15,17,17,19,20,20,21,22,23,22,22,25,25,28,28,29,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,31,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,30,30,30,30,30,29,29,28,28,28,27,27,24,26,28,26,26,28,28,25,27,28,27,25,28,27,26,27,27,28,28,28,29,28,28,29,29,28,28,29,29,29,30,29,30,30,30,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,29,29,30,29,29,29,29,30,30,30,30,30,30,30,30,29,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,29,29,29,29,27,29,28,29,30,30,31,30,31,30,31,30,30,29,30,31,30,29,29,29,30,27,30,30,29,28,30,30,29,30,30,30,30,31,30,30,30,31,31,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,30,28,30,30,28,30,30,30,29,30,30,30,30,30,30,31,31,31,31,31,30,31,31,31,30,30,30,29,30,29,28,28,30,29,26,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,28,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,30,30,29,30,31,30,29,29,30,30,30,30,30,30,31,31,30,30,31,31,31,31,31,31,30,31,30,30,30,30,30,31,30,30,30,30,30,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,31,30,30,30,30,29,29,29,29,29,29,28,28,27,26,26,25,26,25,23,24,24,21,21,20,17,18,19,16,14,11,8,6,6,6,4,2,0,1,3,5,6,9,9,11,13,14,14,16,17,20,19,20,23,24,24,24,25,25,26,28,29,29,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,31,30,29,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,29,30,29,28,29,28,27,28,25,28,28,27,26,28,28,26,27,28,28,26,27,27,27,27,27,29,29,29,29,29,28,29,29,28,30,29,29,29,30,30,30,29,30,30,30,29,29,29,30,30,30,30,29,30,30,30,29,29,30,29,30,29,29,29,29,30,29,29,30,29,30,30,29,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,29,29,28,29,29,30,29,30,31,30,30,30,30,30,30,29,30,30,30,29,29,29,29,26,29,29,28,27,30,30,28,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,28,30,30,27,30,30,29,29,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,30,30,30,29,30,29,27,27,29,29,25,28,29,30,30,30,30,30,30,30,31,30,30,30,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,30,30,30,30,30,31,30,30,30,31,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,28,28,27,27,26,25,26,25,23,24,23,21,23,21,17,19,19,18,15,14,10,7,6,5,5,3,1,0,1,3,6,7,7,9,11,12,13,15,16,17,18,19,21,20,23,22,23,24,25,28,28,29,29,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,30,30,30,29,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,30,29,29,29,28,28,28,27,27,27,23,26,27,27,25,27,27,25,26,27,27,25,27,26,26,27,27,27,27,27,28,28,27,28,28,27,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,27,29,28,29,29,28,29,29,28,29,29,29,29,29,29,29,29,29,30,29,29,30,29,29,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,29,29,27,28,28,29,30,30,31,29,30,29,31,30,30,29,30,31,30,29,29,29,29,27,29,29,28,27,30,29,28,30,30,30,29,30,30,30,30,30,30,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,29,30,30,29,30,27,29,28,26,30,30,29,29,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,31,30,30,29,29,29,27,27,29,28,24,29,29,30,29,30,29,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,29,30,30,29,30,30,30,28,30,29,27,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,30,30,30,29,29,30,29,30,30,29,30,31,30,30,30,31,30,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,28,27,27,26,25,26,25,23,24,24,22,23,22,18,20,20,19,16,15,13,10,7,6,6,5,3,2,0,1,3,4,5,6,9,10,9,13,14,17,16,17,20,20,22,22,23,24,24,28,28,28,29,29,30,30,30,31,31,30,30,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,29,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,29,29,29,29,27,28,27,26,27,24,26,27,27,25,27,27,26,26,27,27,26,27,26,26,27,26,28,28,27,28,28,28,28,28,28,29,29,29,29,29,29,30,29,29,30,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,27,29,28,29,29,28,29,29,27,29,29,29,29,29,29,29,29,29,30,29,30,29,29,29,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,29,29,27,28,28,29,29,30,31,30,31,29,30,30,30,29,30,30,30,28,28,29,29,26,28,29,28,27,29,29,28,29,30,30,29,30,30,29,29,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,29,27,30,29,25,29,30,29,28,29,30,30,29,30,30,30,30,31,31,30,30,31,31,30,30,30,29,29,29,29,27,27,28,28,24,28,29,29,29,29,29,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,29,30,30,28,30,30,29,27,29,30,27,29,29,30,30,30,30,30,30,30,29,30,30,30,30,31,31,30,31,30,31,30,30,30,29,30,30,30,29,29,30,29,30,30,30,29,31,30,30,30,31,30,31,31,31,31,30,31,30,31,30,30,30,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,28,28,28,27,26,26,25,25,25,23,23,24,22,23,23,19,20,21,20,17,16,14,13,11,8,7,7,6,3,2,0,1,3,4,4,7,9,9,9,12,15,15,14,17,20,22,21,23,24,23,28,27,28,28,29,30,30,30,30,30,29,30,31,30,29,30,31,29,30,30,30,30,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,29,30,30,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,31,31,30,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,29,29,29,28,26,27,26,25,26,23,26,27,26,25,27,27,26,26,27,26,25,27,26,25,26,26,27,26,27,27,27,27,28,28,27,28,29,28,28,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,28,29,28,29,28,28,28,26,29,28,28,29,27,28,29,27,28,28,29,28,29,29,29,29,29,30,29,30,29,29,29,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,29,30,29,28,28,29,27,28,28,29,29,30,30,29,30,29,30,30,30,29,30,30,29,28,28,28,28,26,28,29,27,27,29,29,28,29,29,29,28,30,30,29,29,30,30,29,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,29,30,29,29,29,27,29,28,25,29,29,28,28,29,29,30,29,30,29,30,30,30,31,30,30,30,30,30,30,29,29,28,29,29,26,27,29,28,24,28,28,29,28,29,29,30,29,30,30,29,29,30,30,29,30,30,30,30,30,31,30,30,31,30,30,31,30,31,31,30,30,31,30,30,30,30,30,29,29,30,30,28,29,29,29,26,28,29,26,28,29,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,28,29,30,28,29,30,29,29,30,30,30,30,30,30,30,31,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,28,28,27,26,26,25,26,25,23,24,24,22,24,23,18,22,21,21,19,18,16,16,15,12,9,8,7,6,4,2,0,1,3,4,4,5,7,7,8,11,12,13,15,16,19,19,21,22,23,26,27,28,29,29,30,29,30,30,30,29,30,30,30,29,30,31,30,29,30,30,30,29,30,30,30,30,31,30,30,31,30,30,31,30,31,30,31,31,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,30,31,30,30,31,31,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,31,30,31,31,29,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,29,30,30,30,30,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,31,31,30,31,31,30,31,30,31,31,30,30,31,31,29,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,29,30,30,29,29,28,28,28,25,26,25,24,25,21,24,25,24,23,25,24,23,24,26,25,23,25,25,25,25,25,26,26,26,26,26,26,28,27,26,28,28,28,28,28,28,29,29,29,29,28,29,29,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,27,28,28,28,28,27,28,28,27,27,28,28,28,28,29,28,29,29,29,29,28,29,29,29,29,30,29,30,30,30,30,31,31,31,31,30,31,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,30,29,29,29,28,28,29,26,29,27,29,30,30,31,29,30,29,30,30,29,29,30,30,30,29,29,29,29,26,29,29,28,27,29,29,28,29,29,30,29,29,29,29,29,30,30,29,29,30,30,29,30,31,30,29,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,30,30,30,30,30,29,29,29,29,29,25,29,27,25,28,29,28,28,28,29,29,29,29,29,30,29,30,31,30,29,30,31,30,30,29,29,28,29,29,26,25,27,28,23,27,28,28,28,29,29,30,29,30,30,28,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,31,31,31,30,30,30,30,30,30,30,30,29,29,29,29,27,29,29,28,26,28,28,26,28,28,29,29,29,29,29,29,29,29,30,30,29,29,30,30,29,30,30,30,29,29,30,28,30,29,28,28,28,29,28,28,29,29,28,30,30,29,29,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,31,30,30,30,30,30,30,29,29,30,29,28,28,27,28,27,25,27,25,21,24,24,21,24,22,19,22,22,22,20,20,19,18,17,14,12,9,8,7,5,4,2,0,1,3,4,3,6,6,6,7,10,10,13,14,16,18,20,21,22,25,26,27,27,28,29,29,30,30,30,29,29,30,30,29,30,30,30,28,30,30,29,29,29,30,29,29,30,30,30,30,31,30,30,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,30,30,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,29,30,30,30,30,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,31,31,30,30,31,31,30,30,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,29,30,29,29,28,28,27,27,25,27,26,23,24,21,23,25,25,22,25,25,22,24,26,26,25,26,25,25,26,26,27,27,27,27,26,27,28,27,27,28,28,28,29,29,29,30,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,28,29,28,28,29,27,28,28,28,28,27,28,29,27,27,28,29,27,29,28,28,28,29,29,28,29,29,29,28,29,30,29,30,30,30,30,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,31,31,31,30,30,30,30,29,29,29,29,28,28,28,29,26,28,28,29,30,30,31,30,30,29,30,30,29,28,30,30,29,28,28,29,28,26,27,28,27,26,29,28,27,29,29,29,28,29,29,29,28,30,30,28,29,30,30,29,30,31,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,30,29,29,30,29,30,29,29,28,29,25,28,27,24,28,29,27,27,28,28,29,29,29,29,30,29,30,30,30,30,30,30,30,29,29,28,28,28,28,26,25,27,27,24,27,28,28,27,28,28,28,29,29,30,28,29,29,29,28,29,29,29,29,30,30,29,30,30,30,30,30,30,31,31,30,31,30,30,30,29,30,29,29,29,28,29,28,28,29,28,27,28,28,26,27,28,29,29,29,28,29,29,29,28,29,30,29,29,30,30,29,30,30,30,29,29,30,29,29,30,29,28,28,30,28,28,29,29,28,29,29,28,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,28,28,27,27,27,26,26,25,23,25,24,22,24,24,20,23,22,22,20,20,18,18,18,16,15,12,9,7,6,5,4,1,0,1,3,3,4,5,5,6,7,10,11,12,16,16,19,21,20,26,26,26,27,28,29,29,30,30,30,29,30,30,29,29,30,30,29,29,30,30,29,29,29,30,29,29,30,30,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,30,31,30,30,29,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,29,28,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,31,31,30,31,31,30,31,29,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,29,30,29,29,28,26,27,26,23,26,25,22,24,21,23,25,25,22,25,24,23,23,24,24,23,25,23,24,25,25,25,26,25,26,26,26,27,27,26,28,28,28,28,29,28,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,27,28,27,26,28,26,27,28,26,27,28,26,27,27,28,27,28,28,28,28,29,28,29,28,28,29,28,29,30,29,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,29,29,28,28,28,28,27,28,27,27,28,28,29,30,30,29,30,28,30,30,29,28,29,30,29,28,27,28,28,25,27,28,26,26,28,27,27,28,28,29,28,29,29,29,28,29,30,28,29,30,30,29,30,31,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,30,29,29,30,29,29,29,28,28,28,25,28,27,24,27,28,26,26,28,28,29,28,29,28,29,29,30,30,30,29,30,30,29,30,29,28,28,27,28,25,27,26,26,23,26,26,28,27,28,27,28,28,29,29,28,28,29,29,28,30,29,29,29,30,30,30,30,30,30,30,31,31,31,31,30,31,30,30,30,30,30,30,29,28,29,29,27,28,29,27,26,27,28,26,27,27,29,29,29,29,28,29,29,28,29,29,29,29,30,30,29,29,30,30,29,29,29,28,29,29,28,28,27,29,27,28,29,28,28,30,29,28,29,30,30,30,31,31,31,30,30,30,30,30,30,30,31,29,30,30,30,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,29,30,30,28,29,29,29,28,28,28,28,27,27,26,26,25,25,24,24,25,23,24,24,20,23,23,23,20,20,19,18,18,17,16,13,11,8,7,5,5,3,1,0,1,3,4,3,5,5,6,6,10,11,14,14,17,20,20,24,25,25,27,28,29,28,29,30,29,28,30,30,29,29,30,30,29,29,30,30,29,28,29,30,29,29,30,30,29,30,30,30,30,30,30,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,31,30,30,31,31,30,31,31,30,30,30,30,30,31,30,30,30,31,30,30,31,30,30,31,31,30,30,31,30,30,30,30,29,30,30,30,30,30,29,30,30,29,30,30,30,30,30,31,31,30,31,31,30,31,31,31,31,30,31,30,31,31,31,31,31,30,31,31,30,31,30,31,30,30,30,30,31,31,29,30,30,30,30,28,30,30,29,30,30,30,30,31,30,30,30,31,30,30,31,31,30,30,31,31,30,30,31,30,30,31,31,30,30,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,30,30,30,30,31,30,30,30,30,30,31,31,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,28,30,31,30,29,30,30,29,30,31,31,30,31,31,30,31,30,29,30,31,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,29,29,29,28,29,28,28,27,26,26,25,22,24,23,21,23,20,22,23,23,21,24,24,23,24,25,25,23,26,24,24,25,25,25,25,25,26,25,24,26,27,26,27,27,27,27,28,28,29,28,29,28,29,28,28,28,28,28,28,28,28,28,28,28,28,27,28,27,27,27,27,27,25,28,27,27,27,25,26,27,25,26,27,26,26,27,27,27,27,28,27,27,28,28,28,27,28,29,28,29,29,30,30,31,30,31,30,30,31,31,30,31,30,31,29,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,30,31,31,30,30,31,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,31,30,30,30,30,29,30,29,28,28,29,28,27,27,28,27,28,27,28,29,29,30,29,30,28,30,30,29,29,29,30,30,29,28,29,29,27,28,29,28,27,29,29,28,28,29,29,28,28,29,29,28,29,29,28,29,30,30,29,29,30,30,29,30,30,30,30,30,31,30,30,30,30,31,30,31,30,30,30,31,30,30,30,30,30,30,30,29,30,30,29,28,29,28,29,29,29,28,28,24,27,25,25,27,28,26,27,28,28,28,29,29,28,29,29,30,30,29,29,30,30,29,29,28,28,28,28,28,27,26,27,28,23,28,28,28,27,27,26,28,27,29,29,27,28,29,29,27,29,29,29,29,29,30,29,29,30,30,29,30,30,30,30,30,30,29,30,29,29,29,29,29,28,28,28,26,28,28,27,26,27,28,26,27,26,27,28,28,28,28,28,29,28,29,29,29,28,29,29,29,29,29,29,28,28,29,27,28,29,27,27,27,28,26,27,28,28,27,29,29,27,28,29,30,29,30,30,30,29,29,29,29,29,29,29,30,29,29,29,29,29,30,30,30,30,30,31,30,30,31,30,31,30,30,31,30,31,31,31,30,30,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,29,30,30,29,30,29,29,29,29,28,28,28,27,27,25,27,26,21,24,25,21,23,23,19,22,23,23,21,20,19,18,18,17,16,15,13,11,9,6,5,4,3,1,0,1,3,3,3,4,5,5,7,10,13,14,16,18,19,22,23,26,27,28,29,28,29,29,30,29,29,30,30,29,29,30,29,28,30,30,28,28,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,31,30,30,30,31,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,29,29,30,30,30,30,31,30,30,30,30,30,30,30,31,29,30,30,30,29,31,31,30,30,30,31,30,31,30,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,31,31,31,30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,28,28,27,25,25,24,22,24,23,22,22,20,22,22,23,20,22,23,21,23,24,24,22,25,24,24,24,24,26,25,24,25,25,25,27,27,25,28,28,27,28,29,29,29,28,29,29,28,29,29,29,28,28,28,28,28,28,28,28,28,28,28,28,28,27,27,28,25,28,28,27,27,27,27,27,26,26,27,28,27,28,27,27,27,28,28,28,27,28,28,27,28,29,29,30,29,29,30,30,31,31,30,30,30,31,30,30,30,31,30,30,31,30,30,30,30,31,30,31,31,31,31,31,31,31,31,30,31,31,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,31,31,31,30,31,31,31,31,30,30,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,28,28,27,28,27,26,28,27,29,29,30,30,28,29,29,29,29,28,28,29,30,29,28,28,29,29,26,28,28,27,26,28,28,28,28,28,29,28,29,29,28,27,29,29,28,29,30,29,28,29,30,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,29,28,28,28,28,26,27,22,27,25,24,27,28,26,26,26,27,29,28,29,29,29,29,29,30,30,30,30,30,30,30,29,28,28,28,28,26,25,28,26,23,26,27,27,27,28,26,27,28,29,29,27,27,29,28,28,28,28,28,28,29,29,28,29,30,30,30,30,30,30,30,29,30,30,30,30,28,30,30,29,29,28,28,27,28,28,27,26,27,27,24,27,26,27,28,28,27,27,28,28,27,28,29,28,28,28,29,28,29,29,29,29,29,29,28,29,29,28,28,27,28,26,27,28,27,27,29,28,27,28,29,29,29,30,30,30,29,29,29,28,29,29,30,30,29,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,30,30,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,31,30,30,30,30,30,29,30,29,30,29,29,29,28,28,27,25,28,25,20,26,25,22,25,23,20,23,24,24,22,22,21,20,20,19,18,16,14,12,10,8,6,4,5,3,1,0,2,2,4,4,6,5,7,9,12,14,17,18,18,22,24,26,26,27,28,28,29,30,29,28,29,30,29,28,29,30,29,28,30,30,29,28,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,31,30,30,30,31,30,30,30,30,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,31,30,31,30,31,30,31,31,30,30,30,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,28,30,30,30,30,30,30,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,30,31,30,30,31,31,31,30,30,31,31,31,31,31,30,31,31,31,30,30,31,30,30,30,30,30,30,30,31,31,31,31,31,30,31,31,31,30,31,31,30,30,30,30,30,30,30,30,31,30,31,30,30,31,30,30,31,30,29,31,31,31,30,31,31,30,31,30,30,30,30,30,30,30,31,31,30,30,31,31,31,31,30,31,31,31,30,30,30,30,30,29,29,29,29,28,29,28,28,27,26,26,25,23,25,23,21,23,20,21,24,24,20,23,23,22,22,24,25,23,25,25,25,25,26,26,26,26,26,27,26,27,27,26,28,28,27,29,29,29,30,29,29,29,30,29,30,29,29,29,29,29,29,28,28,28,29,29,29,28,29,27,28,28,25,29,27,27,28,26,27,27,25,26,27,27,27,28,27,28,27,29,28,28,28,28,29,28,29,29,28,30,30,30,30,31,31,31,31,30,31,31,30,31,31,31,30,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,30,31,30,30,31,30,30,31,31,31,30,30,30,30,30,29,28,29,28,28,28,27,28,26,27,28,29,29,30,30,29,29,28,30,30,29,29,29,30,29,28,28,29,28,25,26,28,27,26,28,28,27,28,28,28,28,29,29,29,27,29,30,27,29,30,30,29,30,31,30,29,30,30,30,30,31,31,31,31,30,31,31,30,31,31,31,30,31,30,30,30,30,30,30,30,29,30,30,29,30,29,28,28,29,29,27,28,24,27,25,24,26,27,25,26,27,28,28,28,28,27,29,29,29,30,29,29,30,30,29,29,29,27,27,27,27,26,25,26,26,23,26,27,26,26,26,26,27,27,29,29,27,27,29,28,27,29,28,29,28,29,30,29,29,30,30,30,30,30,31,31,30,30,30,30,30,29,29,29,29,28,29,28,28,28,28,27,26,27,27,25,26,26,28,28,29,27,27,29,29,28,28,29,29,29,29,30,29,29,29,29,29,29,29,29,28,29,28,28,28,29,27,27,28,28,27,29,29,28,28,29,29,30,30,30,31,30,30,29,29,29,29,30,30,29,30,30,30,30,31,30,30,30,30,31,30,31,31,30,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,30,30,30,30,29,29,28,29,28,29,28,28,27,27,26,27,25,25,25,25,23,25,25,21,24,24,24,22,22,20,20,19,18,18,16,14,13,11,8,6,5,4,4,4,1,0,1,3,3,4,5,6,7,10,11,15,17,16,22,23,25,27,27,28,28,29,30,30,28,30,30,29,28,30,30,29,28,30,30,28,28,29,30,29,29,30,29,29,30,30,30,30,30,31,30,31,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,31,31,30,30,31,30,30,31,31,31,30,31,30,31,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,28,30,30,30,30,30,31,30,31,31,31,30,31,31,31,31,31,30,30,31,31,30,30,31,31,31,31,31,31,31,30,31,30,30,31,31,30,30,31,30,29,30,30,30,29,28,30,29,29,30,30,30,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,31,30,30,30,30,31,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,31,30,30,30,31,31,31,31,30,31,30,31,30,30,30,29,29,30,30,30,30,29,30,30,30,30,29,31,31,30,30,30,30,29,31,31,31,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,28,28,27,24,26,24,22,24,23,20,22,19,22,23,23,21,24,24,23,22,23,24,23,24,23,24,24,24,25,26,25,25,25,24,27,27,25,27,27,28,28,29,28,30,28,29,29,28,29,29,29,29,29,29,28,28,28,28,28,28,28,28,28,28,27,27,27,24,27,26,26,27,25,27,25,24,26,26,26,27,27,28,28,27,28,27,28,28,27,28,27,28,28,27,30,30,29,30,30,31,31,30,30,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,31,31,31,31,31,31,30,31,30,30,30,30,29,30,30,30,29,31,31,30,30,31,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,30,31,30,30,30,31,30,30,30,30,29,30,29,27,27,28,27,28,27,27,26,27,27,28,29,29,30,28,29,28,30,30,28,28,29,30,29,28,27,28,28,26,27,28,27,27,28,28,27,28,28,28,28,29,29,28,27,28,29,27,29,30,30,29,30,30,30,29,30,30,30,30,30,31,30,30,30,31,31,30,31,30,30,30,31,30,31,30,30,30,30,30,28,29,29,28,28,29,28,28,28,28,27,28,22,26,24,23,25,26,26,26,27,28,28,28,29,28,28,29,30,30,29,29,30,30,29,29,29,28,27,27,28,26,27,28,27,24,27,27,28,26,27,25,27,27,29,29,27,27,29,28,27,28,28,28,27,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,27,29,28,26,27,28,26,25,26,27,23,26,26,27,28,29,27,27,28,28,27,28,29,29,28,29,29,29,29,29,29,28,28,28,27,28,28,27,27,27,28,26,27,28,27,26,29,28,27,28,29,29,29,30,30,30,30,30,29,29,28,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,30,31,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,29,30,30,29,30,29,29,29,29,29,28,28,28,27,26,27,26,24,26,26,23,26,25,20,24,25,25,22,22,21,21,20,19,19,17,15,15,13,11,7,6,5,4,4,4,1,0,1,3,4,4,6,8,11,10,13,16,16,21,23,25,26,27,28,28,29,29,29,28,30,30,29,28,29,30,29,28,30,30,29,29,29,30,29,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,30,29,30,30,30,30,30,28,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,31,30,30,30,29,30,31,30,30,30,30,29,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,28,30,29,29,30,30,30,30,30,30,29,30,30,30,30,30,31,29,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,30,31,31,30,30,31,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,28,30,30,29,29,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,31,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,29,29,28,29,29,27,28,27,27,27,25,25,24,22,24,22,20,22,18,21,22,22,20,22,22,22,22,23,24,22,24,24,24,24,25,25,25,24,25,26,25,26,27,26,28,28,27,28,29,28,30,29,29,29,28,29,29,29,29,28,28,28,29,28,28,28,28,28,28,27,28,26,27,28,25,28,27,26,27,26,26,26,25,26,27,27,26,25,27,27,27,28,27,28,28,27,28,27,28,28,27,29,29,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,31,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,31,30,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,28,28,28,28,27,28,29,28,28,28,29,29,30,30,29,29,29,30,29,28,29,29,30,30,29,28,29,29,27,28,28,29,27,28,29,28,29,28,29,29,28,29,29,28,28,29,28,29,30,30,28,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,29,29,29,29,29,29,29,29,28,28,27,27,22,26,24,23,26,26,25,26,26,28,28,29,28,28,29,28,30,30,29,29,30,30,30,30,28,27,28,28,28,26,25,26,26,23,25,27,26,26,26,25,27,28,28,29,28,27,28,28,28,28,28,29,28,28,30,29,28,30,30,29,30,30,30,30,30,30,29,30,30,29,29,28,28,28,28,28,26,28,28,26,25,27,27,23,26,25,26,28,28,27,27,28,28,28,28,28,29,28,28,29,28,29,29,29,28,28,28,27,28,28,27,27,27,27,26,26,27,26,26,28,28,28,27,28,28,28,29,29,30,29,29,28,28,28,29,29,29,29,29,29,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,28,29,29,27,29,28,25,28,27,23,26,25,22,24,25,21,25,25,25,22,23,22,22,22,20,20,18,17,16,15,13,11,9,8,6,4,4,4,1,0,2,3,4,5,6,9,9,13,15,15,20,20,23,24,26,27,27,28,28,28,28,29,29,29,27,29,29,28,28,29,29,28,28,28,29,29,28,29,28,29,29,29,29,29,29,30,29,30,30,30,29,30,30,29,29,29,29,30,30,30,29,29,29,30,30,30,30,30,30,29,30,30,30,29,30,30,30,29,29,29,30,30,30,30,30,31,30,30,30,30,30,30,30,29,29,30,30,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,31,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,28,29,29,29,29,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,31,29,30,30,29,29,30,30,29,30,29,29,29,30,30,29,30,30,29,30,30,29,29,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,28,29,29,27,28,27,26,26,24,24,23,22,24,22,20,21,19,20,23,22,20,24,23,21,22,25,25,23,26,26,25,24,26,27,26,26,25,26,26,27,28,26,27,27,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,27,27,28,26,27,28,27,28,27,27,27,25,26,27,26,26,27,27,27,26,27,28,27,27,26,28,27,27,29,26,29,29,29,29,30,30,30,30,29,30,30,29,29,30,30,29,30,31,30,29,30,30,30,30,30,30,30,31,31,30,30,31,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,29,29,30,30,30,30,30,29,30,30,31,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,30,29,30,30,30,29,30,30,30,30,29,30,30,30,30,30,30,29,29,30,28,28,28,27,27,27,28,27,27,27,28,29,28,30,30,28,29,28,29,29,28,28,29,29,29,29,27,28,29,27,27,28,28,26,28,28,27,27,29,28,28,29,28,28,27,29,29,27,28,29,29,28,30,30,29,29,30,30,29,29,30,29,29,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,30,28,30,29,28,29,28,27,28,27,26,27,26,22,26,23,23,26,25,24,26,27,27,28,27,27,27,28,28,29,29,28,28,28,29,28,28,28,27,27,27,26,26,24,26,26,23,24,26,26,25,26,25,26,27,28,28,27,27,27,27,27,28,28,28,27,29,29,28,28,30,29,29,30,30,30,30,30,30,30,30,30,28,29,29,28,29,27,28,27,27,27,26,26,26,26,23,24,24,25,27,28,27,26,28,27,27,28,28,28,28,28,29,28,29,28,28,29,27,29,28,28,28,27,27,27,28,26,26,28,26,26,28,28,27,27,28,29,28,29,29,29,29,29,28,28,29,29,29,29,29,30,30,30,29,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,31,30,30,30,31,30,30,30,30,30,30,30,30,29,29,29,29,28,29,27,27,28,27,24,27,26,23,27,25,21,25,26,26,23,24,23,22,23,22,21,19,18,17,16,14,13,9,8,7,6,4,4,4,2,0,2,3,4,5,6,8,11,14,14,19,20,22,24,25,27,26,28,29,29,27,28,29,28,27,29,29,28,27,29,29,28,28,29,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,30,30,30,30,30,30,30,30,29,30,30,30,30,30,28,29,30,30,30,30,30,30,30,30,31,30,31,30,31,31,30,30,30,30,31,30,31,31,31,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,28,30,29,29,30,30,30,30,31,31,30,31,31,30,30,31,31,30,30,31,31,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,30,31,31,31,30,30,31,30,30,30,30,30,30,31,31,30,30,31,30,30,30,30,31,30,30,30,30,29,30,30,30,30,29,30,30,30,30,28,30,30,30,30,30,30,29,30,30,31,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,31,31,31,30,30,30,31,31,30,30,30,30,29,30,28,29,29,29,27,28,27,26,26,23,25,23,20,23,22,18,20,16,20,22,21,18,22,22,21,20,22,24,21,24,24,24,24,26,26,27,26,26,27,25,27,27,26,28,27,27,28,28,28,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,27,25,28,27,27,28,25,28,26,24,27,27,26,26,27,27,27,27,28,27,28,27,27,28,26,28,28,27,29,29,29,30,30,31,30,30,29,31,31,30,30,30,30,29,30,31,30,29,30,30,30,30,30,30,31,30,31,30,31,31,30,31,30,30,30,30,29,30,30,30,30,31,31,30,30,31,30,30,31,30,31,30,30,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,30,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,31,30,30,30,29,29,30,28,28,28,27,26,26,27,27,26,26,27,28,28,29,30,28,29,27,29,29,28,28,29,29,29,28,26,28,28,27,27,28,27,26,27,28,27,27,28,28,27,28,28,27,25,28,29,27,28,30,30,28,29,30,30,29,30,30,30,30,31,30,30,30,30,30,31,31,31,30,30,30,31,30,30,30,30,30,30,30,28,30,30,28,29,28,28,27,28,26,26,27,23,25,23,22,25,24,24,25,27,26,27,26,27,28,28,28,29,30,29,29,29,29,29,29,28,27,27,27,27,26,26,25,25,23,26,26,25,24,25,24,25,26,28,28,25,25,28,27,26,28,28,28,27,29,30,28,28,30,30,29,30,30,30,30,30,30,30,30,30,29,29,29,28,28,28,27,26,27,27,26,24,25,26,22,24,23,25,27,28,25,26,28,28,27,27,28,28,27,28,29,29,28,29,29,28,29,28,28,28,28,27,27,26,28,25,26,27,27,26,28,28,27,27,29,29,29,30,30,30,29,29,28,28,29,29,29,30,29,30,30,30,29,30,30,30,30,30,30,29,30,30,30,31,30,31,31,30,31,31,31,30,30,30,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,28,27,28,27,27,27,26,26,26,26,25,26,25,23,25,25,25,23,23,22,22,22,21,21,19,18,17,16,14,13,12,11,8,7,6,4,4,4,2,0,1,3,4,6,6,11,13,12,18,20,22,25,25,27,26,28,29,29,28,28,29,29,28,29,29,29,28,29,30,28,28,29,29,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,27,29,30,29,29,30,30,29,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,28,29,29,29,29,30,30,30,30,30,29,30,30,30,29,30,31,29,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,30,30,29,30,30,29,30,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,29,29,29,28,28,28,28,26,27,26,26,26,23,24,22,20,22,20,18,19,17,19,20,21,18,21,21,21,20,22,23,21,24,23,24,23,24,26,25,24,25,24,24,25,26,25,27,26,27,27,29,28,29,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,28,28,27,27,27,26,26,26,24,26,25,25,26,25,25,24,24,26,25,25,25,25,26,26,26,27,26,27,27,27,28,26,27,28,26,29,29,29,29,30,30,30,30,29,30,30,29,30,30,30,29,30,31,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,31,30,30,30,30,29,30,30,29,30,30,30,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,28,28,28,28,27,28,27,27,27,27,27,28,28,29,29,28,29,28,29,29,28,29,29,30,29,29,28,29,29,28,28,29,27,28,28,28,28,28,29,28,28,29,29,28,27,29,29,28,29,29,30,29,29,30,30,28,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30,28,29,29,28,28,28,27,27,27,26,27,27,21,24,22,23,24,24,24,27,27,28,28,28,28,28,29,28,30,30,29,29,30,30,29,29,29,28,28,28,28,27,27,27,27,24,27,28,27,25,26,24,25,26,28,28,26,25,28,27,27,27,28,27,26,28,29,28,28,30,30,29,29,29,30,29,29,30,29,29,29,28,28,28,27,27,27,27,25,26,27,24,23,24,24,20,23,22,24,26,27,26,25,27,27,26,27,28,28,27,28,28,28,28,27,28,27,28,28,26,28,27,26,26,25,27,23,25,26,25,25,27,27,26,25,28,28,28,29,29,29,29,28,28,28,28,28,28,29,28,28,29,29,28,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,29,30,30,29,30,29,28,29,28,26,27,27,25,27,27,23,26,27,26,24,25,24,24,23,22,22,21,20,18,17,17,15,13,12,10,8,7,7,5,5,4,1,0,1,3,5,6,10,11,13,17,20,20,24,25,27,26,28,29,28,27,29,29,29,28,29,29,29,28,29,29,29,28,29,29,29,29,29,29,29,30,29,29,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,28,29,30,29,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,29,30,29,29,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,29,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,29,29,29,30,30,29,29,30,30,30,30,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,27,28,28,29,27,27,27,25,24,22,23,20,18,20,18,18,20,17,18,21,21,17,21,21,20,20,22,24,21,23,25,24,23,25,27,26,26,26,26,25,26,27,26,27,28,27,28,29,28,29,28,29,29,29,29,29,29,29,29,29,28,29,29,29,28,29,28,28,28,28,28,27,28,26,28,27,27,27,26,26,26,25,26,27,25,26,26,27,27,27,27,27,27,27,26,28,26,27,27,26,29,29,28,30,30,30,30,30,29,30,30,29,30,30,30,29,30,31,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,29,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,28,30,30,30,30,30,30,29,30,30,30,29,30,30,30,28,28,29,28,28,26,28,27,28,28,29,29,29,30,30,29,29,28,30,30,28,29,29,30,30,29,28,29,29,28,28,29,29,27,29,29,28,28,29,29,29,28,29,28,27,29,29,28,28,29,30,28,29,30,29,29,29,29,29,29,30,30,30,29,29,30,30,30,30,29,30,30,30,29,30,29,29,30,30,30,29,29,29,28,28,28,28,28,28,27,27,26,20,24,20,20,25,25,23,25,25,28,27,29,27,29,29,28,29,30,29,29,29,30,29,29,29,28,29,28,28,28,25,27,27,24,26,27,26,24,26,22,26,26,27,28,27,25,27,27,27,26,28,28,27,28,29,28,28,29,30,29,29,29,30,30,30,30,29,30,30,28,29,29,28,29,28,27,26,26,26,25,24,24,24,20,23,21,23,26,26,25,24,27,26,27,27,28,27,27,28,29,27,27,28,28,27,28,28,27,27,27,26,25,25,26,22,24,26,25,25,27,27,26,27,28,29,28,29,29,29,28,28,28,27,28,29,28,29,28,29,29,30,28,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,29,30,29,29,29,28,27,29,28,26,28,27,24,27,27,24,27,27,27,25,26,24,25,25,24,25,22,22,20,20,18,17,15,16,15,12,11,9,8,7,6,4,2,0,1,3,5,8,10,12,16,17,20,22,24,27,26,28,28,28,26,28,29,28,27,29,29,28,28,29,29,28,28,30,29,30,29,30,29,29,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,31,31,31,30,30,30,31,30,30,30,30,30,30,30,31,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,31,30,30,31,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,31,31,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,31,31,30,30,31,31,31,31,31,31,31,31,30,30,31,30,31,30,30,31,30,31,31,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,31,30,30,31,31,30,31,30,31,31,30,30,30,30,30,30,29,28,29,29,27,28,27,27,24,21,23,18,18,20,18,16,18,17,17,20,22,18,21,22,23,21,23,25,22,24,25,25,25,26,26,28,27,28,27,26,28,27,27,28,28,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,28,29,29,29,29,28,27,28,27,27,28,26,27,26,25,27,26,25,27,26,27,27,25,27,27,26,26,25,28,27,27,27,27,29,29,29,30,30,31,31,30,29,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,31,31,31,31,31,30,31,30,30,31,30,30,30,31,30,30,30,30,30,31,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,31,30,30,30,30,30,30,30,29,30,30,28,28,29,27,27,27,27,28,27,27,28,28,28,30,30,29,29,28,30,30,29,29,30,30,30,29,29,29,28,27,27,29,28,25,28,28,27,26,28,29,27,29,29,28,26,29,30,28,27,30,30,28,29,30,30,28,30,30,30,30,30,30,30,30,30,31,31,31,31,30,30,30,31,30,30,30,30,30,30,30,29,30,29,29,29,28,28,28,28,27,26,27,22,25,21,22,25,23,23,25,26,27,27,27,27,27,29,28,29,29,29,29,29,29,29,29,29,28,28,27,27,26,24,26,26,23,25,25,25,24,25,22,23,26,27,28,26,24,27,27,27,26,28,28,27,29,29,28,27,30,30,29,30,30,30,30,30,31,30,30,30,29,29,29,29,28,28,27,27,27,26,25,24,24,23,20,21,20,23,25,26,25,24,27,27,26,26,28,28,26,28,29,28,28,28,29,28,29,28,28,26,27,27,27,23,27,22,24,26,24,25,27,28,27,26,28,30,28,30,29,30,29,29,28,28,28,29,29,30,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,31,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,29,30,29,28,29,28,27,28,28,26,27,27,26,28,26,25,26,27,27,25,26,25,25,24,24,24,23,22,21,21,19,18,17,16,15,14,13,10,10,9,7,6,5,2,0,1,3,5,7,9,13,16,18,21,22,25,25,27,28,28,27,28,28,28,27,29,29,28,27,29,29,28,28,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,30,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,31,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,30,30,28,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,30,28,29,29,29,29,29,30,30,30,30,30,31,30,30,30,30,30,30,30,29,28,29,29,27,27,28,28,25,27,26,25,23,19,22,18,16,19,19,17,20,16,18,21,22,17,22,23,22,22,23,23,24,24,24,25,25,27,26,27,27,26,27,25,26,27,27,27,27,28,29,29,29,30,29,30,30,29,29,30,30,30,30,30,30,29,29,30,29,28,29,28,29,29,28,28,26,26,27,26,27,27,26,27,24,25,27,25,24,26,25,27,27,26,27,26,25,26,24,27,26,27,26,25,29,29,28,30,30,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,31,30,30,30,30,31,31,31,30,30,30,30,30,30,30,30,29,30,30,31,31,30,31,30,31,31,30,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,28,28,29,28,26,26,26,28,27,27,28,29,29,29,30,29,29,27,29,30,28,29,29,30,30,29,29,29,29,28,28,29,28,26,29,29,27,27,29,29,26,28,29,28,26,29,29,27,28,30,30,28,29,30,29,28,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,28,29,29,28,28,28,27,27,26,25,26,25,22,22,20,21,24,22,22,25,26,27,27,28,27,28,28,28,29,29,29,29,30,29,28,29,29,28,29,28,28,27,27,27,26,25,27,26,25,24,25,21,22,25,27,28,25,23,27,27,25,26,28,28,26,28,29,28,27,29,29,29,29,29,30,29,29,30,29,30,30,28,28,29,28,27,28,27,25,26,25,24,23,23,22,18,20,17,21,24,26,23,22,26,27,25,25,28,27,25,28,28,27,27,28,29,26,28,28,26,27,27,26,26,24,26,21,25,26,25,24,26,26,25,26,27,29,27,29,29,29,28,28,27,27,28,29,29,29,28,30,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,29,29,29,28,29,28,27,28,28,26,28,28,25,28,28,28,27,28,26,26,26,25,26,24,23,23,23,22,20,18,18,17,16,15,12,11,10,9,8,6,4,2,0,1,3,5,7,11,13,16,21,21,24,24,26,27,27,24,26,27,27,25,27,28,28,26,28,28,27,28,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,29,30,30,29,30,30,30,29,29,27,29,30,29,28,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,28,29,30,29,28,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,29,28,29,30,29,29,29,29,27,29,30,30,28,29,30,29,29,28,26,28,28,29,28,29,30,29,29,30,30,30,30,30,30,30,30,29,29,28,28,27,28,26,26,27,27,23,26,25,25,21,17,20,15,15,18,17,15,20,16,17,21,22,18,22,22,23,23,23,24,24,25,25,26,26,27,26,27,27,27,26,26,26,27,27,28,28,28,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,29,29,28,28,26,27,28,26,27,28,27,27,25,25,27,25,25,26,25,27,27,25,26,26,26,26,24,26,26,27,25,25,27,28,28,29,29,30,30,30,29,30,30,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,30,30,28,30,30,29,28,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,27,28,29,27,26,26,27,28,28,28,29,29,28,29,30,29,29,29,30,29,28,29,30,29,29,29,29,29,29,29,29,30,29,28,29,29,28,27,29,29,27,28,29,28,25,29,29,26,26,29,29,27,27,29,29,26,29,29,29,28,30,30,29,29,30,30,30,30,30,29,30,30,30,29,30,30,28,29,29,30,28,29,29,28,28,26,26,27,25,24,26,26,21,22,18,21,24,21,20,25,26,26,26,28,27,28,29,28,29,29,29,29,30,29,29,29,29,29,29,29,29,28,27,27,27,26,27,27,26,24,23,19,20,25,25,26,24,20,25,26,22,24,26,26,23,27,28,27,26,29,29,28,28,28,29,29,29,30,29,29,29,27,28,29,28,27,27,26,24,25,24,22,21,21,20,16,18,13,18,22,23,19,19,24,25,22,23,27,26,24,27,28,27,27,28,29,26,29,28,27,26,26,26,26,23,25,20,23,25,23,22,25,26,25,24,26,28,27,29,29,29,28,28,27,27,28,29,28,29,29,30,29,30,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,29,30,30,28,30,29,28,29,29,27,29,28,26,28,28,28,27,27,27,27,27,26,26,25,24,24,24,23,21,20,19,20,18,16,15,13,12,11,10,9,7,5,2,0,1,3,6,9,13,15,18,20,24,22,25,26,27,24,27,27,26,25,26,28,27,26,28,28,28,28,29,28,28,29,29,28,29,29,29,29,29,29,30,29,29,30,29,29,29,29,29,29,29,29,29,30,29,29,29,30,29,30,30,29,30,30,29,30,30,30,29,30,30,30,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,29,28,29,29,29,28,28,29,29,27,28,30,28,29,29,29,29,30,29,30,29,30,29,30,30,30,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,30,29,30,29,29,30,30,29,30,30,30,29,30,30,29,29,30,29,28,29,29,29,27,29,29,28,28,28,29,28,29,28,29,29,30,29,29,30,30,29,29,30,30,29,30,30,29,30,30,30,29,30,30,30,30,29,29,28,30,30,29,28,30,30,28,29,30,29,29,30,30,30,29,29,29,29,29,29,28,29,29,28,28,29,28,27,29,29,28,28,29,29,28,29,28,26,28,28,28,27,28,29,28,28,29,29,29,29,30,29,30,29,29,28,27,27,27,27,26,26,27,26,23,25,25,24,19,17,17,16,15,18,18,18,22,16,17,22,23,19,21,22,24,24,23,24,25,26,26,26,26,28,27,28,28,27,27,26,27,28,27,28,28,28,29,29,29,30,29,30,29,30,29,30,30,30,30,30,30,30,29,30,29,29,29,28,29,29,28,28,28,27,28,27,27,28,27,26,25,25,25,25,25,25,24,26,25,25,26,25,26,26,24,26,26,28,26,26,28,28,27,28,29,29,30,29,28,29,29,28,29,29,29,28,29,30,29,29,29,30,29,29,29,30,30,29,30,29,30,30,29,30,30,28,29,29,29,29,29,29,29,30,29,28,28,29,28,27,29,28,29,29,29,29,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,29,29,29,29,29,29,30,29,28,28,30,30,27,28,29,27,26,26,27,28,29,28,29,29,29,29,30,29,29,29,29,29,29,29,29,30,30,29,29,29,30,29,29,29,29,27,29,29,28,27,28,29,27,27,29,28,25,28,29,27,27,28,29,26,27,28,28,26,28,28,28,28,29,29,28,29,29,29,29,30,30,28,29,30,29,28,29,29,28,29,30,29,29,29,28,29,29,26,27,28,26,24,26,25,21,22,18,21,22,20,19,24,24,26,25,27,26,28,28,27,28,28,28,29,29,29,28,28,29,28,28,28,28,28,27,27,26,26,27,25,24,22,22,17,20,24,24,26,24,20,25,25,23,22,26,26,24,27,28,27,26,29,29,28,28,29,29,29,30,30,28,29,29,27,28,29,29,28,26,26,27,27,23,24,23,21,19,16,18,14,18,21,23,20,20,24,25,23,23,27,26,25,27,28,27,27,28,29,27,28,28,28,27,26,27,26,24,25,21,23,25,22,23,25,26,24,24,26,28,27,28,28,28,27,28,27,26,28,28,28,29,28,30,29,30,29,30,29,28,30,30,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30],[31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,29,30,29,28,29,29,27,29,28,27,28,28,28,28,28,27,27,27,27,27,26,26,26,26,25,23,22,22,21,19,18,17,15,14,12,11,10,10,8,5,2,0,1,4,7,10,13,14,16,21,21,23,25,25,23,25,27,25,24,26,28,27,26,28,29,27,29,29,28,29,29,29,28,29,30,29,29,30,30,30,30,30,30,30,29,29,30,29,29,30,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,29,30,29,29,29,29,28,28,29,29,27,29,29,29,29,29,30,29,29,30,30,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,29,30,29,29,29,30,29,30,30,30,29,30,30,29,28,30,30,28,29,29,29,27,29,29,28,28,28,29,28,29,29,29,29,30,29,29,30,30,29,29,30,30,29,30,30,29,30,30,30,29,30,30,30,30,29,29,28,30,30,29,28,30,29,28,29,30,29,29,29,30,30,29,29,29,29,29,29,28,29,29,28,27,29,28,27,28,29,29,27,28,28,28,28,27,25,26,27,27,27,28,29,28,28,28,29,29,29,29,29,29,28,29,28,27,26,26,26,24,25,25,25,22,24,23,22,17,14,16,14,14,16,16,15,20,16,17,20,22,19,22,23,23,23,24,24,24,24,25,25,25,26,26,27,27,27,27,26,26,28,27,28,27,28,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,29,28,28,27,27,27,27,27,27,26,26,25,25,27,25,25,26,24,26,26,24,26,25,24,25,23,25,25,25,24,23,27,26,27,27,28,29,29,29,28,29,29,28,28,29,29,29,29,30,29,29,29,29,29,30,30,30,30,30,30,29,29,30,29,30,30,29,29,29,29,29,29,29,29,30,29,28,29,29,28,26,28,28,29,28,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,29,30,29,30,30,29,29,30,30,29,30,30,29,29,29,29,29,28,29,29,28,28,29,29,27,28,28,26,25,25,26,27,28,27,29,28,28,29,29,28,28,29,29,29,28,29,29,29,29,30,29,29,29,29,29,29,29,27,29,29,27,26,28,29,25,27,28,27,24,27,28,25,25,27,28,26,26,28,28,26,27,28,28,27,28,28,28,28,28,29,29,30,29,28,29,29,29,28,29,29,28,28,29,28,28,28,28,27,28,26,26,27,24,22,25,25,20,20,18,20,22,19,19,24,23,25,25,27,26,28,28,27,29,29,28,29,29,29,29,29,29,29,28,28,28,27,27,27,26,25,26,25,23,21,19,16,18,23,22,25,21,19,23,24,20,20,24,25,22,25,27,26,24,28,28,28,27,28,28,28,29,29,28,29,29,27,28,28,28,27,26,25,24,23,22,21,21,20,17,15,16,10,16,18,21,18,17,22,24,21,21,25,25,23,26,27,27,26,27,28,26,28,27,26,27,26,26,24,22,24,19,22,24,21,20,24,24,22,21,24,27,26,27,27,27,27,28,27,26,28,28,27,28,28,29,28,30,29,29,29,28,29,29,29,29,29,29,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30],[31,31,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,28,28,29,28,29,28,27,28,28,28,27,28,27,27,27,27,27,26,26,26,25,25,23,23,22,21,20,20,19,18,17,15,14,12,10,9,7,5,2,0,1,4,7,8,11,12,15,17,20,21,20,17,18,21,21,18,21,22,21,20,23,24,22,22,24,24,25,25,26,24,25,27,26,27,28,28,28,28,28,29,28,28,28,28,28,27,28,28,27,28,26,28,28,28,28,29,29,27,29,28,28,28,29,29,28,29,28,29,28,28,28,28,28,28,29,29,29,29,29,29,28,28,29,28,26,27,27,26,25,27,26,24,27,25,25,25,25,21,24,25,23,23,25,27,24,25,26,26,26,27,28,27,27,28,28,29,27,27,28,28,28,29,28,29,27,28,29,28,29,28,28,28,28,28,27,28,28,28,28,28,28,27,27,26,26,26,27,28,27,27,28,27,27,27,27,26,24,27,26,24,24,26,25,24,24,25,22,23,25,25,25,26,26,26,27,28,27,26,28,28,26,27,28,27,26,28,28,26,27,28,28,27,27,28,28,28,27,26,26,28,27,26,25,28,27,24,27,27,27,26,27,27,27,27,26,27,26,25,25,23,25,25,24,22,24,24,23,25,25,25,23,24,26,24,25,24,22,23,24,24,23,25,26,26,25,26,27,28,27,28,28,28,27,27,26,25,24,24,24,21,23,22,23,17,20,19,18,15,13,16,13,13,16,16,16,20,18,16,19,21,18,19,21,21,20,21,22,21,22,23,25,24,26,25,27,28,26,27,25,25,28,27,28,27,28,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,28,29,29,29,29,28,27,26,27,28,26,27,27,25,27,25,25,27,24,23,24,24,25,24,22,25,24,23,23,22,22,23,23,23,21,25,25,25,26,27,27,28,28,27,28,28,27,27,28,28,27,27,29,28,29,28,28,28,28,28,28,28,28,29,27,28,28,28,28,29,28,28,28,27,28,28,28,27,29,28,26,27,28,27,25,26,27,27,27,26,26,29,28,28,29,28,29,29,29,29,29,28,29,28,28,28,28,28,29,29,30,29,29,28,29,27,27,26,29,28,26,27,29,29,26,28,28,27,26,26,27,26,24,27,26,24,25,26,26,23,25,26,23,22,20,23,23,24,24,25,25,26,25,26,25,25,24,26,25,24,26,25,27,27,27,24,26,25,25,24,25,25,23,23,26,24,22,24,25,22,22,24,24,20,22,25,21,20,24,25,21,23,25,24,23,23,24,24,24,25,25,25,26,26,27,27,28,27,25,26,27,26,25,27,26,24,26,26,26,24,25,25,24,25,22,23,25,22,20,22,21,19,17,16,18,18,15,15,19,17,20,19,22,20,23,23,21,24,23,23,24,25,25,24,24,24,24,24,24,23,24,23,21,22,21,21,18,17,16,15,12,13,16,18,20,17,16,20,19,17,18,21,22,20,22,24,23,22,25,26,25,25,26,26,26,26,27,25,27,27,24,26,27,26,26,23,24,22,22,20,20,19,19,18,15,13,9,13,15,16,16,17,19,20,19,19,22,22,21,24,25,25,23,26,27,24,26,26,25,25,24,24,23,20,20,18,19,22,20,20,22,22,20,20,21,25,24,26,26,26,26,27,25,23,26,27,26,27,26,28,27,28,26,28,28,26,27,29,28,28,28,28,27,28,28,28,28,28,29,29,28,28,29,28,29,29,28,28,27,28,28,28,29,29,29,29,30,30,30,30,30,30,31,30,30,30,30,31,30,30,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30],[30,30,30,30,30,31,30,30,30,30,30,29,30,29,29,29,29,29,29,29,29,28,29,28,28,28,28,28,28,28,28,28,28,28,28,28,27,27,27,27,27,26,26,26,26,25,24,24,23,22,22,20,20,19,17,16,15,14,11,10,9,7,5,2,0,1,4,6,8,10,12,13,15,18,18,15,16,19,19,17,19,21,19,19,22,22,21,22,24,23,25,25,25,24,24,25,23,24,25,25,26,25,25,26,25,25,25,26,25,24,24,25,24,25,24,23,24,24,25,26,26,25,26,26,26,26,26,27,25,26,27,26,25,25,25,25,26,27,26,26,27,26,26,26,26,26,25,25,23,24,24,23,22,25,23,23,25,23,23,22,22,20,20,23,22,19,22,25,22,23,24,24,23,25,25,25,24,25,25,26,25,24,25,26,26,25,26,26,24,25,26,25,25,27,26,26,25,26,26,26,25,24,26,26,26,26,25,25,24,24,25,27,24,25,27,26,26,25,25,23,22,25,24,22,21,24,22,20,21,23,21,20,22,22,20,23,24,24,25,25,25,24,25,26,24,25,25,25,23,25,25,24,25,25,26,24,26,25,25,26,25,25,23,25,25,23,23,26,24,22,24,26,25,25,25,26,26,25,25,25,24,24,23,22,22,23,22,21,22,22,22,21,22,23,21,21,23,21,23,20,19,18,21,21,21,21,23,22,22,24,25,25,25,24,25,25,25,25,23,21,22,20,19,18,18,18,17,12,13,13,12,11,10,12,12,13,14,14,15,16,16,15,17,19,16,16,18,18,18,19,20,21,20,22,24,24,25,23,26,25,25,26,23,24,25,26,27,26,27,28,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,27,28,28,28,28,27,27,26,26,25,26,26,25,24,26,24,24,25,23,22,23,22,23,22,20,22,20,20,21,20,21,19,19,18,15,20,21,22,22,23,24,25,24,23,25,25,24,24,26,25,24,25,27,25,25,26,26,26,26,27,26,27,26,26,26,26,26,26,26,27,26,26,25,25,26,25,24,23,26,24,23,24,24,24,22,24,24,25,24,24,23,26,26,26,25,26,26,26,26,26,26,26,26,26,27,26,26,27,26,26,27,26,26,26,26,24,25,24,25,26,24,24,25,26,22,25,26,25,24,25,25,23,23,24,24,22,23,24,23,21,21,23,20,18,20,19,20,22,21,22,22,24,24,25,23,23,24,24,24,22,25,25,26,25,25,24,24,24,24,23,24,25,22,22,23,22,20,22,22,18,18,22,20,16,21,22,17,17,21,22,18,20,22,22,20,21,21,23,22,22,23,23,23,23,24,25,25,24,23,24,24,23,23,24,23,22,24,24,24,23,23,23,22,21,17,19,20,18,17,18,20,15,16,11,16,16,13,13,16,16,17,17,20,17,21,22,20,22,22,22,23,23,23,23,22,22,23,23,22,20,21,21,19,20,19,17,17,15,15,13,9,11,15,14,18,15,13,16,16,14,14,15,17,15,16,21,18,17,22,23,23,23,24,24,24,24,25,23,24,24,22,23,24,23,22,18,19,19,18,16,15,17,16,14,11,11,6,9,10,12,13,13,14,14,15,15,17,17,17,20,21,21,20,22,24,20,22,22,20,22,20,19,19,17,18,15,15,18,16,16,16,17,16,15,16,22,21,23,23,23,21,23,23,21,22,23,24,24,25,26,24,26,25,27,25,24,25,26,26,25,26,26,24,26,26,25,25,26,26,26,25,26,26,26,26,27,26,26,26,26,26,28,27,28,27,28,29,28,29,28,30,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29],[30,30,30,29,29,30,30,30,29,29,29,28,28,28,28,28,28,28,28,28,28,27,28,28,27,28,28,27,27,27,27,27,28,27,26,28,27,27,27,26,26,25,25,25,24,24,23,22,23,22,20,21,20,19,17,17,16,15,13,11,8,8,6,3,1,0,1,3,4,6,8,10,10,13,14,11,11,14,14,12,13,15,14,15,15,16,15,15,18,18,18,21,20,18,21,22,20,21,23,22,22,22,23,23,23,22,22,23,22,20,22,22,21,22,20,22,21,21,22,23,23,22,23,22,23,22,22,23,22,23,23,24,22,21,22,22,24,23,22,24,24,24,24,23,22,23,22,22,18,20,21,20,18,19,20,17,21,19,18,19,18,15,16,19,18,16,18,20,17,18,19,20,19,20,21,21,19,21,22,23,21,19,21,22,21,22,22,23,21,22,22,22,23,22,22,21,22,23,22,22,23,22,22,22,24,23,22,21,20,19,21,22,21,22,22,22,20,21,20,20,16,20,19,17,17,19,18,15,16,18,16,14,18,16,17,19,19,20,20,21,19,19,21,21,19,19,21,19,18,20,20,19,20,21,21,21,22,22,21,22,19,20,17,21,21,19,18,21,21,18,21,21,19,20,21,22,22,22,20,21,20,18,19,17,18,19,18,15,18,18,16,17,18,18,16,17,17,17,17,15,15,14,16,17,16,16,17,17,17,18,19,20,19,20,20,20,18,18,17,16,16,15,15,13,12,13,11,9,9,11,9,9,7,8,9,10,12,12,13,14,15,13,15,17,15,15,18,18,18,20,21,21,21,22,23,23,25,23,26,24,24,24,23,23,24,25,24,25,24,26,27,27,28,26,28,28,28,27,28,29,28,29,29,28,28,29,29,29,27,28,27,27,28,26,26,24,25,26,25,26,25,24,26,22,24,24,23,22,23,21,21,22,20,21,21,19,18,17,17,16,16,15,12,18,17,17,17,18,18,19,19,19,19,21,20,18,21,21,21,21,23,21,21,22,23,22,23,22,23,23,22,22,21,21,23,21,23,23,22,22,22,21,21,21,20,18,22,20,20,19,20,19,18,18,18,19,18,19,19,20,20,21,21,21,22,22,21,22,22,22,22,22,22,23,23,23,23,23,22,21,23,20,22,19,19,18,21,21,19,20,22,23,18,21,21,20,19,19,20,19,18,20,19,18,19,19,18,17,18,18,16,16,16,17,15,17,18,18,18,19,18,19,19,19,19,19,19,18,20,21,21,21,21,19,20,19,19,18,20,18,16,17,18,16,17,17,17,15,15,17,17,13,14,17,16,15,15,17,15,13,16,17,14,15,17,18,16,17,18,19,18,18,19,20,20,20,18,19,19,19,18,19,18,17,19,19,18,18,18,18,17,17,16,17,17,15,14,16,16,14,12,11,13,15,10,12,13,13,12,11,14,12,14,15,14,16,17,15,17,17,18,17,18,18,16,17,16,15,15,14,13,13,14,14,14,11,11,10,7,8,10,10,11,11,10,9,12,11,11,13,14,12,13,15,17,15,17,18,17,16,18,18,18,18,20,18,19,18,16,18,17,17,17,16,16,16,16,13,14,13,11,10,9,8,4,5,6,8,8,8,10,11,13,11,14,15,14,16,16,17,16,16,17,16,17,17,16,16,16,15,16,14,15,14,12,15,14,14,13,15,14,11,13,15,16,17,18,17,17,17,16,16,16,17,18,18,18,20,19,19,19,21,20,18,20,21,19,20,22,21,20,21,22,21,22,21,22,22,22,22,22,22,23,23,23,22,23,23,24,24,24,25,25,26,26,26,27,26,27,27,28,28,28,27,27,28,28,27,29,28,28,28,29,28,28,28,29,29,28,29,28,29,29,28,29,28,28,29,29,28,28,29,29,28,28,28,28],[30,29,29,29,30,30,29,29,29,29,29,28,29,28,28,28,28,28,28,28,28,27,28,28,28,28,28,27,27,27,26,27,28,28,27,27,27,26,27,26,27,26,26,25,26,25,23,23,23,23,21,21,21,20,18,19,18,17,16,14,11,10,8,5,3,1,0,1,3,4,5,7,8,10,9,6,7,10,9,7,10,10,10,9,10,11,11,11,12,12,14,14,14,13,14,17,15,15,17,16,16,16,17,16,18,17,17,18,18,17,18,18,16,17,16,16,17,17,16,18,17,16,18,17,18,16,17,18,17,18,17,17,17,15,16,16,17,17,16,17,17,17,18,18,15,16,16,15,13,15,15,13,12,15,14,12,15,13,13,13,13,10,12,13,12,11,13,15,13,13,14,14,13,14,15,15,14,16,16,16,15,13,16,15,15,15,16,17,14,15,16,15,16,16,16,16,17,17,16,16,16,16,17,17,18,17,16,16,15,13,16,16,14,15,15,15,13,15,14,13,12,14,13,13,12,13,12,10,12,13,11,9,12,11,13,15,14,14,14,16,13,15,16,16,15,14,16,13,13,15,14,12,14,15,15,15,16,15,15,14,14,13,13,15,15,13,12,15,15,14,14,15,14,13,14,16,15,15,14,15,14,13,14,11,11,12,12,10,12,12,12,11,11,12,12,12,11,12,11,13,11,12,12,13,13,11,13,14,12,13,15,16,15,16,15,17,16,16,14,14,12,10,10,9,8,9,10,7,7,7,6,6,4,8,6,8,12,11,13,15,15,13,13,17,15,14,18,18,16,18,21,20,20,22,24,23,26,24,27,25,24,26,25,24,26,26,26,25,26,27,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,28,27,28,25,26,27,25,26,25,24,27,24,23,25,23,22,22,23,21,21,20,19,19,17,16,15,13,12,12,10,11,12,12,12,15,16,17,17,17,18,17,18,17,18,18,18,19,18,18,18,19,19,19,18,19,20,18,16,17,17,18,17,17,19,18,19,19,19,19,18,18,17,17,17,18,17,16,16,15,14,13,14,14,15,15,16,15,17,16,16,17,19,17,16,18,18,17,17,18,17,16,17,17,19,18,17,18,17,17,16,17,16,13,14,15,16,14,13,16,16,13,14,15,13,12,13,13,12,13,13,12,12,13,12,13,11,12,13,11,11,10,11,10,13,14,14,15,14,14,14,14,12,14,14,12,13,14,13,15,15,15,13,15,14,14,14,13,13,13,12,13,13,12,12,12,12,9,12,12,8,10,11,10,8,10,12,10,10,12,12,12,12,12,12,12,13,12,14,13,12,14,16,14,13,15,13,13,14,14,13,12,13,14,13,13,12,13,12,13,14,12,12,12,10,9,11,10,8,9,7,8,9,7,7,7,7,8,7,10,9,10,11,9,11,11,11,12,13,12,13,12,12,13,12,12,12,12,12,11,10,11,11,8,7,8,5,5,5,6,5,6,6,5,7,7,7,9,9,9,10,8,12,11,9,14,14,13,13,15,12,15,13,13,13,15,15,13,13,13,12,13,13,13,11,9,9,9,11,10,7,5,4,3,3,5,7,6,5,7,8,9,9,10,10,10,11,13,14,12,13,14,12,13,14,13,13,12,12,11,10,11,10,10,11,10,9,10,10,9,8,10,10,12,14,13,15,14,14,14,12,13,14,14,15,16,18,16,16,15,16,17,15,15,17,16,14,16,17,15,15,17,16,15,15,17,16,14,15,18,16,15,16,17,16,18,18,20,19,20,21,20,23,24,24,26,24,26,25,27,26,26,25,26,27,28,27,29,27,27,28,28,27,29,28,29,28,29,29,28,28,28,28,29,28,28,28,28,28,27,28,28,27,27,27,26],[30,30,29,29,30,30,30,29,29,29,29,28,29,28,29,28,29,29,28,29,28,28,28,29,28,28,28,27,28,28,27,28,28,28,27,28,27,28,27,27,27,26,26,26,26,25,24,23,24,23,22,22,22,21,20,20,19,18,17,16,12,10,9,7,5,3,1,0,1,3,3,4,6,6,6,6,5,7,8,8,7,8,8,9,9,9,9,9,12,12,11,12,12,11,12,15,14,12,14,15,14,14,14,14,14,13,14,14,14,14,14,14,14,15,15,14,14,15,14,14,14,13,15,14,13,14,13,15,14,14,14,15,13,14,13,14,14,16,14,14,14,14,13,15,13,13,13,13,12,11,12,12,11,13,11,12,12,12,12,12,11,9,10,12,12,9,11,11,12,12,11,12,13,11,12,13,12,14,14,13,14,12,14,14,13,13,14,14,13,14,13,14,14,15,15,15,15,15,14,15,15,15,15,15,16,15,15,15,15,14,14,15,14,14,13,13,12,12,12,12,11,11,12,11,10,11,11,9,10,11,8,8,10,10,11,12,12,12,13,13,12,11,13,13,12,11,13,11,12,13,12,11,13,13,13,13,14,15,14,13,12,11,12,12,12,12,12,13,13,12,12,13,14,13,13,15,14,13,14,13,12,12,12,10,10,11,10,10,11,10,10,8,11,10,10,9,10,10,10,9,7,8,10,9,9,10,11,11,12,12,13,13,14,14,14,14,14,13,14,12,11,11,8,7,7,7,7,6,6,6,6,6,6,7,7,7,9,10,12,12,15,13,12,17,16,14,17,19,17,18,20,21,21,22,23,23,24,23,26,24,24,25,22,22,25,26,26,25,26,27,27,27,28,28,28,28,29,28,29,29,29,29,29,29,28,29,28,29,27,28,27,28,28,27,27,25,26,26,25,26,25,24,25,23,22,23,23,21,21,22,21,21,19,19,18,16,16,14,13,11,11,8,8,9,11,10,12,12,13,15,14,15,15,16,15,14,16,17,15,17,18,17,16,17,18,17,17,18,16,17,16,16,17,17,17,17,16,18,18,17,16,15,17,15,15,12,16,14,13,13,14,13,12,13,12,14,14,14,13,15,15,13,16,16,15,15,17,17,15,16,16,16,16,16,16,18,16,16,17,15,16,15,15,13,12,12,13,14,12,13,14,14,13,12,14,12,13,12,12,12,12,13,12,10,11,10,11,10,10,11,8,8,7,9,9,11,11,12,13,13,12,14,13,12,12,13,12,11,14,13,13,14,14,13,14,12,12,13,11,12,11,9,10,10,8,9,9,10,9,9,8,9,10,8,9,8,7,8,9,9,9,9,9,9,10,10,9,10,11,12,12,12,13,15,12,13,13,13,12,13,13,12,11,11,13,11,12,10,11,11,10,9,10,8,8,8,9,8,7,7,6,3,6,8,4,5,7,6,7,7,7,8,9,9,7,10,9,9,10,10,11,11,10,10,11,10,11,11,11,10,9,8,8,9,8,7,7,6,3,3,7,4,6,7,4,5,8,6,6,8,7,8,7,11,9,9,9,11,11,11,13,13,13,12,12,12,12,12,12,11,10,10,10,8,8,7,7,6,7,9,6,4,4,4,3,3,5,6,5,6,6,7,7,7,8,7,8,9,11,11,10,10,11,10,11,10,10,11,9,8,9,7,8,7,8,9,7,8,9,7,6,8,8,9,10,12,12,11,11,11,11,11,10,12,12,12,13,15,14,14,14,15,15,13,14,15,15,14,15,15,13,13,15,14,15,15,16,15,14,15,16,15,14,15,16,15,17,17,20,19,20,18,20,20,22,23,25,23,25,25,26,25,25,26,25,27,26,27,27,27,28,28,28,27,28,28,28,28,28,28,27,28,28,27,27,28,29,27,29,28,27,28,28,27,26,27,27],[29,28,29,29,29,29,29,29,29,28,27,28,28,27,28,27,28,28,27,28,27,27,28,28,27,27,28,27,27,27,26,27,27,28,26,27,26,27,27,26,27,25,26,26,26,25,24,22,23,23,21,21,22,20,19,20,19,18,16,16,14,11,9,7,6,3,3,1,0,1,2,4,4,5,5,5,5,8,8,8,7,8,8,7,8,10,10,10,12,12,12,13,13,12,14,14,12,13,16,14,14,15,16,15,14,15,15,15,15,15,15,15,14,14,12,15,14,15,13,16,14,14,14,16,14,12,15,16,13,13,15,15,12,13,14,14,15,14,15,15,15,13,16,15,14,13,13,13,11,13,13,12,11,12,12,11,14,13,10,11,10,9,9,12,10,9,11,12,11,9,12,13,10,11,12,12,12,13,13,12,12,10,11,13,12,12,13,14,12,12,14,13,14,14,14,14,14,14,15,14,15,14,15,15,15,15,14,13,13,12,14,14,13,13,13,13,13,12,12,11,11,12,11,12,10,11,10,8,9,10,8,7,9,8,9,10,10,12,11,12,11,10,11,11,11,11,11,11,10,11,12,11,12,11,12,12,13,13,13,11,11,11,11,12,12,12,12,12,13,12,12,12,13,13,12,13,13,13,12,13,12,11,12,10,10,11,11,10,11,11,10,8,10,9,8,9,10,10,10,8,6,7,9,9,8,9,11,10,10,10,12,13,12,12,11,13,12,12,11,11,10,9,8,8,7,7,8,7,5,6,8,6,8,9,9,10,9,11,11,15,14,13,15,16,16,16,17,18,17,18,20,19,21,21,22,23,25,22,25,23,24,25,23,21,25,24,25,24,25,26,27,26,28,26,28,28,28,28,28,28,28,29,29,29,28,29,29,28,27,27,27,28,28,26,27,24,25,25,24,25,24,23,25,22,23,24,22,19,21,20,19,20,18,17,17,14,15,14,13,11,11,10,8,12,11,11,12,12,13,14,14,14,14,15,15,14,16,16,16,15,17,16,15,16,16,17,16,16,16,15,16,16,15,16,15,16,18,17,16,17,16,14,16,15,15,13,15,14,14,13,12,13,12,12,12,12,13,13,13,14,13,14,14,15,15,14,16,16,16,15,15,15,14,15,15,15,15,15,14,14,13,13,13,11,12,12,11,12,12,13,13,13,12,13,12,12,12,11,11,12,12,12,12,11,12,10,12,10,11,12,10,10,9,9,9,11,13,12,13,12,12,12,12,11,12,13,12,12,14,13,13,14,14,13,14,13,12,12,13,12,10,11,12,10,10,10,11,9,8,10,9,9,8,9,8,6,9,9,9,8,9,9,8,9,11,10,10,10,11,11,11,11,11,14,13,12,13,12,12,14,12,12,12,12,13,11,13,10,11,11,10,11,10,9,9,10,9,7,8,7,7,6,6,8,7,6,8,7,8,7,9,8,10,10,8,10,9,8,10,11,10,10,11,11,10,11,11,10,10,10,9,8,9,9,11,8,8,7,5,5,5,4,5,6,6,5,6,7,6,5,7,8,8,9,10,10,11,12,11,11,14,12,12,12,13,12,12,13,11,11,11,11,9,9,9,7,10,9,9,7,8,7,6,6,4,4,6,5,6,7,8,8,8,9,10,10,11,11,12,11,10,11,12,11,12,12,12,11,10,10,9,9,10,9,10,10,9,8,11,10,8,8,10,11,11,13,12,12,12,12,11,11,12,12,12,13,12,15,12,13,12,15,15,13,14,15,14,14,14,15,13,14,15,14,13,13,15,14,13,14,15,14,14,14,15,15,16,17,18,18,19,18,19,21,22,23,24,24,24,24,25,24,25,24,24,27,25,26,27,25,27,27,28,26,27,26,27,28,27,29,27,28,28,27,27,27,27,27,28,27,27,27,27,26,25,27,26],[29,29,29,29,29,30,29,29,29,28,28,27,28,27,27,27,28,28,27,28,28,26,27,28,27,27,28,27,27,27,27,27,28,28,27,28,27,27,28,27,27,26,26,26,26,25,24,23,23,23,22,22,22,21,20,21,20,19,19,19,16,13,11,8,7,5,3,4,1,0,1,2,2,3,4,2,3,5,5,4,4,5,5,4,5,5,6,6,7,7,7,8,8,8,8,8,9,9,9,9,9,9,9,9,9,10,9,10,10,10,11,10,10,9,9,10,10,10,9,10,10,8,9,10,9,9,8,10,9,9,9,9,9,9,9,10,9,10,9,9,8,9,8,8,8,8,8,8,8,8,8,8,8,8,7,8,8,8,8,9,8,6,8,8,7,6,7,7,7,7,7,7,8,7,7,8,8,8,8,8,8,7,7,8,9,8,8,8,8,8,9,8,8,9,9,10,10,10,9,10,10,11,10,10,10,10,10,9,9,9,8,8,9,8,7,7,7,7,6,7,7,7,7,6,6,7,5,5,6,6,4,5,5,7,8,8,7,8,8,7,7,7,7,7,7,6,7,7,6,6,6,6,7,7,8,8,9,9,9,8,7,7,6,7,6,6,6,7,8,7,7,7,8,8,8,8,9,8,8,7,8,7,7,6,6,7,6,5,6,5,6,5,5,5,5,5,6,5,5,4,4,4,4,4,4,5,5,6,6,6,7,7,8,7,8,8,8,8,8,7,8,7,5,5,5,5,5,4,4,5,5,5,6,7,9,9,10,12,12,14,16,15,15,17,18,16,16,18,18,16,18,19,20,20,22,23,24,23,24,22,23,24,22,21,24,25,25,23,25,26,27,27,28,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,27,27,25,27,27,25,26,24,25,26,23,23,23,22,22,21,21,20,20,19,19,17,15,15,14,11,10,9,7,7,6,8,8,8,9,9,10,9,10,10,11,11,10,12,11,11,12,13,13,13,13,13,12,13,13,12,12,12,12,12,12,12,13,12,14,13,12,13,12,12,11,10,10,10,10,9,9,9,8,8,8,8,8,8,7,8,8,8,8,8,10,9,8,9,10,9,10,10,11,11,11,11,11,11,11,10,9,8,8,8,6,7,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,6,6,6,6,5,6,7,6,5,6,6,7,8,9,9,9,9,8,8,7,7,7,8,7,7,8,8,8,8,9,9,8,8,7,8,7,7,7,6,6,6,6,5,6,5,6,5,5,6,6,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,6,6,6,7,6,8,7,7,6,7,6,6,6,7,6,6,6,6,7,6,6,6,6,6,6,5,5,6,6,5,5,5,6,4,5,6,4,4,5,5,5,5,5,6,6,6,5,6,6,6,7,7,7,7,7,7,8,7,7,8,7,8,7,6,7,7,7,7,6,6,3,3,5,2,4,5,2,2,5,4,2,6,5,4,4,7,5,6,5,6,6,7,8,7,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,5,8,6,7,4,5,5,5,2,3,3,3,4,4,4,6,6,6,6,7,7,6,7,8,7,7,7,7,8,7,8,7,7,7,7,7,7,7,7,6,6,7,7,6,5,6,6,7,8,8,8,8,8,8,8,8,9,9,8,10,9,9,9,10,9,9,8,9,9,9,8,8,8,8,7,8,7,9,8,9,8,8,9,9,8,8,10,11,11,13,13,14,15,15,15,16,17,18,19,21,20,23,24,23,21,23,23,22,25,23,24,26,23,27,26,27,26,27,26,27,27,27,27,26,27,28,25,25,27,27,26,27,26,25,26,27,25,23,26,25],[28,28,28,28,28,28,28,28,28,27,26,26,27,26,26,26,27,27,26,27,26,26,27,27,26,26,27,26,27,27,26,26,27,27,26,26,26,27,27,26,27,25,25,25,26,25,24,23,23,23,21,21,21,21,19,20,19,18,17,17,15,13,11,7,7,5,4,3,2,1,0,1,2,2,3,4,4,5,5,5,4,5,5,5,6,7,7,7,7,8,8,8,9,8,9,9,9,9,10,9,11,10,11,10,11,10,10,11,10,11,11,10,9,10,8,10,10,11,10,10,11,10,10,10,10,10,9,11,10,9,10,10,9,9,10,11,10,11,10,10,10,9,10,9,9,9,9,9,9,9,9,8,7,7,8,8,8,8,8,7,7,7,6,7,7,6,7,8,7,6,7,8,7,6,8,9,7,8,8,8,8,7,7,8,9,8,8,9,9,8,9,9,8,9,9,10,11,9,9,10,11,9,10,10,11,10,10,9,9,10,9,9,9,9,8,8,8,8,8,7,7,8,7,7,7,6,6,6,6,5,4,5,5,6,7,7,7,7,7,8,7,6,7,7,6,6,7,6,6,7,7,6,6,6,7,8,9,9,8,7,6,7,5,7,7,7,6,7,8,7,7,7,9,9,8,8,8,8,8,8,8,8,7,7,6,7,6,5,6,5,5,5,5,5,5,5,5,5,4,4,3,3,4,4,5,5,5,5,6,7,6,7,7,7,7,8,7,8,8,7,8,7,6,5,4,4,5,4,4,5,6,5,5,7,9,9,12,14,14,16,16,15,17,17,17,17,18,18,18,19,20,20,21,22,23,23,24,23,25,23,24,24,22,21,23,23,25,23,24,26,26,25,27,25,26,27,27,27,28,28,28,28,28,28,27,28,28,28,27,27,27,28,28,27,27,25,26,26,24,26,24,23,25,22,23,23,22,20,21,20,18,19,17,17,16,15,14,13,11,10,9,7,6,7,8,7,8,8,8,9,9,10,10,10,10,10,11,11,11,11,13,13,11,12,14,13,13,13,13,12,12,11,11,12,13,13,13,12,13,13,13,11,11,11,12,10,10,10,10,9,9,9,8,8,7,7,7,7,7,8,8,9,8,9,9,9,9,9,9,9,10,11,10,11,11,11,11,10,9,8,8,7,7,6,6,6,6,6,6,7,6,7,7,7,7,7,7,6,7,7,6,6,7,6,6,6,7,5,7,6,6,6,5,7,7,8,9,9,10,9,8,8,7,7,9,8,8,8,9,9,9,9,9,9,10,9,8,9,9,8,7,7,8,7,6,6,7,6,5,6,5,5,5,5,4,4,4,4,3,3,4,5,4,4,5,5,4,4,5,6,6,6,6,7,7,7,6,7,7,6,6,6,6,6,7,6,7,6,6,6,6,6,6,6,6,6,6,5,6,6,5,4,5,5,4,4,4,4,5,5,6,5,6,6,6,7,7,6,7,7,7,7,8,8,7,8,8,7,7,8,7,7,7,7,7,6,5,4,4,3,3,3,3,3,3,3,3,3,3,2,4,4,4,4,5,5,5,6,6,6,7,8,7,7,7,7,8,8,7,8,8,8,7,7,7,6,7,6,6,6,6,6,5,4,4,3,4,3,3,4,5,5,5,6,6,6,7,7,7,8,7,8,8,9,9,9,9,9,8,8,8,7,8,7,7,8,7,7,7,7,6,5,6,7,7,8,8,8,8,9,8,8,9,9,9,9,9,10,9,9,9,11,9,9,8,9,9,8,8,8,8,8,8,8,8,8,9,9,8,8,8,8,8,8,10,10,12,13,14,14,14,14,15,17,18,18,19,20,21,21,23,20,22,21,21,24,22,23,25,23,25,25,24,24,25,23,26,26,26,26,25,25,26,24,25,25,24,24,25,24,24,25,25,24,22,23,25],[29,29,29,29,29,29,29,28,28,28,28,27,27,27,27,27,27,28,27,27,27,27,26,27,27,27,27,27,27,27,27,27,28,28,27,27,27,27,28,27,27,26,26,26,26,25,24,24,24,25,23,22,23,22,21,21,21,19,20,20,17,13,11,7,7,5,3,3,2,2,1,0,1,1,1,2,2,3,4,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,8,8,7,6,6,6,7,6,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,6,6,6,5,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,5,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,7,6,7,7,7,6,7,7,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,5,4,4,4,4,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,5,5,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,2,2,3,2,3,3,4,3,3,4,4,4,5,5,5,5,5,5,5,5,5,4,4,3,3,3,3,3,3,4,4,4,4,6,7,8,9,13,13,16,17,16,16,17,18,18,18,19,19,18,19,20,21,22,23,24,25,24,25,23,24,24,22,21,24,25,25,24,25,25,26,26,26,26,27,27,28,28,28,27,28,27,28,28,27,27,27,27,27,27,27,28,28,27,27,26,27,27,26,27,26,26,26,24,24,24,23,22,21,20,19,19,18,17,17,15,14,13,11,8,7,5,4,4,5,5,5,5,5,6,6,6,6,7,7,8,8,8,8,9,10,9,9,10,10,10,10,10,10,9,9,9,9,9,9,10,10,11,10,10,10,9,9,8,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,7,7,8,8,9,9,8,7,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,5,5,6,7,7,8,7,6,5,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,5,5,6,6,5,6,6,6,6,6,6,6,6,5,6,6,5,6,5,4,4,3,3,2,2,2,2,1,2,2,2,2,3,3,2,3,3,3,3,4,4,4,4,4,5,5,5,4,5,5,4,5,5,5,4,4,4,4,4,4,4,4,5,3,4,4,3,3,2,2,2,3,3,2,4,4,3,4,5,4,4,4,5,5,5,5,5,6,6,6,5,5,5,5,5,5,4,5,4,4,5,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,7,8,9,10,11,12,13,12,13,15,15,17,18,19,22,22,21,19,20,21,21,24,21,23,24,22,26,26,26,24,25,25,26,26,25,26,25,25,25,23,24,26,26,24,26,24,24,25,26,23,22,24,24],[28,28,28,27,28,28,28,28,27,27,26,26,27,26,26,25,26,27,26,26,27,26,27,26,26,26,26,26,26,26,26,26,26,26,25,25,25,26,26,26,26,24,24,25,25,24,23,23,22,23,22,21,21,20,19,19,19,18,18,18,16,13,11,9,6,5,4,3,3,2,1,1,0,1,1,2,2,3,3,3,3,4,4,4,3,5,4,5,5,6,6,5,6,5,6,6,6,7,7,7,7,7,7,7,8,7,8,8,8,8,8,8,7,7,6,7,7,6,7,7,6,6,6,6,7,6,6,7,7,6,6,7,6,6,7,8,7,7,6,6,6,6,6,6,5,6,6,6,5,6,5,5,5,5,5,6,6,6,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,6,5,5,5,6,5,5,6,7,7,7,6,7,7,7,7,8,8,8,7,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,4,4,5,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,5,5,6,5,5,5,4,4,3,4,4,4,4,5,5,4,4,5,6,6,5,6,5,6,5,5,5,5,4,4,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,2,2,3,3,3,3,4,4,4,4,5,5,5,6,5,6,6,6,6,6,5,6,5,4,4,4,4,4,4,4,4,4,5,5,6,8,10,13,13,14,15,15,16,16,17,17,17,16,18,19,19,20,21,21,21,22,23,24,22,24,23,22,23,21,20,23,23,23,22,23,24,25,25,26,25,25,26,26,26,26,26,25,26,25,26,25,26,26,26,26,26,27,26,27,26,26,25,25,25,24,25,24,23,24,22,23,23,22,21,20,19,18,19,17,16,16,14,13,11,9,8,8,6,5,5,6,6,6,7,7,8,7,8,8,8,8,9,9,9,9,9,11,10,10,11,12,11,11,11,11,10,9,9,10,9,9,10,10,11,10,11,10,9,9,8,8,8,8,8,7,7,7,6,6,7,6,6,6,6,6,6,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,7,7,6,6,5,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,4,4,5,5,5,4,4,4,5,4,5,5,4,5,5,5,6,6,8,8,8,7,6,6,5,5,6,6,5,5,6,6,6,6,7,7,7,7,6,7,6,5,6,6,6,5,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,2,3,4,3,3,4,5,4,4,5,5,6,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,4,5,4,5,4,4,4,4,5,3,4,4,4,4,4,5,4,5,5,4,4,5,4,5,5,5,5,5,6,6,6,7,6,6,7,6,6,6,6,6,6,5,5,4,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,4,4,4,5,5,5,6,6,6,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,3,2,3,2,3,3,3,4,5,5,5,4,5,5,6,6,6,6,6,7,6,7,6,7,6,6,6,6,6,5,5,6,5,5,5,5,5,4,5,5,5,6,6,7,7,6,6,6,7,7,7,7,7,7,8,7,7,8,7,7,7,7,7,6,6,6,6,6,6,7,6,5,6,6,5,6,6,5,6,6,7,8,10,9,12,11,13,12,12,14,15,17,18,18,21,21,20,19,20,21,20,23,20,23,23,23,24,26,24,24,25,24,24,25,25,24,24,24,26,23,23,25,25,24,25,23,23,24,25,25,21,24,24],[28,29,28,28,29,29,29,28,28,28,28,27,28,27,28,26,27,27,26,28,27,26,27,27,26,27,27,27,27,27,26,27,27,27,26,27,26,27,27,27,27,26,26,26,26,26,24,24,24,23,23,23,22,21,20,20,19,18,18,18,16,13,11,8,7,6,4,4,3,2,2,1,1,0,1,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,4,4,4,3,4,5,4,5,5,5,5,5,6,6,6,7,7,7,7,8,8,7,6,5,5,6,6,6,6,6,6,5,5,6,6,5,5,5,5,5,5,6,5,6,6,6,6,6,5,6,5,4,5,5,4,4,5,4,3,4,4,3,3,4,4,4,5,5,4,5,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,6,6,5,6,6,6,6,6,6,6,6,5,5,4,5,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,2,3,3,2,3,3,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,4,5,5,5,4,4,3,4,3,3,3,3,4,3,3,4,4,4,4,5,5,5,4,4,4,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,2,2,1,2,2,2,2,3,3,3,3,4,5,5,5,4,5,5,5,5,5,5,5,4,4,3,3,3,4,3,3,4,4,5,5,6,8,10,11,12,15,16,18,18,17,19,20,18,19,21,22,21,23,23,23,24,24,24,26,24,26,24,23,25,23,24,25,24,25,24,25,25,27,27,27,27,27,28,28,28,27,28,27,27,27,27,27,27,27,27,27,27,27,27,28,27,27,27,27,27,26,27,26,25,27,24,25,25,24,23,23,20,20,20,17,16,15,13,12,11,9,8,7,5,4,5,5,5,5,5,6,6,6,7,7,7,7,8,9,8,9,9,10,10,10,10,11,11,10,10,10,10,9,9,9,9,9,10,10,11,10,10,10,9,9,9,8,7,7,7,6,6,6,5,5,5,5,5,4,4,4,5,5,5,5,6,5,5,5,6,6,6,7,7,8,8,8,9,8,7,6,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,3,4,4,4,4,3,4,4,3,4,4,4,4,4,5,5,6,7,7,7,7,6,4,4,4,4,4,4,4,4,5,5,5,6,6,6,6,5,6,5,5,5,4,4,4,4,3,4,4,3,3,3,3,2,3,3,2,2,2,3,2,2,3,2,2,3,3,2,2,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,4,4,4,3,3,3,3,4,3,3,3,3,3,4,4,4,5,5,5,6,6,5,6,6,6,6,5,6,6,6,5,5,4,4,3,3,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,3,3,2,3,3,3,3,4,4,4,4,5,4,5,5,5,5,6,6,6,6,6,6,5,6,6,6,6,5,5,5,5,4,4,5,4,4,4,4,5,5,6,6,6,6,5,6,6,7,7,6,7,7,6,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,7,7,9,9,11,12,12,14,13,16,16,17,18,19,22,22,21,19,20,22,21,23,22,23,24,23,25,25,24,24,24,25,25,25,25,26,24,25,25,22,24,25,25,25,25,24,23,25,26,24,24,25,24],[28,28,28,28,29,29,28,28,28,28,27,27,28,26,27,26,27,27,26,27,27,26,27,27,26,27,27,26,27,26,26,27,27,26,26,27,26,26,26,26,26,26,25,25,25,25,23,23,23,23,22,20,21,20,19,19,20,18,18,18,15,13,12,10,9,7,5,4,4,3,3,2,1,1,0,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,7,6,6,5,6,6,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,6,6,7,6,5,6,5,5,5,5,4,5,4,4,4,4,4,4,5,5,4,4,4,3,3,4,4,3,4,4,4,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,4,5,6,5,5,6,6,6,5,6,6,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,5,5,4,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,5,5,6,6,5,5,4,4,4,4,4,4,5,4,5,5,5,5,6,5,5,6,5,5,5,5,5,5,4,4,3,4,4,3,3,3,2,2,3,2,2,3,3,3,2,2,2,3,2,2,3,3,3,3,4,4,4,4,5,5,5,5,5,6,5,5,6,5,4,4,4,5,5,4,5,5,5,7,6,7,10,11,12,12,15,16,17,18,16,17,19,17,18,20,21,20,21,22,22,22,23,24,24,23,24,22,22,23,22,22,23,23,24,22,24,24,25,25,27,26,26,26,26,26,27,27,27,26,26,26,26,26,27,27,26,26,26,26,26,26,26,25,26,26,24,26,24,24,25,22,23,23,23,22,21,20,20,19,18,17,17,14,13,13,10,8,7,7,6,6,6,6,5,6,6,7,7,8,8,9,8,9,10,9,10,10,11,11,11,12,12,11,11,11,11,10,9,10,9,10,10,11,11,12,11,12,10,10,9,9,9,9,9,8,8,7,7,6,6,6,6,5,5,4,5,5,5,5,5,6,6,6,6,6,6,7,8,8,8,9,9,9,8,8,7,6,6,5,5,4,3,3,4,4,3,4,4,4,4,5,5,5,5,5,5,4,5,5,5,4,4,4,5,4,5,5,5,4,5,5,6,6,8,8,8,8,6,6,5,4,5,5,4,4,6,6,6,6,7,6,7,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,4,3,3,3,3,2,2,3,3,2,3,3,3,2,3,3,3,3,4,4,3,4,5,5,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,5,4,5,5,4,4,4,4,3,3,3,3,3,3,4,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,5,6,6,5,5,5,5,4,4,3,2,2,3,3,2,3,3,3,3,3,4,3,4,4,4,3,5,5,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,3,3,4,4,4,3,5,5,4,5,6,5,5,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,6,6,7,7,7,6,7,7,7,7,7,7,8,8,7,8,7,8,7,7,7,7,7,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,6,6,7,9,10,10,11,13,13,13,13,15,16,17,18,19,21,21,20,19,20,21,20,22,20,23,23,23,25,26,25,25,25,24,26,25,25,25,25,25,27,23,24,25,25,24,25,23,22,24,26,24,22,25,24],[28,28,28,28,28,29,28,28,28,28,28,27,28,27,27,27,27,28,27,28,28,27,27,27,26,28,28,27,28,27,27,28,28,28,28,28,28,28,28,28,28,27,26,26,27,26,24,25,25,24,23,23,23,20,20,21,20,19,19,20,17,14,11,10,7,6,5,5,4,3,3,2,2,1,1,0,1,1,2,2,2,2,2,4,3,3,4,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,6,5,5,5,6,6,6,6,6,7,5,6,6,6,5,6,6,6,6,6,7,6,6,7,7,6,7,6,7,6,6,6,6,5,5,5,5,5,4,4,4,3,4,4,4,5,5,4,4,4,4,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,5,6,5,5,6,6,5,6,6,7,7,7,7,7,7,8,7,7,7,7,7,6,6,6,6,6,5,5,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,4,4,5,5,4,5,5,5,4,5,5,5,4,5,5,5,4,5,5,4,5,5,5,6,6,6,6,5,4,4,4,4,5,4,5,4,5,4,5,5,5,5,5,6,5,6,6,5,5,5,4,4,3,4,4,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,7,7,7,6,5,6,6,5,5,4,5,5,4,5,5,6,6,7,7,9,9,12,14,14,16,17,18,18,18,19,18,19,20,20,20,22,23,23,23,24,25,26,25,26,24,23,25,24,22,25,24,25,24,25,24,26,25,26,26,26,26,27,26,27,27,26,26,26,26,26,26,27,26,26,26,27,27,27,27,27,26,27,27,26,26,26,26,27,24,25,26,23,21,22,19,19,20,17,17,16,14,13,11,10,9,8,6,6,5,7,7,6,7,7,8,8,8,9,8,8,9,10,9,9,10,11,10,11,11,11,12,11,10,11,9,9,9,10,10,10,11,12,12,11,12,11,10,10,9,9,9,9,9,8,8,8,8,7,7,6,7,5,5,5,6,7,6,6,7,7,7,7,7,7,8,8,9,8,9,9,10,9,8,7,7,6,6,5,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,4,4,5,5,4,4,4,4,5,4,4,5,4,4,5,5,5,6,7,7,8,8,6,6,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,4,5,4,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,4,5,5,4,4,5,4,4,5,5,5,5,5,4,5,5,4,5,5,4,5,5,5,5,4,5,5,4,4,4,4,4,4,3,4,3,4,4,3,3,3,3,4,4,4,4,5,5,5,6,5,6,6,7,5,5,6,6,7,6,6,5,4,4,3,2,3,3,3,2,3,4,3,3,3,4,3,3,4,4,4,4,5,5,7,6,6,6,5,6,6,5,5,6,6,6,5,5,6,5,5,5,5,5,5,4,5,4,5,4,4,3,3,5,5,4,4,5,4,5,5,5,5,6,6,7,6,7,7,8,7,7,7,7,6,7,7,6,6,7,7,5,5,7,6,5,5,6,6,7,8,8,8,7,7,7,7,7,8,7,7,8,7,8,7,8,7,7,7,7,7,6,6,7,6,6,7,7,6,6,6,6,5,6,6,6,6,6,8,9,10,10,12,13,13,13,13,15,16,18,18,19,21,22,22,19,21,22,21,24,21,23,23,23,25,25,24,25,26,25,25,26,26,26,25,26,26,23,23,25,26,23,26,23,23,24,26,24,21,25,25],[27,27,27,28,27,28,28,28,28,27,26,26,26,26,26,25,26,26,26,26,27,26,26,27,26,26,26,26,27,26,26,26,27,26,26,26,26,26,27,26,26,25,25,25,25,25,23,22,23,22,22,21,22,21,19,20,19,17,18,16,16,14,11,9,7,6,5,4,4,3,3,2,2,2,2,1,0,1,1,1,2,1,2,3,2,3,3,4,4,4,4,4,4,3,4,5,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,5,5,4,4,5,5,5,4,6,5,4,5,5,5,4,5,6,5,5,5,6,5,6,6,7,6,6,5,6,5,5,5,5,4,4,5,4,3,4,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,2,3,3,2,3,4,3,3,4,4,4,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,7,7,7,7,7,7,7,8,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,4,4,5,5,4,5,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,5,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,5,5,5,5,4,4,3,4,4,3,3,3,3,3,4,4,4,4,4,5,4,3,3,3,4,5,5,5,5,5,5,5,6,6,7,7,7,7,7,7,7,6,7,6,5,5,4,5,5,4,4,5,5,6,6,7,9,10,12,13,13,15,15,16,16,17,17,17,17,18,19,20,21,22,21,21,24,24,24,24,25,24,22,23,23,23,23,23,24,23,23,23,25,25,26,24,25,25,25,26,26,25,25,25,25,25,26,25,26,25,26,26,26,26,26,25,25,25,25,25,24,26,24,24,25,22,23,24,23,22,21,19,19,19,18,16,17,14,12,11,10,9,7,6,5,6,7,7,7,8,7,8,7,8,9,9,8,9,10,9,9,10,11,10,11,12,12,12,13,11,11,10,10,10,10,10,11,11,12,12,11,12,12,10,10,10,10,9,9,9,9,8,8,8,7,7,7,7,6,7,6,7,7,8,7,7,8,8,8,8,8,8,8,9,9,9,10,9,9,9,8,7,7,7,6,5,5,5,6,6,5,6,6,6,5,6,6,5,6,5,5,5,5,5,5,4,4,4,5,4,5,5,4,4,5,5,6,6,7,7,7,7,6,5,5,5,5,6,4,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,4,3,3,4,4,4,3,4,5,4,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,3,4,3,2,2,3,4,4,4,4,5,4,5,6,6,6,6,6,5,5,6,6,7,5,6,4,4,3,3,2,3,3,3,2,3,3,3,3,4,4,4,4,4,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,4,5,5,4,4,4,4,4,3,4,3,3,4,4,4,4,5,5,5,6,6,7,6,6,7,6,7,7,8,7,7,7,7,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,8,7,7,7,7,7,7,8,8,8,8,8,8,8,8,7,9,8,7,7,8,7,7,7,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,8,9,10,10,12,13,12,12,14,15,16,17,18,19,21,22,22,19,21,21,20,23,22,22,23,23,23,24,24,24,24,25,25,24,25,26,24,24,26,24,24,24,24,24,25,23,23,25,24,24,22,23,23],[28,29,29,29,29,29,29,28,28,28,28,27,28,27,27,27,27,28,27,27,27,27,27,27,26,28,27,27,28,27,27,27,28,28,27,28,27,28,27,27,27,27,26,26,26,26,24,23,25,24,22,22,23,22,19,22,20,19,18,18,16,14,12,9,8,6,5,4,4,3,2,3,2,2,2,1,1,0,1,1,1,1,1,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,3,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,5,5,4,5,5,4,4,5,4,4,5,5,5,5,5,4,5,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,3,3,4,4,3,3,2,3,3,2,1,3,3,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,5,6,6,6,5,6,6,5,6,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,3,3,4,4,3,4,4,5,4,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,6,5,5,5,5,4,4,5,5,4,4,5,5,4,5,4,4,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,3,4,3,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,5,6,5,5,5,4,5,5,4,4,5,6,6,6,9,10,12,12,12,14,15,18,18,18,20,19,18,20,23,22,22,23,25,24,24,24,25,25,25,26,23,24,25,23,22,25,23,26,24,24,25,27,26,27,26,26,27,27,27,28,27,27,26,27,27,27,27,27,28,27,27,27,27,28,27,27,26,27,26,26,28,27,26,27,25,25,25,23,24,23,19,20,19,18,17,16,14,13,12,10,8,8,7,6,6,7,7,6,7,7,8,8,9,9,10,9,10,10,9,10,10,12,10,11,12,12,12,12,11,12,10,10,10,10,10,11,11,12,13,12,12,11,10,10,9,9,9,10,9,9,9,8,7,7,7,6,6,6,5,6,6,6,6,6,7,6,7,7,8,8,8,8,9,9,9,9,9,8,8,7,7,6,6,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,5,5,6,6,7,7,6,5,5,4,4,4,4,3,3,4,4,4,4,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,2,2,2,1,2,2,3,3,3,4,4,4,5,5,5,5,6,5,4,5,5,6,6,5,5,4,3,3,2,2,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,6,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,7,7,7,7,7,7,8,7,7,7,6,6,6,6,6,6,5,6,6,5,5,5,6,6,7,7,7,7,7,8,7,7,7,7,7,8,8,7,7,7,8,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,8,10,10,12,13,13,12,14,16,17,19,20,19,23,22,23,21,22,21,21,24,23,23,25,24,25,26,27,25,26,26,27,25,26,28,25,25,27,24,26,26,26,26,26,26,24,26,26,25,24,25,25],[28,28,28,28,28,29,28,28,29,27,27,27,27,27,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,27,28,27,27,27,27,27,26,26,26,26,26,24,23,23,22,22,22,21,21,20,20,20,19,18,18,16,13,11,9,8,5,5,4,4,3,3,3,2,3,2,1,1,1,0,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,4,5,5,5,5,6,6,5,4,4,4,4,4,4,4,5,4,4,4,5,4,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,3,4,4,3,3,3,3,2,3,3,3,4,4,3,3,3,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,5,5,5,4,4,3,4,4,3,3,4,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,3,2,3,3,4,4,3,3,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,4,4,4,4,4,3,3,3,2,2,3,3,2,3,3,2,3,3,3,3,3,3,4,3,3,3,3,3,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,5,6,6,6,5,5,5,5,5,5,5,5,6,6,6,8,9,12,12,12,14,16,16,16,17,17,17,17,18,19,19,20,22,22,22,22,23,24,25,24,25,24,22,23,22,22,24,23,24,24,23,24,25,24,26,25,26,26,26,26,26,26,25,26,25,26,26,26,26,26,26,25,26,26,26,26,26,25,25,26,25,26,25,25,26,23,24,25,24,22,22,20,20,20,18,17,16,14,13,12,10,8,8,7,6,6,6,7,6,7,7,7,8,8,8,8,8,9,10,9,9,10,10,9,10,12,12,12,11,10,11,10,9,9,9,10,10,11,11,12,11,12,11,11,10,9,9,9,9,8,8,8,7,7,7,6,7,6,6,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,9,8,8,8,8,6,6,6,5,5,4,4,4,4,4,4,4,5,5,4,5,5,4,4,5,4,4,4,4,4,3,4,3,3,3,4,3,3,3,4,4,4,5,6,6,6,6,5,4,4,3,3,4,3,3,3,4,4,4,4,4,5,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,4,4,3,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,5,4,5,5,5,4,4,5,5,5,5,5,4,4,3,3,2,2,2,3,3,3,3,4,3,3,4,4,4,5,5,5,5,5,5,6,5,6,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,6,7,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,5,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,7,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,8,10,9,11,12,12,12,13,14,16,16,18,18,20,20,21,19,20,20,19,22,21,21,23,22,24,25,25,22,24,23,24,24,24,25,24,24,25,24,24,24,24,24,25,24,23,24,24,25,23,24,25],[28,28,28,29,28,29,29,28,29,28,28,28,28,27,27,27,27,28,27,27,28,27,27,28,27,27,28,28,28,27,27,28,28,28,28,28,27,28,28,28,27,27,26,26,26,25,24,23,23,23,23,21,22,21,20,21,20,19,20,19,17,14,12,9,8,6,5,4,4,3,3,2,2,2,2,2,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,4,4,3,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,3,3,3,4,3,3,4,4,3,3,4,4,3,4,4,5,5,5,4,5,5,5,5,5,5,5,5,4,4,3,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,3,3,4,4,4,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,5,6,6,6,5,6,5,5,4,4,4,4,4,5,5,5,5,5,7,9,11,12,14,14,16,17,17,18,18,19,19,18,20,20,20,21,22,22,22,23,24,25,24,25,24,23,25,23,22,24,24,25,23,24,24,25,25,26,25,26,26,26,27,27,26,26,26,26,27,26,27,26,26,26,26,27,26,27,27,27,27,26,27,26,27,25,26,27,25,25,25,24,23,23,20,20,21,19,17,17,15,14,12,10,9,8,6,6,5,6,6,6,6,6,7,7,7,8,8,8,9,9,8,8,9,10,10,10,10,11,11,11,10,10,9,9,9,9,9,10,10,11,11,10,11,10,10,9,9,8,8,8,8,7,7,7,7,6,6,6,5,6,5,5,5,6,5,6,6,6,6,6,6,6,7,7,8,8,8,8,8,8,7,6,6,5,5,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,6,6,6,4,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,5,4,4,4,5,5,5,5,4,3,3,2,2,2,2,2,2,2,3,3,3,3,4,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,6,6,6,6,6,6,5,6,6,5,6,6,5,5,5,5,5,6,6,7,7,6,6,7,7,7,7,7,7,7,7,7,6,7,7,6,6,6,6,5,6,6,5,5,6,5,5,5,5,6,5,5,5,5,5,5,7,8,10,9,11,12,13,12,13,14,16,18,18,19,21,21,21,19,21,21,21,23,21,23,23,22,25,25,24,24,26,24,26,25,25,26,24,25,26,24,24,25,25,25,25,25,24,25,26,25,22,25,24],[28,28,28,28,28,28,28,28,29,28,27,27,27,27,27,26,26,27,26,27,28,27,27,27,28,28,27,28,28,26,27,27,27,28,28,28,27,27,28,27,27,26,26,26,26,26,24,24,24,24,23,23,22,21,20,21,20,19,19,19,17,14,12,9,8,6,5,4,4,3,3,2,3,3,2,2,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,4,4,4,4,5,5,5,5,4,3,3,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,5,5,5,5,5,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,4,4,4,3,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,5,5,5,5,5,5,4,5,4,5,4,5,5,5,5,6,7,9,12,11,12,14,15,18,18,17,19,19,19,20,21,21,21,23,24,24,23,24,26,26,25,26,23,24,26,25,24,25,25,25,25,24,25,27,26,27,26,27,27,27,27,27,27,27,27,27,27,27,28,28,28,27,27,27,27,28,27,27,26,27,27,26,27,27,26,27,25,25,25,25,24,23,21,22,22,20,19,17,15,15,13,10,8,7,6,6,5,6,6,6,6,6,7,7,7,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,10,11,10,9,10,9,9,10,10,11,12,10,12,10,11,9,9,9,9,9,8,8,8,7,7,6,6,6,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,8,8,9,9,8,8,7,6,6,5,5,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,6,6,6,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,3,4,4,4,4,5,5,4,4,5,5,5,5,5,4,3,3,2,2,3,2,2,3,3,3,2,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,6,6,6,6,6,6,5,5,5,6,5,5,6,5,5,5,5,6,6,7,7,6,7,6,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,5,5,6,5,5,6,5,5,5,5,6,5,5,5,5,5,6,7,8,10,10,11,13,12,12,12,16,17,18,20,20,22,23,23,20,21,22,20,24,21,23,23,22,25,25,26,24,25,25,26,25,25,26,25,25,26,24,26,26,25,24,25,25,23,25,25,23,22,24,24],[29,28,28,29,28,29,29,28,29,28,28,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,27,28,27,28,27,27,27,27,27,27,26,26,26,26,24,24,24,23,22,22,22,20,20,21,20,19,18,19,16,14,12,9,8,6,5,4,4,3,3,3,2,2,2,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,4,4,3,4,5,5,5,5,5,4,3,3,3,4,4,4,4,5,4,4,3,4,4,3,4,4,3,4,4,4,4,4,5,5,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,4,4,3,3,4,4,3,3,3,4,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,5,6,5,5,6,5,5,4,4,5,5,4,5,5,5,6,7,8,9,11,12,12,14,16,18,17,17,19,19,19,21,22,21,22,23,24,24,24,24,25,25,25,25,24,24,25,23,23,24,24,25,25,24,25,26,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,26,26,27,26,26,27,25,25,24,25,24,23,21,20,20,18,18,17,15,13,12,10,8,8,6,6,5,6,6,6,6,6,7,8,7,8,8,8,9,9,9,9,9,10,10,10,11,11,11,11,10,10,10,9,9,9,10,10,10,11,12,11,10,10,9,9,9,8,9,8,8,7,7,7,7,6,6,5,6,5,5,5,5,5,5,6,6,6,6,6,7,6,7,7,7,8,8,8,8,8,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,3,3,3,4,4,5,5,6,7,7,6,5,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,4,4,4,5,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,5,5,5,4,4,5,5,6,5,5,4,4,3,2,2,2,2,2,2,2,3,3,3,3,4,3,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,6,6,6,6,6,6,5,6,5,5,5,6,5,5,5,5,5,6,7,6,6,6,6,7,6,7,6,7,7,7,7,7,6,7,7,6,7,6,6,5,6,6,5,6,6,6,5,6,6,5,5,6,6,5,5,6,8,8,9,9,11,12,13,11,13,14,16,17,18,18,22,22,20,20,21,21,21,23,21,22,23,22,26,25,25,24,26,25,25,26,26,26,26,26,26,23,24,26,25,25,26,25,24,25,26,24,23,26,26],[29,28,28,29,28,29,29,28,29,28,28,28,28,27,27,27,27,28,27,28,28,27,28,27,27,27,28,27,28,27,27,27,28,28,28,28,28,28,28,27,28,26,26,26,26,25,24,23,23,22,22,21,22,20,20,20,20,19,19,19,17,14,12,9,8,6,5,5,4,3,3,3,3,2,2,2,2,1,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,3,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,4,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,4,4,3,4,4,5,5,5,5,5,5,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,6,6,7,8,9,12,11,12,14,15,17,17,16,17,19,18,20,19,20,20,22,23,23,23,24,25,25,24,25,24,23,24,22,22,25,24,25,24,24,25,27,26,27,27,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,26,27,26,27,27,26,26,27,25,26,25,24,24,23,21,20,20,19,18,16,14,13,12,10,9,8,6,6,6,6,6,6,7,7,7,8,8,8,8,8,9,10,9,9,10,11,11,11,11,12,12,12,11,10,10,10,10,9,10,10,10,12,12,11,11,10,10,10,9,9,9,9,8,8,8,8,7,6,7,6,6,6,5,5,6,5,6,6,7,6,6,7,7,7,7,8,8,8,8,8,9,8,8,7,6,6,5,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,6,6,6,4,4,3,3,3,3,2,2,2,3,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,5,5,5,5,5,5,5,4,5,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,3,2,3,2,2,2,2,2,3,2,3,3,4,4,4,4,4,5,4,5,4,4,5,5,6,6,5,4,4,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,6,5,6,5,6,5,5,6,6,5,4,5,5,4,4,5,5,4,4,4,4,4,4,5,4,5,5,5,5,5,6,5,6,5,6,6,6,6,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,8,8,7,7,7,8,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,7,8,9,10,11,13,13,12,14,15,16,18,19,20,22,21,22,20,21,22,22,25,22,24,24,23,25,26,25,25,26,25,26,25,26,27,25,26,26,25,25,25,26,26,26,25,25,26,26,26,24,25,26],[28,27,28,28,27,28,28,28,28,27,27,27,27,26,26,25,26,27,25,27,27,25,27,27,26,27,27,26,27,26,26,27,27,28,27,28,26,27,28,27,27,26,25,25,26,25,23,24,24,23,21,23,23,20,20,21,20,19,19,19,17,14,11,9,7,6,5,4,4,3,3,3,3,2,2,2,2,1,1,1,1,1,1,0,1,1,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,3,4,4,4,3,4,3,3,4,4,4,4,5,5,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,5,5,5,6,5,5,4,4,5,5,4,4,5,5,5,6,7,8,10,9,11,14,14,16,16,16,18,19,17,18,21,20,20,22,23,24,23,23,24,26,25,25,24,24,25,23,23,25,24,24,24,24,24,26,26,26,25,26,27,27,26,26,26,26,27,27,27,26,27,27,27,26,27,27,27,27,27,26,26,27,26,26,27,26,26,27,26,26,25,25,24,23,22,21,20,19,18,18,15,14,12,10,8,7,6,6,6,6,6,5,6,6,7,7,7,7,8,8,8,9,9,9,9,10,10,10,10,10,10,10,10,10,9,9,9,9,9,10,9,10,11,10,10,9,10,9,8,8,8,8,8,8,8,7,6,6,6,6,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,7,7,7,8,8,8,7,7,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,4,5,5,6,7,7,5,4,3,3,2,2,3,2,2,2,3,3,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,3,3,4,3,3,3,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,2,2,2,2,2,2,3,3,3,4,3,4,4,5,4,4,4,5,5,4,4,4,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,7,7,6,6,6,6,6,6,5,5,6,6,5,5,6,5,5,5,5,6,6,7,7,6,7,6,6,7,7,7,7,7,7,6,6,6,6,7,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,8,9,9,11,12,12,12,12,15,16,18,20,20,21,22,22,20,21,22,21,23,21,22,23,22,24,24,25,24,25,25,25,24,24,26,24,24,26,23,24,25,25,24,25,24,23,25,25,23,23,24,23],[28,28,27,28,27,28,28,27,28,27,26,27,27,26,25,25,26,26,24,26,26,25,26,26,25,26,26,25,26,25,25,26,26,26,26,26,25,26,26,26,26,26,25,25,24,24,22,22,21,22,21,20,20,19,18,19,18,17,16,17,14,13,10,8,7,5,5,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,3,2,2,2,2,2,2,2,2,2,3,3,4,4,3,4,4,3,3,4,4,4,4,3,3,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,2,2,2,2,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,2,2,2,2,2,2,3,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,5,5,5,6,7,7,11,10,11,13,14,16,15,15,17,18,16,18,19,19,19,20,22,22,21,23,23,23,22,24,23,23,24,21,22,24,23,23,22,24,23,26,24,26,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,26,26,26,25,26,25,26,26,25,25,26,23,23,23,24,22,21,19,19,18,17,16,16,14,12,11,9,8,7,6,5,5,6,6,5,6,6,7,7,7,7,7,7,8,8,8,8,8,9,9,9,10,10,10,10,9,9,9,9,8,8,8,9,9,10,11,9,9,9,9,8,8,8,7,7,7,7,7,7,6,6,6,5,5,4,4,4,5,5,4,5,5,5,5,6,6,5,6,6,7,7,7,7,7,7,6,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,4,5,6,6,6,4,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,4,4,3,4,4,5,4,3,4,5,5,4,4,3,3,3,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,6,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,5,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,4,5,5,5,4,4,5,4,4,5,5,4,4,5,6,7,8,8,10,11,11,10,11,13,14,16,16,17,20,21,18,17,19,20,19,21,19,20,21,20,24,23,23,22,24,23,24,24,24,23,23,24,25,22,22,24,24,23,24,23,22,23,24,23,21,23,23],[28,28,28,28,28,28,28,27,28,27,26,27,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,26,27,26,26,27,27,27,27,27,27,27,27,27,27,26,26,26,25,25,23,23,23,22,21,21,21,20,19,20,18,18,17,17,15,13,11,8,7,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,2,1,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,4,3,4,4,3,4,4,4,4,3,3,2,2,2,2,2,2,2,2,1,1,2,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,4,4,4,3,3,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,5,4,5,5,5,6,7,6,7,10,10,10,14,14,15,15,15,17,17,17,18,19,19,20,21,22,22,22,23,23,25,23,24,23,22,24,23,21,24,23,24,24,23,23,25,24,26,25,26,26,27,26,27,26,26,27,26,27,26,26,27,26,27,26,27,27,27,27,26,25,26,26,27,27,26,26,26,23,25,24,24,24,22,21,20,19,18,16,16,14,12,11,9,8,7,6,6,5,5,5,5,6,6,6,6,6,7,7,7,7,8,7,8,8,9,9,9,10,10,10,10,9,9,9,8,8,8,8,9,9,10,10,10,9,9,9,9,8,7,8,7,7,7,7,6,6,6,5,5,5,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,6,7,7,7,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,4,4,5,6,6,6,5,4,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,3,3,3,3,3,4,3,4,4,3,4,5,5,4,4,4,3,3,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,5,6,6,8,8,10,11,11,10,11,13,14,17,17,18,20,21,19,18,20,20,19,22,20,22,22,22,24,24,24,24,25,23,25,25,25,26,24,25,25,23,23,25,25,25,25,24,23,25,25,24,21,23,25],[28,28,28,29,28,29,28,28,28,28,27,27,27,27,27,26,27,27,26,27,27,26,28,27,26,28,27,27,28,26,26,27,28,28,27,28,27,27,27,27,27,26,25,26,25,25,23,23,23,21,19,21,21,19,19,20,18,17,18,17,15,13,11,8,7,7,5,5,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,0,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,3,4,4,4,5,4,4,4,3,4,4,4,3,3,4,3,3,4,3,3,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,5,4,5,4,4,4,5,5,4,4,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,4,5,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,4,4,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,7,7,7,6,6,7,6,6,5,5,5,6,5,5,6,6,7,7,7,8,11,10,11,13,14,15,14,14,16,17,16,17,17,18,18,19,21,21,21,23,23,25,23,25,23,23,24,22,21,24,23,23,23,23,24,25,24,25,25,26,26,26,26,26,25,26,26,26,26,26,26,27,26,26,26,27,26,26,26,26,25,26,25,26,26,26,25,26,24,25,24,23,22,22,20,20,20,18,18,16,14,13,11,10,9,8,7,7,6,7,7,6,7,7,8,8,8,8,9,8,9,9,9,9,9,10,10,10,11,10,11,11,10,10,10,10,9,9,9,10,10,11,12,10,11,11,10,10,10,9,8,9,9,8,8,8,8,7,7,7,7,6,6,6,7,6,6,6,7,7,6,7,7,7,7,8,8,8,8,8,8,8,8,7,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,5,5,8,8,8,7,4,4,4,2,2,3,3,2,2,3,3,3,4,4,4,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,4,4,4,4,3,4,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,5,6,5,5,6,6,5,5,6,5,5,5,5,5,5,4,5,5,5,4,5,5,4,5,5,5,4,4,5,5,4,5,5,5,5,5,6,6,5,6,6,6,6,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,7,6,6,5,6,6,7,7,7,7,7,7,7,7,7,7,7,8,8,7,7,7,8,7,6,7,7,6,6,6,7,6,6,6,6,6,6,6,6,5,6,6,5,5,6,7,7,9,9,10,12,13,11,12,13,15,16,17,17,20,20,20,18,19,20,19,22,20,21,22,21,23,24,22,23,24,23,24,23,23,25,23,24,24,22,22,24,24,23,25,23,22,24,25,23,21,23,24],[28,28,28,28,28,29,28,28,28,27,27,27,27,27,27,27,27,27,26,27,27,26,27,27,26,27,27,27,28,27,26,27,28,28,27,28,27,28,28,27,28,26,26,26,26,25,23,24,24,22,22,22,22,20,20,21,19,18,19,19,16,14,11,8,7,6,5,4,4,3,4,3,3,3,3,2,3,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,5,4,3,3,3,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,4,4,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,6,7,6,7,10,9,10,13,13,14,14,14,16,16,15,17,18,18,18,20,22,23,23,24,24,26,24,26,23,23,25,24,22,25,25,24,25,25,24,26,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,27,28,28,27,27,27,27,28,27,27,27,27,27,27,25,26,24,25,24,22,22,21,19,20,17,17,15,12,12,10,8,7,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,9,8,9,9,10,9,10,10,11,11,11,10,10,10,9,9,9,9,10,10,11,12,11,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,6,6,5,5,6,6,6,6,7,6,7,7,7,8,8,8,8,7,7,6,6,5,5,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,4,4,4,7,6,7,5,4,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,3,3,3,4,4,3,4,4,4,4,3,4,4,5,5,5,4,4,3,3,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,6,5,5,5,5,5,5,5,5,6,6,6,6,6,7,6,6,6,6,6,7,7,6,6,6,7,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,8,9,11,12,13,11,12,14,16,17,18,18,21,21,21,19,21,20,22,24,22,23,23,23,25,25,25,24,24,23,25,25,25,27,24,25,25,24,24,24,25,25,25,25,24,25,25,25,23,23,24],[28,28,28,28,28,29,28,28,28,27,27,27,28,27,27,27,27,28,26,28,27,26,28,28,26,27,28,26,27,27,26,27,28,28,26,28,27,26,27,26,27,25,25,25,26,25,21,23,23,21,21,22,21,19,19,20,18,17,18,18,16,13,11,9,8,7,6,5,5,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,1,1,1,0,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,5,5,4,4,4,4,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,5,5,4,4,5,4,5,4,4,4,5,4,4,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,4,4,3,4,4,4,4,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,5,4,5,4,5,4,4,4,4,4,4,4,4,3,4,4,4,4,4,3,3,3,3,3,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,7,7,6,6,6,7,6,6,7,7,7,8,8,9,11,11,11,13,13,14,15,15,16,16,16,17,18,18,18,20,21,21,21,23,23,25,24,24,23,22,24,23,22,24,23,23,24,23,24,26,26,27,25,26,26,27,27,27,26,26,26,26,26,27,27,27,27,27,27,26,26,26,26,25,25,26,25,25,26,25,25,26,24,24,24,24,23,22,21,21,20,19,19,17,15,14,14,11,10,9,8,8,8,8,8,8,9,8,9,9,9,9,10,10,10,11,10,10,12,12,11,12,13,13,13,12,12,12,11,10,11,11,12,12,14,13,13,13,14,13,13,12,11,10,10,11,11,10,10,10,9,8,8,9,8,7,7,7,8,8,7,7,8,7,7,8,8,8,8,9,9,9,10,10,10,9,9,7,8,7,6,6,5,6,5,5,5,5,5,6,6,6,5,6,5,5,5,5,5,5,4,4,4,4,4,4,3,4,4,3,3,4,4,4,5,7,7,8,6,5,4,4,3,3,3,3,2,3,2,3,3,3,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,8,8,7,7,7,7,7,7,6,6,7,7,6,7,7,6,6,6,7,7,8,8,8,8,8,8,7,8,8,8,8,9,9,8,8,7,9,8,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,8,9,10,11,12,13,14,12,14,15,17,19,19,19,22,21,22,21,21,22,21,24,21,23,24,22,25,25,25,24,25,24,26,26,24,27,26,26,25,25,26,26,26,24,26,25,24,25,25,24,24,24,25],[28,28,28,28,28,28,28,28,28,28,27,27,27,27,27,26,27,27,27,27,27,27,28,27,27,28,27,27,28,26,26,27,27,27,27,27,26,27,27,27,27,26,25,26,25,25,22,23,23,22,21,21,21,20,19,20,19,18,18,18,16,13,12,9,8,7,6,6,5,5,5,4,4,4,4,3,3,3,3,3,2,2,2,2,2,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,3,3,3,4,4,4,5,5,4,4,4,4,4,4,4,3,3,3,4,3,3,4,4,4,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,4,4,4,4,3,3,2,2,3,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,5,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,3,3,4,3,3,4,4,3,3,4,4,4,3,3,3,3,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,7,6,7,8,8,8,11,11,11,13,14,15,15,15,17,18,18,20,20,21,21,22,23,24,24,25,25,26,25,26,25,24,25,23,22,25,25,24,24,24,24,26,25,26,26,27,27,28,27,27,27,27,27,27,27,27,28,27,27,28,27,27,27,28,27,27,26,27,26,26,27,27,26,27,25,25,26,25,24,23,22,22,21,20,19,19,15,15,13,11,10,9,8,8,8,8,7,7,8,8,9,9,9,9,9,9,10,11,10,10,11,11,11,11,12,12,12,12,11,11,11,10,11,10,11,11,12,12,13,13,12,11,12,12,11,10,10,10,10,9,9,9,9,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,8,7,8,8,9,9,10,9,9,9,9,7,7,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,4,4,4,5,7,7,7,5,4,4,3,3,2,2,3,2,2,2,3,3,3,3,4,3,4,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,5,4,5,5,4,5,5,5,5,5,5,4,4,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,5,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,6,7,7,7,7,6,8,7,7,7,7,7,7,7,7,6,7,6,7,7,7,6,6,6,7,7,8,8,8,7,7,8,7,8,8,7,7,8,8,7,7,7,8,8,7,7,7,7,6,6,7,6,6,7,7,6,6,7,7,6,7,6,6,6,7,8,8,10,10,12,13,13,12,14,15,17,18,19,20,22,22,21,20,22,21,20,24,22,23,25,21,26,25,26,25,25,24,26,26,26,27,26,26,26,24,25,26,26,25,26,25,24,26,25,24,22,25,25],[28,28,28,28,28,28,29,28,28,27,26,26,27,27,26,27,26,27,26,27,27,26,28,27,26,27,27,26,27,26,25,27,27,28,27,27,26,26,27,26,27,25,25,25,25,24,22,23,23,20,20,22,20,19,18,20,18,17,17,17,16,14,12,9,8,8,7,6,6,5,6,5,5,5,4,4,4,4,3,3,3,3,2,2,2,2,2,1,1,1,0,1,2,1,2,2,2,2,2,3,3,2,3,3,3,3,4,4,4,4,4,4,3,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,2,2,3,3,3,3,3,4,4,3,3,3,4,3,3,4,4,3,4,4,4,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,4,3,4,4,4,4,4,4,4,5,5,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,8,8,8,8,7,7,6,7,7,7,7,7,7,8,8,8,9,11,11,12,13,13,14,14,15,17,16,17,18,19,18,20,21,22,22,22,24,24,26,24,26,23,23,23,24,22,24,24,24,25,23,24,26,25,27,26,27,26,27,27,27,26,26,26,26,26,27,28,27,28,28,27,27,27,28,27,27,26,27,26,26,27,26,25,27,25,26,26,24,24,22,22,20,20,18,17,17,15,15,14,12,11,10,9,8,8,8,8,9,9,10,10,11,10,10,11,11,11,13,11,11,12,14,13,13,14,15,14,14,14,13,12,13,13,13,13,13,15,14,14,15,14,14,13,13,12,11,11,12,11,10,10,10,10,9,9,9,9,8,8,7,8,9,8,9,9,8,8,9,9,9,9,10,10,11,10,10,10,10,9,8,8,8,7,6,6,6,6,6,6,5,6,6,6,5,5,6,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,7,7,7,6,5,4,4,3,3,3,3,2,3,3,3,3,3,4,4,4,4,4,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,7,7,7,6,6,6,6,5,6,6,5,5,6,6,5,5,5,6,5,5,5,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,3,3,2,3,2,2,2,3,3,3,2,2,3,3,3,4,4,4,4,5,5,5,5,4,5,5,6,6,6,5,5,5,4,4,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,8,7,6,7,7,6,6,7,7,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,7,7,6,7,8,7,7,7,8,8,7,8,9,9,8,9,8,8,7,8,8,7,8,8,7,8,8,8,7,7,8,8,9,8,9,8,8,9,8,9,8,9,8,9,9,8,8,7,9,8,8,8,8,8,7,7,8,8,7,8,8,7,7,8,8,7,7,8,7,7,7,8,9,11,11,13,13,14,13,14,16,17,18,20,20,23,23,23,22,22,23,23,24,23,24,25,24,26,26,26,26,25,25,25,27,26,27,25,26,26,25,25,27,26,26,26,26,24,26,26,26,24,26,26],[28,27,27,27,27,28,27,27,27,25,26,24,26,25,25,26,25,26,25,26,26,25,26,26,25,26,26,25,25,26,25,26,27,27,25,26,26,25,26,25,26,25,24,24,24,23,21,21,22,19,19,20,19,19,18,18,16,16,16,16,13,12,10,8,8,7,6,6,5,5,5,5,4,4,4,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,3,3,4,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,3,3,3,2,3,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,4,4,5,4,4,4,5,4,4,5,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,7,7,7,6,6,7,6,6,6,7,7,7,8,9,10,10,10,12,13,13,12,14,15,14,15,17,17,18,18,19,19,21,20,22,22,23,23,23,22,22,22,22,22,23,22,24,23,23,23,25,25,26,25,25,25,25,26,27,26,26,26,25,25,26,26,26,26,27,26,27,25,26,24,25,25,25,26,24,26,25,24,26,24,23,24,24,22,22,21,19,19,18,17,17,15,13,13,11,10,8,8,7,7,8,8,7,8,9,9,9,9,10,10,10,10,12,10,11,12,12,11,12,13,14,12,13,12,13,12,12,11,12,11,12,13,13,13,14,13,12,12,12,11,11,11,11,10,10,10,9,9,8,9,8,8,7,7,7,8,7,7,8,8,7,8,8,8,8,8,9,9,9,10,9,10,9,8,7,7,7,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,6,6,6,6,5,4,4,3,3,3,2,2,2,3,3,3,3,3,4,3,4,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,4,4,4,4,4,4,4,5,4,5,4,4,4,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,7,7,7,7,7,7,6,6,7,7,6,7,7,6,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,9,8,8,7,8,8,7,8,8,7,7,7,8,7,7,7,7,7,6,7,7,7,7,7,7,7,7,7,8,10,10,12,12,13,12,13,14,15,16,17,17,20,19,20,19,20,20,20,21,21,21,23,22,23,24,24,23,24,21,25,24,23,25,24,23,24,23,24,23,23,23,23,24,23,25,24,23,23,23,23],[28,28,28,28,28,29,28,28,28,27,27,27,28,26,27,26,27,27,27,27,27,27,28,27,26,28,27,27,28,26,26,28,28,28,27,28,26,27,27,27,27,26,25,26,26,26,23,23,23,21,21,21,21,19,18,19,17,17,18,17,15,12,10,9,7,7,6,5,5,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,4,4,4,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,3,3,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,7,6,6,5,6,6,6,6,6,7,7,7,8,9,10,11,11,13,14,15,14,15,17,17,16,19,19,19,20,21,23,23,23,24,25,26,25,26,24,24,25,24,23,24,25,25,24,24,25,27,25,27,26,27,28,27,27,27,27,27,27,27,26,27,28,28,27,27,27,28,27,27,27,27,26,27,26,26,27,27,27,27,25,26,25,25,23,23,22,21,22,19,18,17,15,14,12,11,10,9,8,7,7,7,7,7,8,8,8,9,9,9,9,9,9,11,10,10,11,12,11,12,12,13,12,12,11,12,10,10,11,10,11,11,12,13,13,14,13,11,12,12,11,10,10,10,10,9,9,9,9,8,8,8,7,7,6,6,7,7,6,7,7,7,7,7,7,7,7,8,8,8,9,9,8,8,8,7,7,6,6,5,5,5,5,5,5,4,4,5,4,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,6,6,6,6,4,4,3,3,3,3,3,2,2,3,3,3,3,3,4,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,4,4,5,4,4,4,4,5,5,5,5,4,4,3,3,3,3,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,6,5,6,6,6,6,6,6,5,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,6,6,6,7,7,7,7,7,7,7,7,6,6,7,7,6,7,7,6,6,6,7,7,8,8,8,7,7,8,7,7,8,7,7,8,8,7,7,7,8,8,7,7,7,7,6,6,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,8,8,9,10,11,12,13,12,13,15,16,17,19,19,22,23,22,20,22,22,20,23,21,22,25,22,24,25,25,25,25,25,26,26,26,27,26,26,26,24,26,27,26,25,26,25,25,26,25,24,24,26,24],[28,28,28,28,28,29,28,28,29,27,27,27,26,26,26,26,26,26,27,27,26,27,27,26,27,27,26,27,27,26,27,27,27,27,27,27,27,27,27,26,27,26,26,26,25,25,23,23,22,22,22,21,21,20,19,19,17,18,17,16,14,13,10,8,7,6,5,4,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,3,2,3,3,3,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,2,2,2,3,3,4,3,3,3,4,3,3,4,4,3,4,3,3,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,6,6,6,6,6,6,6,6,5,5,6,5,5,5,6,5,6,7,7,8,10,10,10,12,13,14,13,14,16,16,15,17,18,19,18,19,22,23,21,24,24,25,24,25,23,22,25,23,22,24,24,24,24,23,24,26,25,27,25,26,27,27,27,27,26,26,27,27,27,27,27,27,27,28,27,28,27,27,27,26,26,27,27,27,27,26,27,27,24,25,24,24,24,22,21,20,19,18,16,16,15,13,11,10,9,8,7,7,7,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,10,10,10,10,11,11,11,11,10,10,10,9,10,9,10,10,11,11,11,11,10,10,9,9,9,8,8,9,8,8,7,7,7,7,6,6,6,6,5,5,6,5,5,5,6,5,6,6,6,6,6,7,7,7,8,8,8,7,7,6,5,5,5,4,4,4,4,4,4,3,4,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,3,3,3,3,4,3,4,4,3,4,4,4,4,4,4,4,3,3,3,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,6,7,6,6,6,6,6,6,6,6,5,6,6,5,6,6,5,5,5,6,6,6,7,7,6,6,7,7,7,7,7,6,7,7,6,6,6,7,7,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,8,9,10,11,12,11,12,13,15,17,18,18,21,22,21,19,21,21,21,23,21,23,24,22,25,25,25,24,25,24,25,25,25,26,24,25,26,23,24,25,25,25,26,25,23,25,25,23,23,24,23],[28,27,27,28,27,28,28,27,27,26,26,25,26,25,25,26,26,26,26,26,26,26,27,26,26,26,26,26,26,26,25,27,27,27,26,27,26,25,26,26,26,24,24,24,24,23,21,21,22,19,20,19,19,17,16,18,15,15,16,15,13,12,10,8,7,6,6,5,5,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,2,2,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,4,3,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,6,6,6,6,6,6,5,5,6,5,5,6,6,6,6,7,8,9,10,10,11,13,13,12,13,15,14,14,16,17,16,18,18,20,20,20,22,23,24,23,24,22,21,23,22,22,23,23,24,24,24,24,25,26,27,25,25,26,26,26,26,25,25,26,26,26,26,26,26,26,27,26,28,26,26,26,26,26,26,26,25,27,25,25,26,26,24,24,24,22,21,21,18,17,16,15,16,14,12,12,10,8,7,7,7,7,7,7,7,8,8,8,8,8,9,9,9,10,11,10,9,11,12,11,10,12,13,12,12,12,12,10,10,10,10,10,10,12,12,11,12,12,11,11,11,10,9,9,10,9,9,9,8,8,7,7,7,7,6,6,6,7,6,6,6,7,6,7,7,7,7,7,8,8,8,9,8,8,7,7,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,5,4,4,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,5,6,6,5,5,6,6,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,7,6,6,6,7,7,7,7,7,6,6,7,6,5,6,6,5,6,7,6,5,6,6,7,7,7,8,7,7,7,7,8,7,7,7,7,8,7,7,6,8,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,7,9,9,10,11,12,12,13,14,15,16,17,18,21,20,20,20,21,19,20,22,21,21,22,22,23,23,24,22,25,22,24,24,24,24,23,23,24,22,22,24,24,23,24,23,24,24,24,23,22,23,24],[28,28,27,28,28,29,28,28,28,26,27,26,26,26,25,26,26,26,27,27,26,25,26,26,25,26,26,26,27,26,25,26,27,27,26,26,26,25,26,25,27,25,25,24,24,24,21,21,21,19,19,20,19,17,16,18,16,16,15,16,13,12,10,8,7,7,6,5,5,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,6,7,6,6,6,6,5,6,6,6,6,6,6,6,7,7,8,9,10,10,11,13,13,11,14,15,14,15,17,17,17,18,18,20,22,22,23,23,23,23,24,22,22,23,22,22,23,24,24,23,23,24,26,25,27,25,26,26,25,26,26,26,25,26,26,25,26,26,27,26,27,26,27,27,26,26,26,25,26,26,26,27,26,26,27,25,25,24,24,23,23,22,19,20,18,17,16,14,13,12,10,9,8,7,7,7,7,7,7,7,8,8,8,8,9,10,9,10,11,10,10,11,12,11,11,13,13,12,12,11,12,11,10,11,11,11,11,12,12,13,12,12,11,11,12,10,10,10,10,10,9,9,9,8,7,7,7,7,6,6,6,7,6,6,6,7,6,6,7,7,7,7,8,8,8,9,8,8,7,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,5,6,6,6,5,5,4,3,3,3,3,2,2,3,2,3,3,3,3,4,3,3,3,3,3,3,2,2,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,4,5,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,3,3,3,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,6,6,6,6,5,6,6,6,6,6,6,5,5,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,6,6,7,8,7,6,7,7,7,6,7,6,6,7,7,6,7,7,6,6,6,6,7,7,8,8,7,7,7,7,8,7,7,7,7,8,7,7,6,7,7,6,6,7,6,6,6,7,6,6,6,6,6,5,6,6,6,5,6,5,5,6,7,7,8,9,10,11,12,11,12,13,15,16,19,19,21,22,20,20,22,20,21,22,21,22,24,21,24,25,25,24,25,24,26,25,24,26,25,25,26,24,24,25,25,25,25,26,25,26,25,24,23,25,24],[28,29,28,29,28,29,29,28,28,28,27,27,27,27,28,27,27,27,27,27,26,26,27,26,26,28,27,27,28,26,26,28,27,28,27,27,26,27,27,27,27,27,26,26,26,26,24,24,24,23,23,22,22,20,19,20,17,18,17,17,14,12,10,8,7,6,5,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,4,4,4,3,4,3,4,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,6,6,5,5,5,5,5,5,5,5,5,6,6,7,7,9,10,10,13,14,15,13,15,17,17,17,19,20,20,20,21,24,24,23,25,26,26,25,26,23,24,26,24,23,25,25,25,25,24,25,26,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,27,27,27,26,27,27,27,28,27,27,27,25,26,25,24,24,23,22,20,20,19,17,16,14,13,12,10,9,8,6,6,6,6,6,6,6,6,7,7,7,7,8,8,8,9,8,9,9,10,9,10,11,11,10,11,10,10,10,9,9,8,9,10,10,11,11,10,10,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,6,5,5,5,6,5,5,6,6,5,6,7,7,7,8,7,7,7,6,5,5,5,5,4,4,3,4,4,3,3,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,3,3,2,3,3,2,2,2,2,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,4,5,5,5,5,5,5,4,5,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,5,5,6,7,6,6,6,6,6,5,6,5,5,6,6,5,5,6,5,5,5,5,6,6,6,7,6,6,7,6,7,7,7,7,7,7,6,6,6,7,7,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,8,9,10,11,11,11,11,13,14,16,18,18,21,22,20,19,20,21,20,24,20,22,23,21,25,26,26,24,25,25,26,26,25,26,24,25,26,23,24,26,26,24,25,24,24,25,25,23,22,24,24],[28,28,28,28,28,29,29,28,28,27,26,26,27,26,26,26,27,26,27,27,26,26,27,26,26,27,27,27,28,27,26,28,28,28,27,28,26,27,27,27,27,25,25,26,26,24,22,22,23,20,21,21,21,19,19,19,16,18,16,16,13,12,10,8,7,6,5,5,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,4,3,3,3,4,4,3,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,6,6,5,6,6,5,5,5,5,5,5,5,6,5,6,6,7,8,9,9,10,11,12,13,13,13,15,15,15,17,17,17,18,19,20,21,21,22,23,24,23,24,22,22,23,22,20,23,24,23,23,23,23,24,25,26,25,25,26,26,26,26,26,26,26,26,26,27,26,26,26,27,26,27,27,27,27,26,26,27,26,26,26,26,26,26,24,25,25,24,23,22,20,19,19,17,16,15,14,12,12,10,9,8,6,6,6,6,6,6,7,6,7,7,7,7,8,8,8,9,9,9,10,9,9,10,11,11,10,11,10,10,10,9,9,9,10,10,10,10,10,10,10,9,9,9,9,8,8,8,8,8,7,7,7,6,6,6,6,5,5,5,6,5,5,6,6,5,5,6,6,6,6,7,7,7,7,8,7,6,6,5,5,5,4,4,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,4,4,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,7,7,6,6,6,6,6,5,6,6,5,6,6,6,5,5,5,6,6,7,7,6,7,7,6,7,7,7,7,7,8,6,6,6,7,7,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,4,5,5,5,4,5,6,7,8,8,10,11,11,10,11,12,13,16,16,18,19,20,19,17,19,20,20,22,21,22,22,22,23,23,24,22,24,22,24,24,23,26,23,23,24,23,23,24,24,23,24,24,23,24,24,23,22,24,24],[27,27,27,27,27,28,27,27,27,26,24,24,25,24,24,25,25,25,25,26,25,24,25,25,24,25,25,24,25,24,24,25,26,26,24,26,25,25,25,24,26,23,23,23,24,23,19,20,21,18,18,19,18,16,16,17,15,14,15,15,13,12,10,9,7,7,6,5,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,3,3,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,3,3,2,3,3,2,2,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,3,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,6,7,6,6,6,5,5,6,6,5,5,6,6,6,7,8,9,10,10,11,12,12,11,13,14,13,14,16,16,16,17,17,18,20,19,20,21,22,22,22,22,21,21,21,21,21,21,22,22,22,21,23,24,25,24,24,24,24,25,25,24,24,25,25,25,25,25,26,25,26,25,26,26,26,25,25,24,25,25,24,25,25,24,25,24,23,23,22,21,20,19,18,17,16,15,14,13,12,12,10,9,8,7,7,7,7,7,7,7,7,8,8,8,8,9,9,9,10,9,9,10,10,10,10,11,11,11,11,11,11,10,10,10,9,10,10,11,11,12,11,11,11,10,10,9,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,7,6,6,6,7,6,6,7,7,6,7,7,7,8,8,8,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,5,6,6,6,5,4,4,4,3,3,3,3,2,2,3,3,3,3,3,3,3,4,3,3,3,3,2,2,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,6,6,5,6,6,5,5,6,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,6,7,6,6,7,6,5,6,7,6,5,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,6,7,7,6,7,7,7,6,6,7,6,6,6,6,5,5,6,6,5,5,6,5,5,5,6,7,8,8,10,11,11,11,12,12,14,16,16,15,18,19,19,18,19,18,19,20,20,19,21,20,22,22,23,22,23,21,23,23,22,24,22,22,22,21,21,23,22,22,22,22,22,23,23,22,20,22,22],[28,28,28,28,28,28,28,28,28,26,27,26,27,25,26,26,27,26,26,27,26,26,26,26,26,27,26,26,27,26,25,27,27,27,26,27,25,26,26,25,26,25,25,25,25,24,22,22,22,21,20,20,21,18,19,19,17,17,17,17,14,12,11,9,8,7,6,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,6,6,6,5,6,6,6,6,6,6,7,7,8,8,10,11,11,12,14,14,13,16,16,17,16,19,18,18,20,20,21,22,22,24,25,25,25,25,24,23,24,23,22,24,25,25,24,24,24,26,26,27,26,26,27,26,26,27,26,26,27,27,26,27,27,28,27,28,27,28,28,27,28,27,25,28,26,26,28,27,26,27,25,26,26,25,23,24,22,21,20,19,17,17,14,13,12,12,10,9,7,7,7,7,7,7,7,7,8,8,8,8,9,9,9,11,10,10,11,11,11,11,12,12,11,12,12,11,11,9,10,10,10,11,12,12,12,12,12,11,11,11,10,9,9,10,10,9,9,9,8,7,7,7,7,6,6,6,7,6,5,6,7,6,6,7,7,6,7,8,8,8,8,8,7,7,7,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,6,6,6,6,5,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,4,4,5,5,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,4,4,4,5,5,4,5,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,5,5,6,5,5,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,6,7,7,8,7,7,7,7,7,7,7,6,7,7,6,7,7,6,6,6,6,6,7,7,8,7,7,7,7,8,8,7,7,8,8,7,7,7,7,7,6,6,7,6,6,6,7,6,5,6,6,5,5,6,5,5,5,5,5,5,6,7,7,8,8,10,11,12,10,12,14,15,16,18,19,21,22,20,19,21,21,20,22,21,21,23,22,24,25,24,23,25,23,25,25,24,26,24,24,25,24,24,25,25,25,25,25,22,25,24,23,23,25,24],[28,28,28,29,28,29,29,27,29,28,27,27,27,26,27,26,26,26,27,27,25,26,27,25,26,27,26,26,27,25,25,27,27,28,26,27,25,27,27,26,27,26,25,26,25,25,23,22,23,22,22,21,22,20,18,19,18,18,16,16,14,13,11,9,8,6,6,5,5,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,3,3,4,3,3,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,2,3,3,3,2,3,3,3,3,3,4,3,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,5,5,6,6,5,6,6,6,6,7,7,8,10,11,11,13,14,15,13,15,17,16,16,17,18,19,19,19,22,23,23,24,25,24,25,26,23,23,25,24,24,25,25,25,25,25,25,26,27,27,26,26,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,29,28,28,28,28,26,28,28,27,28,27,27,28,25,26,26,25,25,23,22,20,20,18,16,17,15,13,12,10,9,8,7,7,6,7,6,6,6,7,8,8,7,7,8,8,8,9,9,9,9,10,10,10,11,11,11,11,10,11,10,10,9,9,10,9,11,11,11,10,10,10,10,10,9,8,8,8,8,8,7,7,8,7,7,6,6,5,5,5,6,5,5,6,6,5,5,6,6,6,6,7,7,7,7,7,7,7,7,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,5,5,6,6,5,4,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,4,3,4,4,3,3,4,4,4,4,5,4,4,5,5,6,5,6,6,5,5,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,5,5,4,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,7,7,7,6,7,6,6,6,7,6,6,6,6,5,6,6,6,6,7,7,6,7,7,7,7,7,7,7,8,8,7,7,7,7,7,6,6,7,6,5,6,6,5,5,6,5,5,5,5,5,4,5,5,5,5,5,6,7,8,9,10,11,11,11,12,12,15,15,18,17,21,23,20,19,21,21,20,24,21,22,24,22,24,25,25,25,26,24,26,25,25,25,25,25,25,24,25,26,26,25,25,25,24,25,25,24,23,25,24],[28,27,27,28,27,28,27,27,28,26,25,26,26,26,26,26,25,26,26,26,26,27,26,26,26,26,26,26,26,26,25,27,27,28,26,27,26,26,27,26,27,25,25,25,25,24,22,22,23,20,20,20,21,19,18,19,17,17,16,16,14,13,11,9,8,7,6,5,5,4,5,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,2,2,2,2,2,2,2,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,6,6,7,6,6,7,6,6,6,5,6,6,6,6,6,6,7,7,8,9,10,11,11,13,13,13,12,14,15,14,15,17,17,17,19,18,21,22,21,23,24,24,23,25,23,22,23,22,21,22,23,23,23,23,23,25,25,25,24,25,26,26,25,26,26,26,26,27,26,26,26,27,26,27,26,27,26,27,26,26,25,26,26,26,27,26,27,26,25,25,25,25,22,21,21,18,18,18,16,15,14,13,12,10,10,9,8,7,7,7,7,7,8,8,8,8,9,9,9,9,10,10,9,10,11,11,11,11,12,13,11,11,12,12,10,10,10,10,11,11,12,13,12,13,12,11,11,11,10,10,10,10,10,9,9,9,8,8,7,7,7,6,6,6,7,7,6,7,7,7,7,7,7,7,7,8,8,8,9,8,8,7,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,6,6,6,5,5,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,4,4,4,5,5,4,4,5,5,5,5,5,5,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,7,6,7,6,6,6,7,6,6,6,7,6,6,6,6,6,5,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,6,7,7,7,7,7,8,8,8,8,8,7,7,7,7,6,8,7,6,7,7,7,6,6,6,7,8,8,8,7,8,8,8,8,7,8,8,9,9,7,8,7,8,8,7,7,8,7,6,7,7,6,6,6,6,6,6,6,6,5,6,6,5,5,5,6,7,8,9,11,12,12,10,13,13,15,16,17,17,19,20,20,19,20,19,21,22,21,21,22,21,22,22,24,21,23,22,23,24,23,24,23,24,23,24,23,24,24,23,24,23,22,24,24,22,21,23,23],[28,28,27,27,27,28,27,27,27,25,25,25,26,25,25,26,26,26,26,26,25,25,25,25,25,25,25,26,26,26,25,26,26,27,25,27,26,26,27,25,26,24,24,24,25,24,21,21,22,20,19,20,20,18,18,19,18,17,17,16,15,13,12,11,10,8,8,7,7,6,6,6,5,5,5,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,2,2,2,2,3,3,3,2,2,3,3,3,3,3,3,3,2,3,2,2,2,3,2,2,3,2,2,3,3,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,4,3,3,3,4,3,3,4,4,4,5,5,5,5,5,5,5,6,6,5,6,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,6,6,6,7,6,6,7,7,7,7,8,8,8,8,8,8,9,9,9,9,9,8,8,8,7,7,8,8,7,7,8,8,8,10,10,12,13,12,14,14,14,14,15,16,16,17,18,19,18,19,19,21,23,21,22,24,23,23,24,23,23,22,22,21,23,23,23,24,24,23,25,25,25,25,25,26,26,26,26,26,26,27,26,26,26,26,27,26,27,26,26,26,26,26,26,25,26,25,25,27,26,26,26,25,25,24,23,23,21,21,18,18,18,16,17,14,14,15,12,12,10,10,9,10,9,10,10,10,11,11,11,11,12,12,12,13,14,13,12,14,14,13,14,14,15,14,14,15,13,13,13,13,13,13,14,15,14,15,15,15,14,13,14,13,12,12,13,11,11,12,11,11,10,10,10,10,10,8,9,10,9,9,9,10,9,9,10,10,8,9,10,10,10,10,10,9,9,9,8,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,6,6,7,7,8,8,7,6,6,5,5,5,4,4,4,4,4,4,4,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,7,8,7,8,7,7,7,7,7,7,7,7,7,6,7,7,6,6,7,7,6,7,7,6,7,6,6,6,6,6,6,5,5,5,5,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,4,5,5,5,5,6,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,7,7,7,8,7,8,8,9,8,8,8,8,9,9,8,8,9,8,8,8,8,8,8,7,8,8,7,7,8,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,9,10,10,9,9,9,9,9,10,9,9,10,10,9,8,9,9,9,11,10,11,10,11,11,10,10,10,10,10,10,11,10,9,9,10,10,9,9,10,9,9,8,10,8,8,8,8,8,8,8,8,8,7,8,7,8,7,8,9,10,10,12,13,14,12,14,15,17,18,19,19,20,21,21,21,21,21,22,22,22,21,23,21,23,23,25,23,24,23,24,25,25,26,24,24,24,24,24,24,24,25,25,24,24,24,24,23,22,23,24],[28,28,28,28,28,28,28,28,28,26,26,26,27,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,25,27,27,27,25,27,26,26,26,25,27,26,24,25,25,24,23,22,23,21,21,21,21,20,19,19,19,18,17,17,16,15,13,12,10,9,9,8,8,7,7,7,6,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,3,3,3,3,3,3,2,2,2,2,1,2,1,1,1,0,1,1,1,2,2,3,3,2,2,2,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,2,2,2,3,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,4,3,3,4,4,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,4,4,4,4,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,4,6,6,5,6,5,6,5,5,5,4,4,5,5,5,5,5,5,5,6,5,5,5,5,6,6,5,5,6,6,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,6,6,6,5,5,5,4,5,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,7,8,8,9,8,8,9,9,9,9,9,9,10,9,9,9,8,9,9,9,9,9,9,10,10,11,11,13,14,14,15,15,16,15,17,18,17,18,19,19,20,20,20,22,23,22,23,25,25,24,25,24,23,24,23,22,23,24,25,25,25,24,26,26,27,26,26,27,26,27,26,26,26,27,27,26,26,27,27,27,27,27,28,28,27,27,27,26,27,27,27,27,26,27,27,25,26,25,24,24,24,22,20,20,18,17,17,15,15,14,14,12,12,10,10,10,10,10,10,11,12,11,12,11,12,13,13,13,14,13,12,14,15,14,13,15,15,14,14,15,14,14,13,13,13,14,13,15,15,15,16,15,14,14,15,14,13,12,13,13,11,12,12,12,11,10,11,11,10,9,9,10,9,9,10,10,10,9,10,10,10,10,10,10,10,10,10,10,10,10,8,9,8,7,7,6,7,6,7,7,6,7,7,7,6,7,7,7,7,7,6,6,7,7,7,6,6,6,6,6,7,7,6,6,6,7,7,8,7,9,8,7,7,6,6,6,5,5,4,5,5,4,4,4,5,5,5,6,6,5,5,5,6,5,5,5,5,5,5,6,6,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,8,8,8,7,7,8,8,7,8,8,7,7,7,8,8,7,7,7,7,7,7,7,8,7,7,7,7,7,7,7,6,6,6,6,5,5,4,4,4,4,4,4,3,3,3,4,4,4,5,5,5,6,6,7,7,6,7,7,7,7,7,7,7,7,6,6,6,6,6,7,6,7,7,7,6,7,7,7,8,8,8,8,9,9,9,9,10,9,9,9,9,9,9,9,9,9,9,8,9,9,8,9,9,8,8,8,8,7,8,8,8,7,7,8,8,8,8,9,8,9,9,9,10,9,10,10,10,9,10,10,11,10,10,10,10,10,10,10,10,11,10,10,10,11,10,9,10,10,10,12,11,12,10,10,11,11,11,11,11,11,11,12,11,10,10,10,10,9,10,10,10,9,9,10,9,9,9,9,8,9,9,9,8,9,8,8,8,9,10,10,11,11,12,13,14,13,15,15,16,18,19,18,21,21,20,20,21,21,21,22,21,22,24,21,23,24,25,24,24,23,26,25,24,26,24,25,26,24,25,25,25,25,25,25,24,25,25,23,23,24,24],[28,28,28,29,28,29,28,28,29,27,26,27,27,26,27,26,26,26,27,27,26,27,26,26,26,26,26,26,26,26,25,27,27,28,26,28,26,27,27,26,28,26,25,26,26,26,24,23,24,22,22,21,22,21,20,20,19,19,17,18,16,14,13,12,10,9,8,8,8,6,7,6,6,5,6,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,2,2,3,2,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,4,5,5,5,5,5,6,6,5,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,6,5,5,5,5,4,4,5,5,4,4,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,6,7,7,6,7,7,7,7,7,8,8,8,9,8,8,9,8,9,9,8,9,8,8,8,8,9,8,8,9,9,8,9,9,10,11,13,13,13,14,15,16,16,17,19,18,18,19,20,21,21,21,23,24,23,24,26,26,25,26,24,24,24,24,24,24,25,24,25,25,25,25,26,26,26,26,27,27,27,27,27,27,28,28,28,27,27,27,27,28,28,28,28,28,28,28,27,28,28,28,28,28,28,28,26,27,27,26,25,24,23,21,21,20,18,19,16,15,15,13,13,12,10,9,9,10,10,9,10,11,12,12,11,12,13,12,13,15,14,14,15,15,14,15,16,16,15,15,14,15,14,13,13,13,15,14,15,16,16,16,15,15,15,15,14,13,13,13,13,12,12,11,11,10,10,10,10,8,8,8,9,9,8,9,10,9,9,9,10,9,10,11,11,10,11,11,10,9,9,8,8,7,7,6,6,6,6,6,6,5,6,6,6,5,6,6,6,6,6,5,6,6,6,5,5,6,5,5,5,6,5,5,6,6,7,6,7,7,8,8,7,6,5,5,5,5,4,4,4,4,4,4,4,5,5,5,6,6,6,5,5,5,5,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,7,7,7,7,6,7,7,7,6,7,7,7,7,7,7,7,6,7,7,7,6,7,7,7,7,6,6,7,6,6,6,6,6,5,5,5,4,4,4,4,3,3,3,4,3,3,3,4,4,5,5,5,6,6,7,6,6,7,7,7,7,7,7,6,6,6,6,5,6,6,6,5,6,6,6,6,7,6,7,7,7,7,7,8,8,9,9,9,9,8,9,9,8,9,9,9,8,8,8,9,8,7,8,8,8,7,8,8,7,8,7,7,7,7,7,7,7,8,8,7,8,9,9,9,9,10,10,9,10,10,11,11,10,11,11,10,9,10,10,9,11,10,9,10,10,10,8,9,9,9,10,11,11,10,10,10,11,12,11,11,11,12,12,10,11,10,10,11,9,9,11,10,8,9,10,9,8,9,9,8,8,9,8,7,8,8,7,7,7,9,9,10,11,13,13,14,13,14,15,17,18,21,20,22,23,22,22,22,23,22,24,23,23,25,23,25,25,26,25,26,24,27,26,25,27,26,25,26,26,26,26,26,25,26,26,24,26,26,25,24,25,24],[28,27,27,28,27,29,28,27,28,27,25,26,27,27,26,26,27,27,26,27,27,27,26,26,26,26,26,26,26,27,25,26,27,28,26,27,27,26,27,26,27,25,25,25,25,25,23,23,25,21,20,22,23,20,19,21,18,17,19,17,16,15,13,12,11,10,10,8,9,7,8,7,7,6,6,6,5,5,5,5,5,4,5,5,4,4,5,5,5,4,4,3,3,3,3,3,2,2,2,2,2,1,1,1,1,0,1,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,3,3,3,2,3,3,4,3,4,4,6,4,4,3,4,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,4,4,5,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,6,6,6,7,6,6,7,7,7,7,7,7,7,6,6,6,5,5,5,4,4,4,4,4,3,4,4,4,4,4,5,4,4,5,5,4,5,5,5,6,6,6,6,5,5,6,5,5,5,6,5,5,6,6,5,5,6,6,6,6,6,6,6,6,6,7,6,6,5,5,6,6,6,6,6,6,6,6,6,6,6,7,6,6,7,5,6,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,9,9,9,9,10,10,10,10,11,11,11,10,10,11,11,9,10,9,9,10,9,9,10,10,11,10,12,12,13,14,14,15,16,17,16,16,20,17,18,19,20,20,21,21,23,24,22,25,26,24,25,27,24,24,24,24,23,24,23,25,25,24,25,25,26,27,26,26,27,27,27,27,27,27,27,27,27,28,27,27,27,28,27,28,27,27,27,27,27,27,27,27,28,27,27,28,26,26,26,25,23,22,23,20,19,18,17,18,16,15,15,14,14,13,12,11,13,12,12,12,13,14,14,13,14,15,15,14,16,17,16,15,17,16,16,15,17,18,18,18,17,16,15,16,15,16,16,17,18,18,18,17,17,17,16,17,16,15,15,16,15,14,14,13,13,13,12,13,13,11,11,11,13,11,11,12,12,11,12,12,12,11,11,12,12,12,12,12,11,11,11,10,9,9,8,7,7,7,7,8,7,7,7,7,7,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,7,8,9,9,9,9,8,7,7,6,6,6,5,5,5,6,5,6,6,7,8,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,8,7,8,8,9,8,8,10,11,10,9,9,10,9,8,9,9,8,8,9,9,8,8,8,9,9,7,8,9,8,8,8,9,8,8,8,8,8,8,7,8,7,7,6,6,6,5,5,5,5,4,4,4,4,4,4,4,5,5,6,6,7,7,7,8,8,8,8,8,8,7,8,8,7,7,7,7,6,6,7,7,7,7,7,7,8,8,8,8,9,9,9,9,10,11,12,11,11,11,10,12,11,10,11,11,11,10,10,10,11,10,9,10,10,9,9,10,9,8,9,8,9,8,8,10,9,9,10,11,10,10,11,11,12,11,12,11,11,12,11,13,12,13,13,12,12,11,12,11,11,12,12,11,12,12,11,11,11,11,11,13,13,13,13,13,14,13,14,13,13,13,14,14,12,13,11,14,12,12,11,12,12,12,11,12,11,11,11,11,11,10,11,11,9,10,10,9,9,9,9,10,11,12,14,15,15,15,17,16,18,19,21,21,21,22,23,21,22,22,23,24,24,23,24,24,24,24,26,25,26,24,26,27,26,27,25,26,25,25,25,26,26,25,26,25,25,26,26,24,23,24,25],[27,27,27,27,27,28,27,27,27,25,26,26,26,26,26,26,25,26,26,25,25,25,25,25,25,25,25,25,25,25,25,25,26,27,24,26,25,24,26,24,25,24,24,24,24,24,23,21,22,21,20,21,21,20,19,19,19,19,18,18,16,16,15,14,13,12,11,10,10,9,9,9,9,9,8,7,7,6,6,7,7,5,6,7,6,5,6,6,6,5,5,5,5,4,3,4,3,3,2,3,3,2,2,2,1,1,0,1,2,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,4,3,4,4,3,4,4,3,4,4,4,6,4,5,4,4,3,4,3,3,3,3,3,3,4,4,3,4,4,4,3,4,3,3,5,4,5,5,6,5,5,5,6,4,5,6,6,5,5,6,6,5,5,6,5,5,5,6,6,6,5,6,5,6,6,6,6,6,7,7,6,7,8,8,8,9,9,8,9,9,9,9,8,8,7,7,7,6,6,6,5,6,5,5,5,6,6,5,6,7,6,6,7,7,6,7,7,7,7,7,7,8,7,7,7,7,7,7,8,6,8,8,8,6,8,8,8,7,7,9,8,7,7,8,9,8,7,7,8,8,8,8,8,8,9,8,8,9,8,8,9,8,8,8,7,8,7,7,7,7,6,7,7,7,7,8,8,7,8,8,8,8,8,8,8,9,9,9,9,10,9,9,11,10,10,11,11,12,11,12,11,12,13,13,13,13,12,12,12,11,11,11,12,11,11,11,12,11,12,14,14,16,16,15,16,17,17,17,18,19,18,19,20,20,20,21,20,22,22,22,23,24,23,24,23,24,24,23,23,23,24,23,24,24,24,22,25,25,26,25,24,26,26,25,26,26,27,27,27,27,26,27,27,27,27,26,27,26,26,26,25,26,25,25,26,26,26,25,26,24,25,24,24,23,21,23,20,19,19,18,18,17,15,17,15,14,14,14,13,15,13,14,15,15,17,15,15,16,16,16,16,17,18,17,16,18,18,17,17,19,19,18,18,17,17,16,16,16,16,16,17,18,18,19,19,18,17,17,17,17,16,17,17,16,15,16,15,14,14,14,15,13,14,13,14,14,13,14,14,14,12,13,14,13,12,13,14,13,13,13,13,12,12,12,11,11,10,10,10,10,9,9,9,10,9,9,10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,8,9,9,9,8,8,8,9,9,9,10,10,10,10,9,9,8,8,8,8,7,7,7,7,7,7,7,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,8,8,7,8,8,8,8,8,9,8,8,9,8,9,9,10,10,9,10,11,10,10,11,11,11,12,11,12,11,12,10,11,11,11,10,10,11,11,10,10,10,11,11,10,11,11,10,10,10,10,10,9,10,10,9,10,9,8,8,8,7,7,7,6,6,6,6,5,5,5,5,4,4,5,5,6,6,7,7,8,8,9,8,8,9,8,8,8,8,9,8,8,8,9,8,8,8,10,9,9,9,10,10,10,9,11,11,11,12,11,12,13,13,13,12,12,12,13,13,13,12,12,12,12,11,12,13,11,11,12,12,11,11,11,10,10,10,11,10,11,10,12,12,12,12,12,13,13,12,14,14,13,13,13,13,13,12,14,13,14,14,14,13,13,14,13,13,14,13,13,14,14,12,13,14,14,13,16,14,14,15,14,15,14,14,14,14,14,13,15,14,13,13,13,13,13,13,13,14,13,12,14,13,13,12,12,13,12,12,12,12,11,11,11,12,11,12,13,12,13,15,16,17,15,17,17,20,20,22,20,23,22,22,22,23,22,22,24,23,23,25,23,24,24,25,24,25,24,26,26,25,26,25,26,26,25,25,26,25,25,25,25,23,25,25,24,23,24,25],[28,28,28,28,28,29,28,28,28,27,27,27,27,27,26,27,27,26,27,26,26,27,26,26,27,26,26,27,26,26,26,27,26,27,27,27,26,26,27,25,27,26,25,25,26,25,24,23,24,23,22,22,22,22,21,21,20,21,19,20,18,18,15,15,14,12,12,12,11,11,11,10,11,10,9,9,9,8,8,8,9,8,9,8,8,8,8,8,8,7,7,6,6,5,5,5,5,5,4,4,4,3,3,2,2,2,1,0,1,2,3,3,4,4,4,4,4,4,4,4,3,4,5,4,4,4,5,3,4,5,5,4,4,6,5,7,5,5,5,4,5,4,4,4,4,4,5,4,5,5,5,6,6,5,5,5,5,5,5,7,7,8,7,6,6,7,6,5,6,7,6,5,6,6,4,5,6,7,5,6,6,6,6,6,7,7,7,7,7,8,8,7,8,8,7,8,9,9,8,9,9,9,10,10,9,10,9,9,8,8,7,7,8,6,6,8,7,6,7,8,7,7,7,9,7,7,9,10,8,8,9,10,9,9,9,9,7,7,8,7,7,8,8,7,8,8,8,7,9,9,8,9,8,9,9,7,8,9,10,9,9,9,9,10,9,10,9,10,10,9,10,9,9,9,9,9,9,9,8,9,9,9,8,8,8,9,9,9,9,9,10,9,9,9,10,9,10,10,10,10,11,11,11,11,11,11,11,12,11,12,12,13,12,13,12,13,14,13,14,13,13,13,13,13,11,12,13,13,12,12,13,13,13,14,14,17,17,16,18,18,18,19,19,19,20,19,20,20,22,22,21,23,24,23,24,25,24,25,25,25,24,25,25,25,25,24,25,25,26,24,26,27,27,26,26,27,27,27,27,28,28,28,28,28,28,28,28,28,28,27,28,28,28,28,27,27,28,27,28,28,27,28,27,27,28,27,26,26,24,24,23,22,21,19,19,18,17,18,16,15,15,14,14,16,14,14,15,15,17,17,17,17,17,17,18,17,19,17,16,18,19,17,18,19,19,18,18,19,18,17,17,17,17,18,17,19,18,19,20,20,18,18,19,19,16,18,18,16,16,17,16,15,14,15,16,16,14,13,14,15,14,14,15,15,14,14,15,14,13,14,14,14,13,14,13,13,13,14,12,13,12,11,12,11,10,10,11,11,9,10,11,9,10,10,11,10,10,10,10,9,10,11,9,10,10,11,9,11,11,10,10,10,10,10,10,10,10,11,11,10,10,9,10,9,9,9,8,9,8,8,8,8,8,9,9,9,9,9,10,9,10,10,9,9,9,9,9,9,9,9,10,10,10,9,10,10,9,10,10,10,9,11,11,9,10,11,11,11,11,12,11,11,12,14,13,12,12,14,12,10,12,13,11,11,12,13,11,12,11,13,13,10,12,12,12,11,12,11,11,11,12,11,11,11,11,11,10,10,10,9,9,8,9,9,9,8,8,8,8,7,7,8,8,9,8,9,9,9,10,10,10,9,10,10,10,10,10,10,10,10,11,11,9,10,11,11,10,11,11,10,11,12,11,12,13,13,12,12,13,14,14,15,15,14,13,15,15,14,14,14,14,14,13,13,15,14,14,14,14,13,13,13,12,12,12,12,12,12,12,13,13,13,14,14,15,14,15,16,15,14,15,15,15,14,15,16,15,16,15,15,14,15,15,15,15,16,14,14,16,16,13,14,15,15,14,17,15,17,16,15,18,16,16,16,16,16,15,17,15,15,14,16,15,14,14,15,15,14,13,15,14,14,13,14,14,13,13,13,12,12,12,12,11,12,13,13,13,14,16,16,17,16,17,18,19,20,22,20,22,22,22,22,23,22,22,23,24,23,25,25,24,25,26,25,26,25,26,26,25,27,26,26,25,26,26,26,25,26,25,25,25,26,25,25,24,25,25],[28,28,28,28,28,29,28,28,29,28,27,27,27,27,27,28,27,27,28,27,27,28,26,27,28,27,26,28,27,27,27,27,28,28,27,28,27,27,27,27,28,26,26,26,27,26,25,24,25,24,24,24,24,22,22,23,21,21,21,20,19,18,17,16,15,13,13,13,13,12,13,11,12,11,10,10,10,9,8,9,11,10,10,9,10,10,9,10,9,10,9,10,8,8,7,8,6,6,5,5,5,4,4,3,2,2,2,1,0,1,2,3,3,5,5,3,3,5,6,5,4,6,5,4,3,5,5,4,5,5,5,4,5,5,6,7,6,6,6,5,5,6,5,4,6,7,5,5,6,6,5,7,7,6,6,7,7,5,6,6,7,7,8,7,8,7,7,6,7,7,6,6,8,8,6,6,7,7,6,7,6,8,7,7,8,8,8,8,9,8,8,9,9,8,9,9,10,10,10,10,11,11,11,12,11,11,11,10,10,10,10,9,9,8,7,8,8,7,8,9,8,8,8,10,8,8,10,11,8,10,10,11,10,9,9,9,8,8,9,8,8,9,9,10,10,9,10,11,10,9,11,11,9,10,9,10,9,9,10,9,9,10,9,10,10,10,10,10,10,10,11,10,10,10,11,11,10,10,9,10,10,10,8,9,9,9,9,10,10,9,10,11,11,10,10,11,11,10,11,11,12,12,12,11,12,13,12,13,13,13,12,15,14,14,13,14,15,15,15,14,15,16,14,14,12,14,15,14,13,14,14,15,16,16,17,18,18,18,19,20,19,21,21,22,22,22,22,23,24,24,24,25,25,25,26,26,26,27,27,26,25,26,26,25,26,25,26,26,27,25,28,27,28,27,27,28,28,27,27,28,28,28,28,28,27,28,28,28,28,28,29,29,28,29,28,28,28,28,29,29,29,29,28,27,28,27,27,25,24,25,22,22,21,19,20,18,17,20,17,16,17,16,16,16,16,16,16,17,20,19,18,19,19,20,18,19,20,20,18,20,20,20,19,21,21,20,20,19,19,19,19,19,18,19,18,20,19,21,22,21,20,19,21,20,18,20,20,19,18,19,18,18,17,16,17,17,17,14,15,18,16,15,16,16,15,16,17,16,15,16,16,17,15,16,16,14,14,14,14,14,13,13,11,11,11,11,12,11,10,12,12,10,10,12,11,11,11,12,10,10,11,12,11,10,11,12,11,11,12,12,10,11,11,12,11,12,12,12,12,12,11,11,11,10,10,10,10,10,10,11,10,12,10,11,11,12,11,11,12,11,11,11,11,11,10,10,11,10,10,10,10,10,11,10,11,10,10,11,11,10,10,11,11,10,11,12,12,11,12,14,13,12,14,15,15,13,14,15,13,11,13,13,13,12,14,14,12,12,12,14,14,12,12,14,13,12,13,13,13,13,13,13,12,12,12,12,12,11,10,10,10,9,10,10,10,10,8,9,9,8,7,8,9,10,9,11,11,11,11,12,11,11,12,12,11,10,11,11,11,11,12,12,10,11,12,12,11,12,12,10,12,13,12,13,13,14,13,14,15,16,16,17,17,16,15,17,16,15,17,17,16,16,14,16,16,15,15,15,16,14,14,15,14,13,14,13,13,12,12,15,14,13,15,16,16,16,16,16,17,16,16,16,17,16,16,17,17,18,17,16,16,16,16,16,16,17,17,16,18,17,16,16,17,17,17,19,17,17,17,17,17,17,18,18,17,18,17,18,17,17,16,16,18,17,16,16,17,16,16,17,16,16,15,16,15,15,15,15,13,14,14,13,12,14,13,13,14,15,17,17,19,19,19,19,20,23,22,23,24,23,25,24,24,24,24,24,25,24,25,26,25,26,27,25,25,26,27,26,25,28,26,26,27,27,26,27,27,27,27,27,26,27,27,26,25,26,26],[29,29,28,28,29,29,29,29,29,28,28,28,28,28,28,28,28,28,28,29,28,29,29,28,28,29,28,29,28,28,28,28,29,29,27,29,28,28,28,28,28,27,27,27,27,27,26,26,27,25,24,25,26,25,24,26,24,24,23,23,22,21,20,20,18,18,17,17,17,18,17,17,16,17,16,15,15,13,12,13,13,13,14,14,13,13,13,14,15,13,13,13,13,11,11,9,9,8,8,7,8,6,7,6,4,4,3,3,1,0,1,3,4,5,6,5,5,7,8,7,6,6,7,5,5,6,6,5,6,7,7,6,8,9,9,11,11,12,11,8,9,11,9,7,10,9,7,7,10,8,8,11,12,9,8,9,8,7,8,10,12,12,12,11,11,12,12,9,10,11,11,11,10,10,8,9,10,10,8,10,10,12,11,9,11,13,12,11,13,12,13,13,13,13,14,14,14,13,13,15,16,14,16,16,16,16,15,15,15,14,14,14,14,15,12,13,15,12,11,13,13,11,13,14,12,11,14,15,13,12,13,15,13,15,12,12,12,12,11,11,11,13,12,11,14,13,13,13,14,12,13,14,14,13,12,12,12,12,13,13,14,14,14,15,14,13,16,14,15,15,16,15,15,15,16,16,15,14,15,15,13,16,13,15,14,13,14,15,15,13,15,15,15,16,15,16,14,16,16,16,17,16,15,17,18,17,19,19,18,19,20,20,18,20,19,18,21,20,20,19,19,20,20,19,18,19,20,20,17,19,19,20,19,19,20,21,22,22,23,23,24,23,23,25,24,24,25,25,26,26,25,27,27,26,28,28,27,28,28,27,27,27,27,27,28,27,28,28,27,28,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,28,29,28,28,27,26,27,22,25,24,22,24,21,20,21,21,21,20,21,20,23,21,21,23,23,24,23,24,23,24,24,24,24,25,25,25,25,26,25,24,26,27,26,26,25,24,23,24,24,24,23,25,26,26,26,26,26,26,25,25,25,24,25,25,24,23,24,24,23,22,22,24,23,23,22,22,22,21,23,21,22,22,22,22,20,21,20,22,22,20,22,20,19,19,20,18,18,19,16,16,17,14,17,17,15,14,17,17,15,16,17,17,16,17,16,17,16,17,18,16,15,17,17,15,16,17,16,15,16,17,17,16,17,16,17,17,17,16,16,15,15,15,14,14,16,14,16,15,15,16,16,16,16,17,15,16,16,16,16,16,16,16,16,15,16,17,16,16,16,16,15,17,17,15,16,17,16,14,17,17,16,17,19,18,18,19,19,19,19,20,21,20,20,21,20,19,20,21,19,19,19,19,19,20,18,20,19,19,19,20,18,19,19,20,17,20,18,19,17,18,18,18,18,17,16,16,15,15,14,14,14,14,13,11,13,13,11,12,12,13,12,14,14,16,16,15,15,15,15,16,15,14,14,15,15,17,16,18,17,16,16,16,18,17,18,19,17,18,19,19,21,19,20,22,21,21,21,22,21,21,21,21,22,21,22,21,21,21,22,20,21,20,19,21,21,20,20,20,19,18,20,17,20,18,20,20,20,19,22,21,21,21,22,20,22,22,21,22,21,22,21,22,22,22,22,22,22,21,22,21,20,21,21,22,21,23,21,20,21,23,22,21,24,22,23,23,22,22,21,22,21,22,22,22,23,22,23,21,22,21,21,20,21,22,21,22,21,22,22,20,22,23,20,21,21,21,20,19,19,21,18,18,18,19,20,21,22,22,21,23,24,24,25,26,25,26,27,27,25,27,26,26,27,26,26,28,27,27,28,28,28,29,28,28,29,29,29,28,29,29,28,28,29,29,28,29,28,28,29,29,28,26,27,28],[29,28,29,29,29,29,29,29,29,28,28,28,28,28,27,27,28,28,28,28,28,28,28,28,28,28,27,28,27,27,27,27,28,28,27,28,28,27,28,27,28,27,27,27,27,26,26,25,26,24,24,25,25,24,23,25,22,23,22,22,21,20,19,18,17,16,16,16,16,17,16,16,15,15,14,14,13,11,11,13,14,11,13,14,13,13,13,14,13,13,11,12,11,12,12,11,10,8,8,8,7,7,7,7,5,4,4,4,3,1,0,1,3,5,6,3,5,6,8,9,7,7,9,8,8,8,9,7,9,10,9,9,10,10,9,11,10,12,10,10,9,11,10,10,10,11,8,11,11,10,9,12,12,8,8,8,8,6,7,10,10,9,9,8,9,9,9,7,10,10,9,11,10,10,10,11,12,11,11,13,11,13,12,11,12,13,12,12,14,12,13,15,14,12,13,13,12,14,14,14,13,15,16,15,16,15,15,15,14,14,12,13,13,13,12,14,14,12,13,14,12,11,14,15,12,12,15,14,12,14,14,14,12,12,12,11,11,10,12,11,11,12,13,12,14,13,14,14,14,13,15,15,14,12,13,12,13,12,12,14,15,15,15,16,14,14,16,15,15,16,16,15,16,15,16,16,15,14,15,16,14,14,14,14,14,14,14,14,15,15,15,14,15,16,15,14,15,17,15,15,16,15,15,17,16,16,18,18,16,17,18,19,17,17,18,17,20,18,19,19,17,17,18,18,17,17,18,17,17,17,18,18,19,19,20,20,21,20,22,22,22,22,22,23,22,23,24,24,24,26,24,26,26,26,26,26,26,27,27,26,26,26,27,27,27,26,27,27,27,25,27,29,28,27,28,28,29,28,28,29,28,29,29,29,28,29,29,29,28,28,29,28,28,28,28,28,28,28,29,28,29,28,29,28,28,27,28,26,25,25,22,23,22,20,22,21,20,21,19,19,19,19,19,21,19,19,21,22,22,21,22,22,23,23,23,23,23,24,23,23,24,23,23,25,25,25,24,24,23,23,23,23,23,22,23,24,24,25,25,24,23,23,24,24,21,23,24,22,22,23,20,21,21,20,22,21,21,21,20,20,19,22,21,20,19,20,19,19,20,20,20,20,20,19,20,19,18,17,17,16,18,16,16,17,15,17,16,17,17,17,16,17,18,16,16,16,17,16,16,18,16,17,16,16,16,16,16,16,16,16,15,16,16,16,15,16,15,15,15,15,15,16,15,16,15,14,14,15,14,15,14,13,14,15,15,15,16,14,15,16,15,15,17,15,16,16,15,16,15,15,16,15,15,16,16,15,15,16,16,16,16,16,17,17,17,18,18,19,18,18,18,18,18,20,19,20,19,18,17,19,19,17,18,19,18,17,19,17,18,18,17,18,18,18,17,18,18,17,18,16,18,16,17,17,18,17,16,16,15,14,15,13,12,14,14,11,11,11,10,12,12,11,13,12,12,12,15,14,15,14,14,16,15,14,14,14,14,15,15,16,16,16,15,16,16,17,16,16,18,17,17,18,18,19,18,18,20,19,19,20,20,20,20,19,20,21,19,19,20,20,19,21,18,20,19,17,20,19,19,18,18,19,18,18,16,18,17,18,18,18,18,19,19,19,20,20,19,21,20,19,20,20,21,20,19,20,20,21,20,21,19,20,20,20,20,20,20,19,21,20,18,20,21,20,20,21,21,21,21,21,22,21,21,20,20,21,20,22,21,21,20,20,21,20,20,21,21,19,19,21,21,19,19,20,21,18,19,20,20,18,18,18,20,18,17,17,19,20,21,21,22,22,22,22,24,25,25,24,26,26,27,25,26,26,27,27,27,25,28,27,27,27,28,28,28,27,28,28,28,29,28,28,28,27,27,28,29,27,28,28,27,28,28,27,25,26,28],[29,29,28,29,29,29,29,28,29,28,27,28,27,28,27,28,27,27,28,27,27,28,28,27,27,27,27,27,27,27,27,28,27,28,27,28,27,27,28,27,27,27,26,26,26,25,25,24,25,22,23,23,23,21,20,22,20,19,20,18,17,16,14,14,12,10,11,10,9,9,9,8,8,7,7,7,7,6,6,6,7,5,7,7,6,6,7,7,7,7,6,7,6,5,5,5,4,4,4,4,3,3,4,4,3,3,4,4,3,2,1,0,1,1,2,3,3,3,5,5,3,3,4,5,4,3,5,5,4,5,6,6,6,7,8,8,7,7,7,7,6,6,6,6,6,5,4,4,4,4,4,4,4,3,3,3,3,3,3,5,5,5,5,4,4,4,5,3,4,5,4,4,4,6,4,4,6,7,6,7,6,6,7,8,7,7,8,8,7,7,8,9,8,8,9,9,10,9,9,9,10,9,10,10,10,10,10,9,9,8,8,8,7,7,7,7,6,7,6,6,6,6,6,7,5,6,6,6,6,6,6,7,6,7,7,8,6,7,7,7,6,6,7,6,7,7,8,8,7,7,9,8,7,8,8,8,9,8,9,8,8,8,7,8,8,7,8,8,8,8,9,9,9,9,9,9,9,9,9,9,8,8,7,7,6,7,7,7,7,7,8,7,8,7,7,8,8,8,8,8,9,9,9,9,10,10,10,11,10,11,10,12,12,12,13,13,14,12,12,12,12,12,11,12,10,11,12,11,11,11,11,12,12,13,14,14,15,15,17,18,17,18,20,20,19,20,21,21,22,24,22,24,25,24,25,26,26,26,25,26,25,25,25,25,25,25,26,25,26,26,27,28,28,27,26,27,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,27,28,27,28,28,27,28,29,27,28,28,27,27,26,26,24,23,23,20,20,20,17,19,16,16,17,14,15,14,13,12,14,13,14,14,15,17,16,15,18,17,18,17,18,19,19,18,20,20,19,19,20,20,20,19,19,19,17,17,18,18,18,19,19,20,20,20,19,21,17,20,18,17,18,18,17,17,17,16,15,14,14,14,15,15,12,13,15,13,13,15,15,14,15,15,15,13,14,15,16,15,15,15,14,14,14,12,12,11,10,10,9,9,9,10,9,9,10,10,9,9,10,10,9,9,10,10,8,9,10,9,8,10,10,8,8,10,9,8,9,9,10,9,10,10,11,11,10,10,9,9,8,9,9,7,8,8,9,9,10,9,9,9,10,9,9,9,9,9,8,8,9,8,8,8,8,8,7,9,8,8,8,9,7,7,8,8,7,7,9,9,8,9,10,9,9,10,11,10,10,11,13,13,11,11,13,12,10,12,12,10,10,12,13,11,11,10,12,12,10,10,12,11,10,11,11,10,10,10,10,10,9,9,9,9,9,8,7,7,6,6,7,6,6,6,5,6,5,5,5,6,7,7,8,8,9,9,9,9,9,10,9,9,9,9,9,9,9,8,8,7,8,9,8,8,10,9,8,9,11,9,10,12,11,10,12,13,12,13,13,14,14,13,15,14,13,13,14,14,14,13,13,14,12,12,13,13,12,11,12,11,10,11,10,10,9,10,12,11,11,12,13,13,13,14,15,15,14,14,15,15,14,14,15,15,16,16,15,14,15,14,14,14,15,15,13,15,15,13,12,15,14,13,16,15,15,14,15,16,15,15,15,15,16,16,16,16,16,14,16,16,15,14,15,16,14,14,16,15,15,14,15,14,14,14,13,12,13,13,12,12,12,12,12,14,15,17,18,18,18,19,19,21,22,23,23,24,24,25,24,24,24,26,25,26,24,26,26,26,27,27,26,27,26,27,27,27,28,26,27,27,27,26,26,27,26,27,27,26,27,27,26,24,26,27],[29,29,29,28,28,29,28,28,28,27,27,26,27,27,27,27,27,27,28,27,27,27,27,27,27,27,27,26,27,27,27,27,28,28,27,28,27,27,28,27,28,27,26,27,26,25,24,23,24,22,22,22,22,21,20,22,19,19,19,17,16,15,13,12,11,10,10,8,8,7,7,6,6,6,5,5,5,4,5,5,5,4,5,5,4,5,5,5,5,5,4,5,4,4,3,4,3,3,3,3,2,2,3,3,2,2,3,3,3,3,1,1,0,1,2,1,1,2,2,3,2,2,2,3,3,2,3,3,3,3,4,4,4,4,5,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,2,3,3,3,2,3,2,2,3,3,4,4,4,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,6,5,5,6,6,7,7,7,7,7,8,7,8,8,7,8,7,6,7,6,6,6,6,5,5,5,4,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,5,6,6,6,6,5,5,5,6,6,5,5,6,6,6,6,6,6,6,7,7,7,6,6,6,5,5,5,5,4,5,5,5,4,5,5,4,5,5,5,5,5,6,5,5,6,7,6,7,7,7,7,8,7,8,8,9,9,8,9,10,10,10,9,10,10,10,9,9,8,8,9,9,8,8,10,10,10,10,12,13,13,14,16,16,16,16,18,19,17,18,20,21,20,21,22,24,24,24,26,25,26,26,26,24,25,25,25,25,25,25,25,25,26,25,27,27,28,26,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,26,27,26,24,23,22,19,20,18,17,17,15,15,15,13,13,12,11,10,10,10,11,10,11,12,13,13,14,14,15,14,16,17,16,15,17,18,16,17,18,17,17,16,16,16,15,15,15,15,16,15,18,17,17,18,17,17,15,17,15,15,15,16,14,14,14,13,14,12,11,12,11,11,9,10,12,10,10,11,12,10,11,12,12,11,11,12,12,12,12,12,11,10,10,10,9,8,7,7,6,6,6,7,6,6,7,7,6,6,7,7,7,6,7,7,6,6,7,7,7,7,7,6,7,8,7,7,7,7,8,8,8,9,9,9,9,8,7,7,6,6,7,5,6,6,6,7,7,6,7,7,8,8,8,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,7,7,6,6,7,6,6,7,7,8,7,8,8,9,7,7,9,9,7,8,9,7,7,8,9,8,8,8,8,9,8,8,8,8,8,8,9,9,9,7,8,9,8,7,7,7,7,6,5,5,5,5,5,5,4,4,4,4,4,3,4,5,5,6,7,7,8,7,8,7,8,8,7,8,7,7,7,7,7,6,6,6,6,7,7,6,7,7,7,7,8,7,7,8,8,7,8,9,8,9,9,10,11,9,10,11,10,10,10,11,10,10,9,10,10,8,9,9,9,8,9,9,8,9,8,8,7,8,8,8,8,9,10,9,9,10,10,10,10,11,11,11,11,11,12,12,11,11,11,11,11,12,11,10,11,12,10,11,12,10,9,10,10,10,12,12,12,12,13,12,12,12,11,12,13,13,14,12,12,10,12,12,11,11,12,12,10,11,12,11,10,11,10,10,10,10,9,9,10,10,8,8,9,9,10,11,12,15,16,17,15,17,16,18,21,21,22,21,23,24,23,22,22,25,24,24,24,25,25,25,26,26,25,26,25,27,27,26,28,26,27,26,26,26,27,27,26,27,26,25,27,27,26,24,26,26],[28,28,28,28,28,28,28,28,28,26,27,27,27,26,27,26,26,27,27,27,26,26,26,26,26,26,26,26,27,26,26,27,27,28,26,27,26,27,27,26,27,27,25,26,26,26,24,23,24,23,23,23,23,22,20,21,19,20,18,19,16,14,12,11,9,8,7,6,6,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,1,1,0,1,1,1,1,1,2,1,1,1,2,1,1,2,2,2,2,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,1,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,5,6,6,6,6,6,6,6,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,4,4,4,4,4,3,3,4,4,3,3,4,4,3,4,4,4,3,4,4,4,4,4,5,4,5,5,5,5,5,5,6,6,6,7,7,6,7,7,7,7,7,8,7,7,7,7,6,7,6,6,7,7,8,9,9,10,13,14,13,15,16,16,16,18,18,18,18,20,20,21,22,22,25,26,22,25,26,26,26,27,24,25,25,26,24,25,26,25,26,26,25,26,27,27,26,26,27,27,27,27,27,28,28,27,28,28,28,27,28,28,27,28,28,28,28,27,27,28,27,27,28,27,27,28,25,26,27,25,24,23,22,21,20,18,17,17,16,15,14,12,11,10,9,8,8,8,8,7,8,9,10,10,10,11,12,12,12,13,12,13,14,15,12,14,15,15,14,15,14,15,14,13,13,12,13,13,14,14,15,15,15,14,14,13,13,12,12,12,11,11,10,10,10,9,9,8,8,7,7,7,8,7,7,7,8,7,8,8,8,8,9,10,10,9,10,10,9,8,8,7,7,6,6,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,4,5,6,5,5,5,5,7,7,7,8,8,8,7,7,5,5,4,5,5,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,6,6,5,5,6,6,6,6,6,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,8,8,6,8,8,7,8,8,8,7,7,8,7,8,7,7,7,7,7,7,6,6,6,6,6,5,6,6,6,6,6,7,6,7,7,7,7,7,8,8,8,8,9,10,10,9,9,9,9,9,9,8,8,9,9,8,8,9,8,7,7,7,8,9,10,10,9,9,9,9,10,10,10,9,11,10,9,10,9,9,10,8,9,9,8,8,9,9,8,7,8,8,7,7,8,7,7,7,7,6,6,7,9,10,11,11,13,14,14,14,14,16,16,18,22,20,23,23,23,22,23,23,22,23,23,23,26,22,25,24,27,25,26,25,27,26,26,27,27,25,25,25,26,27,26,26,26,27,23,26,26,24,25,25,23],[28,28,28,29,28,29,28,29,29,27,27,27,27,26,27,27,28,27,27,28,27,27,27,28,27,27,27,27,28,28,26,28,28,28,26,28,27,28,28,27,28,27,27,27,26,26,25,24,25,23,23,22,23,21,22,22,21,22,19,19,17,16,13,12,11,9,8,8,8,7,7,6,6,6,5,5,4,4,4,5,4,4,4,5,4,5,5,4,5,4,4,4,4,3,3,3,3,2,3,3,2,2,3,2,2,2,3,3,3,3,3,2,1,1,0,1,1,2,2,3,2,2,2,3,2,2,3,3,3,3,4,3,4,4,4,5,5,4,4,4,3,4,3,3,4,3,3,3,3,2,2,3,3,2,2,2,2,2,2,2,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,4,3,4,4,4,4,5,4,4,4,5,5,5,5,5,6,6,6,7,7,7,7,7,8,8,6,8,7,6,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,6,6,6,5,6,6,6,6,6,7,7,8,7,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,9,9,10,10,12,13,14,13,17,17,17,17,18,19,18,18,20,21,20,23,22,23,24,23,25,25,26,25,26,25,25,25,25,24,25,24,25,26,26,26,27,27,28,27,28,28,28,28,29,28,28,28,28,28,28,28,29,28,28,28,28,28,28,28,28,27,28,28,27,28,28,27,27,26,26,25,25,24,22,22,20,20,20,18,18,17,15,15,13,12,11,11,10,11,10,10,10,10,11,11,11,12,12,12,12,12,14,13,13,14,15,13,14,15,15,14,14,15,14,13,13,13,13,14,13,15,14,15,15,16,15,14,14,13,12,13,12,12,12,11,11,11,10,10,10,10,10,9,9,10,9,9,9,9,9,9,10,9,9,10,10,10,10,11,10,10,9,9,8,8,8,7,6,6,6,7,7,7,6,7,6,6,7,7,7,6,7,7,7,6,7,7,6,6,7,6,6,6,7,6,6,7,6,8,7,8,8,9,9,8,8,7,6,6,6,6,6,5,6,5,6,6,6,6,6,7,7,6,6,6,6,5,5,6,6,5,6,6,5,5,6,6,5,6,6,6,5,6,6,6,6,6,6,6,6,7,7,7,7,8,7,7,8,8,8,8,8,8,8,7,7,8,7,7,8,8,7,8,7,8,8,7,7,8,8,7,8,8,8,8,8,8,8,7,7,7,7,6,6,5,5,4,4,4,4,4,3,4,4,3,3,4,4,4,4,5,6,7,7,7,6,7,7,7,7,6,7,7,7,7,7,6,6,6,6,7,6,7,7,7,7,8,7,7,8,8,8,8,8,8,9,9,10,10,9,9,10,9,9,9,9,9,9,9,9,9,8,9,8,9,8,9,9,8,8,8,7,7,7,8,8,8,9,9,9,9,9,9,10,9,9,10,10,10,10,11,11,10,10,10,10,11,10,9,10,10,10,10,9,10,9,9,9,9,9,10,10,11,10,10,11,10,11,11,11,11,12,12,12,11,11,11,11,10,10,11,10,10,10,10,10,8,10,9,9,9,8,9,8,8,8,8,8,8,9,10,11,11,14,14,14,14,15,16,17,19,20,19,22,23,23,21,22,21,23,23,22,22,25,24,24,24,25,23,25,24,26,25,25,26,26,25,26,25,25,26,26,25,26,26,24,25,25,25,24,25,25],[27,28,27,27,27,28,27,27,28,26,25,25,25,25,25,25,26,26,26,26,26,27,26,26,27,26,26,26,26,26,27,26,26,27,26,26,26,26,27,25,27,25,25,25,25,23,23,24,24,21,21,22,21,20,20,21,17,19,19,17,15,15,12,12,10,9,9,8,8,7,7,6,6,6,6,5,4,4,4,5,5,4,4,5,4,4,5,5,5,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,2,1,1,1,0,1,1,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,3,3,3,3,2,2,3,3,2,3,3,3,2,3,3,3,3,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,6,6,5,6,6,6,7,6,7,7,7,7,7,7,7,7,6,6,5,5,5,5,4,5,4,4,4,4,4,4,4,5,5,4,4,5,4,4,4,5,4,5,4,5,4,4,4,4,4,4,4,4,4,5,5,5,4,6,6,6,5,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,5,5,5,4,5,5,5,4,5,6,5,5,6,6,5,6,6,6,6,6,7,7,7,7,7,7,9,8,8,8,9,9,9,9,9,10,9,9,9,9,9,9,8,8,8,8,8,8,8,8,9,9,11,12,12,14,13,15,17,15,15,17,18,16,17,19,19,18,22,20,21,23,23,24,24,25,23,25,24,23,25,24,23,24,24,25,24,25,24,26,26,27,25,26,27,27,26,27,27,27,27,27,27,27,27,27,26,27,26,27,26,27,27,26,26,26,26,27,27,26,27,25,25,25,24,25,22,20,21,18,18,17,16,16,14,13,14,12,11,11,10,9,11,10,11,11,11,12,12,12,13,13,14,12,14,15,14,14,16,15,15,16,17,17,15,15,16,15,13,13,14,13,14,15,16,16,16,16,16,15,15,15,14,13,14,14,12,13,13,11,11,11,10,11,10,11,10,10,11,9,10,11,11,9,10,11,11,10,11,11,11,11,12,11,10,9,9,9,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,7,6,6,7,7,8,7,8,8,9,9,8,8,7,6,6,5,6,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,6,5,5,6,5,5,6,5,5,5,6,6,6,6,6,6,6,7,6,7,7,7,7,8,7,8,8,8,8,9,9,8,9,9,8,8,9,9,8,8,9,9,8,8,8,9,8,7,8,9,8,7,8,8,7,7,7,7,7,7,7,7,6,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,4,4,5,6,6,6,7,7,6,6,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,7,7,6,7,8,7,8,8,8,9,9,9,10,10,10,10,10,9,10,11,10,11,11,11,10,10,10,11,9,9,10,10,8,8,9,8,8,8,7,7,7,7,8,8,8,9,9,10,10,10,10,11,10,10,11,10,11,10,12,11,12,12,11,10,11,11,10,10,11,10,9,10,11,9,9,10,10,10,12,11,11,11,12,12,11,11,11,11,12,12,13,12,12,11,12,12,11,11,12,12,11,11,11,11,10,11,10,10,10,10,10,9,9,9,8,8,8,9,9,11,11,14,15,16,14,16,16,20,20,21,20,22,22,23,22,22,21,23,23,23,21,24,23,23,24,25,24,24,23,25,25,24,26,24,25,24,24,24,25,24,25,25,25,23,25,25,24,22,24,23],[28,28,28,28,28,29,28,28,28,27,27,27,27,27,27,27,27,27,27,27,27,27,26,26,27,27,26,27,27,26,26,27,27,28,27,28,27,27,27,26,27,26,26,26,26,25,24,23,24,23,23,22,23,21,20,21,19,20,18,18,16,14,13,12,10,9,9,8,8,7,7,6,6,6,6,5,5,5,4,5,5,4,5,5,5,4,5,5,5,5,4,4,4,4,3,4,3,3,3,3,2,3,3,3,2,3,4,3,2,3,3,2,2,1,1,1,0,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,6,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,4,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,5,6,7,7,7,7,6,7,7,7,7,8,7,8,7,6,6,6,6,5,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,4,4,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,5,5,5,5,5,6,6,6,6,6,6,6,7,6,6,6,6,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,6,6,7,7,6,7,7,7,7,8,8,7,8,8,8,8,9,9,8,9,8,8,7,8,8,8,9,8,9,9,10,10,12,13,14,14,15,17,17,17,18,19,18,19,20,20,21,22,21,23,24,24,25,26,25,26,26,25,25,25,25,24,25,25,26,24,26,25,26,27,27,26,26,28,27,27,27,27,28,28,28,28,27,27,28,28,28,27,28,28,28,28,28,27,28,27,28,28,28,28,27,25,26,25,25,24,22,23,20,20,19,17,17,14,14,14,12,12,11,10,9,10,9,10,10,10,12,11,11,12,12,13,12,13,14,14,14,15,15,14,15,16,16,15,16,15,15,14,13,14,13,14,14,15,15,15,15,15,14,14,15,13,13,13,13,12,12,12,11,11,10,10,10,9,9,8,9,10,8,8,9,9,8,9,10,9,9,10,10,11,10,11,11,9,9,9,8,8,7,7,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,6,6,6,6,6,6,7,6,6,6,7,7,7,7,7,7,8,7,8,8,9,9,8,8,7,6,6,6,6,6,6,6,6,6,7,6,6,7,7,7,7,6,6,6,6,6,6,6,6,6,5,7,6,5,6,6,5,6,6,6,5,6,6,5,6,6,6,6,7,7,7,7,7,8,7,7,8,7,7,8,8,7,7,7,7,7,7,8,8,7,7,8,8,8,7,8,8,7,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,5,5,4,5,5,4,3,4,4,3,3,4,4,5,5,6,6,7,7,7,7,7,7,7,7,7,7,7,6,6,6,7,6,6,6,7,6,7,7,6,7,7,7,7,7,7,8,8,8,9,9,9,9,9,9,9,9,9,10,10,10,9,9,9,9,9,8,9,9,8,8,8,8,8,7,8,7,7,7,8,8,8,8,8,8,9,9,9,10,9,10,11,10,10,10,11,12,11,12,11,11,11,10,10,10,10,10,10,10,10,9,9,10,10,9,11,11,11,10,11,11,11,11,11,11,12,12,13,11,11,10,11,11,10,10,11,10,10,10,10,9,9,9,9,9,9,9,8,8,8,8,8,8,8,9,10,10,11,13,14,15,14,15,16,18,20,22,20,22,22,22,22,22,22,22,23,23,23,24,23,25,25,26,25,25,25,26,26,25,27,25,26,26,26,26,26,25,26,25,26,24,26,26,24,24,25,24],[28,28,27,27,28,28,28,27,28,27,26,26,26,27,26,26,25,27,26,26,27,27,27,26,27,26,26,27,26,26,26,26,26,27,26,27,26,26,27,25,27,25,25,26,25,25,24,23,23,22,22,23,22,21,20,20,19,20,18,18,17,16,13,12,11,10,9,9,8,7,8,7,7,7,6,7,6,5,5,6,6,5,6,6,5,5,6,6,6,5,5,6,5,5,4,5,4,4,4,4,4,3,4,3,3,3,4,3,3,4,3,2,2,2,2,1,1,0,1,2,1,2,1,2,2,2,3,3,3,3,4,4,4,5,5,6,6,5,5,5,4,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,4,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,3,3,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,6,7,7,7,7,8,8,8,8,8,8,8,7,6,6,6,6,6,5,5,5,5,4,5,5,4,4,5,4,4,4,5,4,4,4,5,5,5,5,5,4,3,4,3,3,4,4,3,4,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,5,5,6,6,5,6,6,6,6,7,7,6,7,7,7,7,7,7,7,6,6,7,6,6,5,5,6,6,5,6,6,5,5,6,6,5,5,6,6,6,7,7,6,7,7,7,7,8,7,7,7,8,8,8,8,9,9,9,9,9,9,9,10,9,8,8,9,9,9,9,9,10,10,11,12,13,15,14,16,17,17,17,18,19,18,17,19,20,20,21,22,23,23,23,24,24,24,25,26,24,24,25,25,24,25,23,25,26,25,24,26,26,27,25,27,27,28,26,27,27,27,28,27,27,28,28,28,28,28,27,28,28,27,27,27,27,27,27,28,28,27,27,27,26,26,26,26,24,22,22,18,19,18,16,17,15,15,15,12,12,10,10,10,10,9,10,10,11,12,11,12,13,12,13,12,13,15,14,14,15,16,15,16,17,18,17,17,16,16,14,15,13,13,14,14,14,17,17,17,16,16,14,16,13,13,14,13,12,12,13,11,11,10,10,10,10,9,9,9,11,8,9,10,10,9,9,10,10,9,10,11,11,11,11,10,9,9,9,8,8,7,7,7,6,6,6,6,6,6,7,6,6,7,7,7,7,7,7,7,7,7,8,7,7,7,7,7,7,8,8,7,8,8,9,8,9,9,10,10,9,8,7,7,7,7,7,6,6,7,7,7,7,7,8,7,7,8,7,7,8,7,7,7,7,7,7,7,8,7,6,7,7,7,7,7,7,6,7,7,6,6,7,7,6,7,8,7,7,7,8,8,8,7,8,9,7,8,9,8,8,8,8,8,8,9,9,8,9,8,9,9,8,9,9,9,9,9,9,9,9,8,8,8,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,6,4,4,5,5,6,6,7,7,8,8,8,7,8,8,8,8,9,8,8,7,7,7,7,6,7,7,7,7,8,7,7,8,9,8,8,9,8,8,9,9,9,10,9,10,10,9,10,11,10,11,11,10,10,10,10,10,10,9,10,10,10,9,9,9,9,8,9,8,8,8,9,9,9,9,10,9,10,10,10,10,10,11,11,11,11,11,12,12,12,11,12,12,12,12,11,11,11,11,10,11,11,10,10,10,9,10,11,11,12,12,12,12,11,12,11,12,13,12,14,12,12,11,12,12,11,11,12,11,10,11,11,10,10,10,10,9,9,9,9,8,9,8,8,8,8,9,9,10,12,14,14,16,14,15,16,19,20,23,20,23,22,23,22,24,22,23,23,23,23,25,24,26,26,26,26,26,25,26,27,26,26,26,26,26,26,26,26,27,26,26,26,25,26,26,25,23,25,24],[30,29,29,29,29,30,29,29,29,29,28,28,28,27,28,28,28,28,28,28,28,28,29,28,28,28,28,28,28,28,28,29,29,29,28,29,28,28,28,28,28,28,27,28,27,27,25,24,26,24,24,24,25,24,22,23,21,21,19,19,17,16,14,12,11,9,8,8,8,7,7,6,6,6,5,5,5,4,4,5,5,4,5,5,4,4,5,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,2,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,6,7,6,7,7,7,7,8,8,8,7,6,6,6,5,5,5,5,4,5,5,4,4,5,4,3,4,4,4,3,4,4,4,3,4,4,4,5,5,4,3,3,4,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,4,5,6,6,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,4,5,5,5,5,5,6,5,5,5,6,5,5,6,5,6,6,6,5,6,7,8,7,7,8,8,7,8,9,9,8,9,9,9,10,9,9,9,10,8,8,9,9,9,9,9,10,10,11,10,11,13,13,14,17,17,18,18,19,20,19,19,21,22,22,23,23,26,26,25,26,28,27,27,28,25,27,26,26,25,26,26,26,27,26,26,28,28,29,27,28,28,28,28,28,28,27,28,27,28,28,28,29,28,28,28,29,28,28,28,28,28,28,28,27,28,28,28,28,27,27,27,26,26,24,24,20,21,20,18,19,17,15,16,13,12,11,10,10,11,10,9,11,9,11,11,11,11,11,12,11,12,13,13,12,13,15,14,15,17,17,15,16,15,15,13,13,12,13,13,14,13,14,15,15,15,15,13,13,12,12,11,11,12,11,10,10,11,11,9,10,10,9,9,9,9,8,9,9,9,9,9,9,9,9,9,10,10,10,10,10,9,9,9,8,8,7,7,6,6,5,6,6,5,6,6,6,6,6,6,6,6,7,6,6,6,7,6,6,6,6,6,6,6,7,6,6,6,7,7,7,8,8,9,9,8,7,6,6,6,6,6,5,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,7,7,7,6,7,7,7,7,8,7,7,8,7,7,7,7,7,7,7,7,8,7,7,7,7,8,7,8,7,7,7,7,8,8,8,8,8,7,7,7,7,7,7,6,6,6,5,5,5,5,5,4,5,5,4,4,5,5,6,6,6,7,7,8,8,7,7,8,8,8,7,7,8,7,7,6,7,6,6,6,7,6,7,7,7,7,7,7,7,7,7,8,8,8,8,9,8,9,8,8,9,9,8,9,9,9,9,9,8,9,9,8,8,8,9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,8,9,9,9,9,9,10,9,10,9,11,11,11,10,11,10,10,10,10,10,10,9,9,10,10,9,9,10,10,9,11,10,10,10,10,11,10,10,10,11,11,12,12,11,11,10,11,10,10,10,10,10,8,9,9,9,8,9,8,9,8,8,9,8,8,8,8,7,7,9,10,11,11,13,14,14,14,15,16,17,19,21,20,24,25,23,23,24,23,25,25,25,25,26,25,27,27,28,26,27,27,27,27,27,29,26,27,28,27,26,27,27,28,27,28,27,28,27,26,26,28,27],[28,29,27,28,27,28,28,28,28,27,26,27,26,26,26,26,26,26,27,26,26,26,26,25,27,26,25,26,26,25,26,27,26,27,26,27,25,26,26,25,26,26,25,25,26,25,24,23,23,22,22,21,21,22,19,20,19,19,18,18,17,15,14,12,10,9,8,8,7,7,6,6,5,5,5,5,4,4,4,5,5,4,5,5,4,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,2,2,2,2,1,1,0,1,1,1,1,1,2,1,2,2,2,2,2,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,2,3,2,3,2,2,2,2,2,2,2,3,3,3,3,4,4,3,4,4,4,5,5,5,5,6,6,6,6,7,6,7,7,7,7,7,7,6,6,5,5,5,5,5,4,5,4,4,3,4,4,3,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,4,5,6,6,5,5,4,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,7,6,6,7,7,7,8,7,8,8,8,8,8,8,8,8,8,7,7,8,8,7,8,8,9,9,10,11,13,14,14,16,17,16,16,18,18,17,18,19,20,21,21,20,22,23,23,23,24,23,25,25,23,24,24,25,24,24,23,25,25,24,23,25,26,26,25,26,27,27,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,26,27,26,27,27,27,27,28,27,27,26,26,27,26,25,25,23,23,20,19,18,16,17,14,14,14,12,11,10,10,9,10,9,10,10,9,10,10,11,11,11,12,12,12,13,12,13,14,14,14,15,16,16,15,15,14,14,12,12,12,11,12,12,14,14,15,15,15,15,14,14,12,12,12,12,11,11,11,9,9,9,9,9,9,8,8,9,9,8,8,9,9,8,8,9,9,8,9,10,9,10,10,9,9,9,9,7,8,7,6,6,5,5,6,6,6,6,6,6,6,6,7,6,6,7,6,6,7,6,7,6,7,6,7,6,7,7,7,7,7,7,8,7,8,8,9,9,8,7,6,6,6,6,6,5,6,6,6,6,6,7,7,7,7,7,7,6,7,7,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,7,7,6,6,7,7,7,7,7,8,8,7,7,8,7,8,7,7,7,7,8,8,7,8,8,8,8,8,8,8,8,8,8,9,8,8,8,8,7,8,7,7,7,6,6,6,5,5,5,5,4,5,4,4,5,4,4,4,5,5,6,6,7,7,8,7,7,7,8,7,7,7,7,7,6,6,6,6,5,6,6,6,6,7,7,6,7,7,7,7,8,7,7,8,8,8,9,8,9,9,8,9,9,9,9,10,9,10,9,9,9,10,9,9,9,9,8,9,8,8,7,7,7,7,7,8,8,8,8,9,8,9,9,9,9,9,9,10,10,10,10,11,11,11,10,11,11,10,10,10,10,10,9,9,10,10,8,9,9,9,9,10,10,11,9,10,11,10,10,10,11,10,11,12,10,11,10,11,10,10,10,10,10,9,9,9,9,9,9,9,8,8,8,8,8,7,7,7,8,7,8,9,10,10,12,13,14,13,13,14,16,17,19,18,22,22,21,20,22,20,22,23,23,23,24,23,23,26,25,24,25,24,25,25,25,26,24,25,26,25,23,26,25,26,25,25,25,25,26,25,24,25,26],[28,28,27,28,27,28,27,26,29,26,25,26,25,26,25,26,25,26,26,25,26,26,26,25,27,26,25,27,26,26,26,26,26,27,26,26,26,26,27,26,27,26,25,25,25,25,24,23,24,22,22,20,21,20,19,20,18,18,18,17,15,14,12,11,9,8,7,6,6,5,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,6,6,5,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,3,3,3,4,3,3,3,4,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,6,6,6,6,6,6,6,7,7,8,9,10,12,13,12,14,15,15,15,16,16,16,17,18,18,20,21,18,21,23,22,23,25,24,25,24,25,23,24,24,24,23,24,24,24,24,24,25,26,26,25,25,27,26,27,26,27,27,28,27,27,26,27,27,27,27,27,28,28,27,28,27,27,27,27,27,28,27,27,27,26,26,26,26,25,22,22,21,19,19,16,16,14,13,13,11,10,9,9,8,8,8,8,8,8,8,9,9,9,10,11,10,11,12,11,12,14,13,12,14,14,15,14,13,13,13,11,11,11,11,11,12,13,13,14,14,14,13,12,13,12,11,11,11,10,10,10,9,9,8,8,8,7,7,7,7,8,7,7,7,8,6,7,8,8,7,8,8,8,8,8,8,8,7,7,6,6,5,5,5,5,4,4,4,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,6,6,6,6,7,7,6,6,5,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,6,6,5,5,6,6,5,6,6,5,5,6,6,5,6,5,6,7,5,6,6,6,5,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,5,5,5,6,6,6,5,5,6,6,6,6,5,6,5,5,5,5,4,4,5,5,4,5,5,5,5,6,5,5,6,6,6,6,6,7,7,7,7,7,7,7,8,7,7,8,8,7,8,7,8,8,7,7,8,7,6,7,7,5,6,6,6,6,6,6,6,6,6,7,7,7,7,8,8,7,8,8,8,8,8,10,10,9,9,10,9,9,10,9,8,9,9,8,9,9,8,7,8,7,8,9,9,9,8,9,9,9,9,9,9,9,10,10,9,9,8,9,9,8,8,9,8,7,7,8,7,7,8,7,6,6,7,6,6,6,6,5,6,6,7,7,8,9,11,11,13,11,12,13,15,15,18,17,20,19,18,20,21,19,19,20,21,19,24,22,22,23,24,23,24,23,24,24,24,26,23,24,24,24,24,24,24,23,23,24,23,25,24,23,22,23,24],[29,29,29,29,29,29,29,28,29,28,27,27,27,26,27,27,27,27,27,27,26,27,26,26,27,27,26,26,27,26,26,28,27,28,27,28,27,28,28,27,27,28,27,27,26,26,25,23,25,23,23,22,23,22,20,21,21,19,18,18,16,14,12,10,9,8,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,1,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,3,3,2,2,3,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,7,7,8,8,9,10,11,12,13,13,14,15,16,18,17,17,19,19,21,22,20,23,25,23,24,26,25,26,26,24,25,25,24,24,25,24,26,25,26,26,25,27,27,26,27,28,27,27,28,27,27,28,28,28,28,28,28,28,28,28,28,29,28,28,28,28,28,28,27,29,28,27,29,26,27,27,25,26,24,22,22,21,19,17,17,16,14,13,11,10,9,7,7,7,7,7,7,7,8,8,8,8,8,9,9,10,11,10,10,11,12,11,12,14,14,12,13,12,12,11,11,10,9,10,11,11,12,13,13,12,12,11,11,10,10,9,9,9,9,8,8,8,7,7,7,6,6,5,6,6,6,5,6,7,6,6,7,6,6,7,7,7,7,8,8,7,6,6,5,5,5,4,3,3,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,5,5,6,6,7,7,6,6,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,4,3,3,4,4,3,3,4,4,4,4,5,4,4,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,5,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,2,3,3,3,3,3,3,4,4,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,5,4,4,4,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,7,8,8,7,8,7,6,7,8,7,6,6,6,7,7,8,8,7,8,8,7,8,8,9,8,9,9,8,8,7,8,8,7,7,7,7,6,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,7,9,9,11,12,12,12,13,14,14,17,19,19,21,22,22,20,22,21,23,24,22,23,24,22,25,24,27,25,26,25,27,26,26,27,26,26,26,24,25,26,25,25,25,26,25,26,26,24,24,25,25],[29,29,29,29,29,29,29,28,28,28,27,27,27,27,28,27,27,27,27,27,27,27,27,27,27,27,27,27,28,26,26,28,27,28,27,28,26,28,27,27,28,27,25,27,26,26,25,24,24,23,23,23,23,22,20,21,19,19,18,17,15,14,12,10,9,7,6,6,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,1,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,6,5,5,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,3,2,2,2,3,2,2,3,3,3,3,4,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,4,3,3,4,4,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,7,7,8,9,10,11,12,13,14,15,14,16,18,16,17,19,19,20,21,20,22,24,23,25,25,25,25,26,24,24,25,24,22,25,23,24,25,25,24,26,25,26,25,26,26,27,27,27,27,27,27,27,27,27,27,28,28,28,27,28,28,28,27,27,27,27,28,27,28,27,27,28,26,27,26,25,24,23,24,19,20,19,16,17,15,13,14,10,10,8,7,7,7,7,7,7,7,7,8,8,8,8,9,8,9,9,9,9,10,10,10,10,12,11,11,12,10,11,10,9,9,9,10,10,10,11,12,10,11,11,10,9,9,9,9,9,9,8,8,7,7,7,6,7,6,6,6,6,6,6,6,6,7,6,6,6,6,6,7,7,7,7,8,8,7,7,7,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,4,5,5,4,4,5,5,5,5,5,6,5,6,7,7,7,6,6,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,6,5,5,5,6,5,5,6,5,6,5,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,6,6,5,5,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,6,7,7,7,7,7,8,8,8,8,8,8,7,8,7,7,8,7,6,7,7,6,6,6,6,6,7,7,8,7,7,8,7,8,8,8,8,8,9,7,8,7,8,8,7,7,7,7,6,7,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,6,7,9,8,10,11,11,11,12,13,14,16,17,19,20,21,19,18,21,20,21,22,22,22,22,23,24,24,25,24,25,25,24,25,24,26,24,25,25,24,23,25,25,26,24,24,24,24,25,24,22,25,25],[28,27,27,27,27,28,27,26,27,26,25,24,24,25,24,25,25,25,25,25,25,26,25,24,26,24,23,25,24,23,25,25,25,25,25,25,24,25,25,24,25,24,23,25,24,24,23,21,22,20,20,19,19,20,18,17,18,17,16,16,14,13,12,10,9,8,7,7,6,5,5,5,4,4,4,4,3,3,3,4,3,3,4,4,3,3,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,5,5,4,4,4,3,3,3,2,3,3,2,2,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,6,7,7,6,7,7,7,6,6,6,6,6,6,6,6,7,7,8,9,10,11,12,12,13,15,15,14,16,15,15,16,16,17,18,18,17,20,20,20,21,22,23,22,22,22,21,23,23,22,22,22,23,23,22,22,26,25,25,24,24,26,25,26,25,25,25,25,25,26,26,26,27,26,27,27,26,25,26,25,27,25,27,26,26,26,26,26,26,25,26,25,24,23,22,22,20,18,17,16,15,13,12,12,10,9,8,8,7,7,7,8,7,8,8,8,9,9,9,9,10,10,11,10,11,12,11,11,12,13,13,12,12,11,11,10,10,9,9,10,10,11,12,13,13,13,12,11,12,10,10,10,10,9,9,9,8,8,8,7,7,7,7,6,7,7,6,6,7,7,6,6,7,7,6,7,8,7,7,7,7,7,7,7,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,6,6,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,6,5,5,5,6,6,5,6,6,6,6,6,6,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,5,5,5,6,6,5,6,6,6,6,6,6,6,5,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,6,7,7,7,7,7,8,7,7,7,7,7,7,7,7,7,6,7,7,6,6,6,5,5,6,6,6,6,7,7,6,7,7,7,7,7,8,7,8,8,8,9,9,9,8,9,9,8,8,8,8,8,8,8,8,8,7,7,7,7,7,8,8,8,8,8,8,8,9,8,9,8,9,9,8,8,8,8,8,7,7,8,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,5,6,6,7,7,8,9,10,11,12,10,11,12,14,15,17,16,20,19,17,18,19,18,18,21,20,20,22,20,23,22,24,23,24,22,24,24,23,25,23,24,24,24,23,24,24,24,24,23,23,23,24,22,22,24,24],[28,28,28,29,28,29,28,27,28,27,26,27,26,26,26,26,26,26,27,26,26,27,26,26,26,26,25,26,26,26,25,27,27,28,26,27,26,27,27,27,27,27,26,26,26,26,25,23,24,23,22,22,23,22,19,21,19,18,17,18,15,14,12,10,9,7,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,1,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,3,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,5,5,5,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,3,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,7,6,6,6,5,6,6,6,6,6,6,7,7,8,9,11,12,12,13,14,16,14,16,17,17,16,17,18,20,21,19,23,25,23,24,26,25,25,26,24,24,25,25,23,24,24,26,26,26,26,26,27,28,26,26,28,28,28,28,28,28,29,29,28,28,28,28,28,28,28,28,29,28,29,28,27,28,28,28,29,28,28,28,26,27,27,25,25,24,22,21,20,19,18,17,14,13,13,11,10,9,8,8,7,7,7,7,8,8,8,8,8,9,10,9,10,12,10,10,12,12,12,12,13,14,13,13,13,12,11,11,10,10,11,11,12,12,13,13,12,12,11,12,11,10,10,11,10,9,9,8,8,7,7,7,6,6,6,6,6,6,6,6,7,6,6,7,7,7,7,7,7,8,8,8,8,7,7,6,6,5,5,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,5,5,6,6,7,7,6,5,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,6,5,6,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,6,6,5,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,6,6,6,6,6,7,6,6,7,7,6,7,6,6,7,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,6,6,6,6,6,7,7,6,7,7,7,7,8,9,9,8,8,8,8,8,9,8,7,8,7,7,7,8,7,6,7,6,7,7,8,8,8,8,8,8,8,8,9,8,9,9,8,8,8,8,8,7,7,8,7,6,6,7,6,6,6,6,5,6,6,6,5,5,5,5,5,5,6,7,8,8,10,11,12,11,12,13,15,17,18,18,21,22,20,20,20,21,21,23,22,23,24,22,25,24,26,25,25,24,26,26,24,27,25,25,26,25,25,26,25,25,25,26,25,26,25,23,23,25,24],[29,29,29,29,29,29,29,28,29,28,28,27,27,27,27,27,27,27,27,27,26,27,27,27,27,27,27,27,28,26,26,28,28,28,27,28,27,28,28,27,28,27,26,27,26,26,25,24,25,24,22,23,23,22,21,21,20,19,19,18,16,15,12,10,9,8,7,6,6,5,5,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,3,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,4,4,5,4,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,3,3,3,3,2,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,5,5,6,6,5,6,6,6,6,6,6,7,7,6,6,6,6,6,6,6,7,7,7,8,8,9,11,12,12,13,14,15,14,17,18,16,17,19,19,20,21,21,23,23,23,24,25,26,26,26,24,25,25,24,25,25,25,26,25,25,25,26,27,28,26,27,28,27,27,27,27,28,28,28,28,28,28,28,28,28,28,29,28,28,28,28,27,28,29,27,28,28,27,28,26,26,27,25,25,23,22,20,20,18,17,17,15,13,12,11,10,9,8,8,8,8,7,7,8,7,8,9,8,8,9,9,9,10,10,10,11,11,11,11,13,12,12,12,11,11,10,10,10,10,10,10,11,11,13,12,12,11,11,10,10,9,9,9,9,8,8,8,8,8,7,8,7,6,6,6,7,6,6,6,7,6,6,7,7,6,7,7,7,8,8,8,8,7,6,6,5,4,4,3,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,4,4,5,5,6,5,6,6,7,7,6,5,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,5,6,6,5,6,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,5,5,6,6,6,6,6,5,5,5,5,4,4,5,5,4,4,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,7,6,6,7,7,6,6,7,7,6,7,6,7,7,6,6,7,7,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,7,7,7,6,7,8,7,7,8,8,8,8,8,8,8,8,8,8,7,8,7,7,7,8,7,7,7,7,7,8,8,8,7,8,8,8,8,8,8,8,9,9,8,8,7,8,8,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,5,6,5,5,5,5,6,7,8,8,10,11,11,11,12,13,14,17,17,18,21,21,20,19,21,21,20,24,21,23,24,23,25,25,25,25,26,25,26,26,26,27,25,26,26,24,25,27,26,26,26,25,25,26,26,24,23,26,24],[29,29,28,28,28,28,29,28,28,27,27,26,27,25,25,26,26,27,27,27,27,26,27,26,26,26,26,26,26,25,25,27,26,27,25,26,25,26,26,25,26,25,25,25,24,24,23,22,23,21,21,19,21,19,18,19,18,17,17,17,14,13,11,10,9,7,6,6,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,7,7,8,9,11,12,12,13,14,14,13,15,15,15,16,17,17,18,19,18,21,21,21,23,23,23,23,24,22,21,23,23,22,22,23,22,23,23,23,25,25,24,23,25,26,26,26,26,26,26,26,26,26,26,27,27,26,26,26,27,27,27,26,26,26,27,26,26,27,27,27,27,26,26,26,24,24,23,23,19,19,17,15,16,14,12,12,10,9,8,7,6,6,6,7,6,7,7,7,8,7,8,8,8,9,9,9,9,10,10,10,10,12,12,12,11,10,10,9,9,9,9,9,10,10,10,12,12,11,11,10,10,9,9,9,9,9,8,8,7,7,7,6,6,6,6,5,6,6,5,6,6,6,6,6,6,6,6,6,7,7,7,8,7,7,6,7,5,5,5,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,6,6,7,7,7,6,5,4,4,4,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,3,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,2,3,3,3,3,3,4,4,4,5,5,5,6,6,5,5,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,6,6,6,6,6,5,6,7,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,7,7,8,8,7,7,8,8,7,8,7,7,7,7,7,6,7,6,6,6,6,7,7,7,7,7,7,7,7,8,7,8,7,8,8,7,8,7,7,7,7,6,7,6,6,6,6,6,6,6,5,6,5,5,6,5,5,5,5,5,5,6,7,8,8,10,11,11,10,12,13,14,15,16,17,20,20,19,18,19,19,19,21,21,21,23,21,23,24,24,22,26,23,25,25,25,25,24,25,25,24,23,25,25,25,24,24,24,24,25,24,23,24,23],[28,28,28,28,27,28,27,27,28,26,25,25,25,26,25,26,25,25,26,25,25,26,25,25,26,25,24,26,25,25,25,25,25,26,26,26,26,26,26,25,26,25,24,24,24,24,23,21,22,21,20,20,20,20,18,19,18,17,17,16,14,13,12,11,9,8,7,7,6,6,5,5,5,4,4,4,4,3,3,4,3,3,4,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,6,6,7,7,8,9,10,12,12,12,13,14,15,14,15,16,15,15,17,17,18,18,18,19,20,20,21,23,22,21,24,22,22,22,23,21,22,22,23,23,23,23,25,25,26,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,27,26,26,27,27,27,27,26,26,26,27,27,27,27,26,26,26,25,24,24,23,22,20,19,18,16,16,14,13,13,11,10,9,8,8,8,8,8,7,8,8,8,8,8,9,9,10,10,11,10,10,12,11,11,11,12,12,12,12,12,10,10,10,10,10,11,10,12,12,12,12,12,11,11,11,10,10,10,10,10,9,9,9,8,8,7,8,7,7,7,7,7,6,7,7,7,6,7,7,7,7,7,7,7,7,8,8,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,5,4,4,5,5,4,4,5,4,4,5,5,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,7,7,6,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,6,5,5,5,6,5,6,5,6,6,5,5,5,6,6,5,5,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,7,7,6,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,7,7,6,7,7,7,7,7,8,8,7,8,7,8,8,8,8,8,9,8,9,8,8,8,8,7,8,8,8,7,7,7,7,8,8,8,8,8,9,8,9,8,8,8,9,9,8,8,8,8,8,7,7,8,7,7,7,7,6,6,7,6,6,6,6,6,6,6,5,6,6,6,6,7,8,8,10,11,11,10,11,12,14,15,16,16,20,19,18,18,20,19,19,20,20,20,23,20,22,22,24,24,24,22,25,24,23,25,24,24,24,23,23,24,25,24,24,24,23,23,24,22,21,23,23],[29,29,29,29,28,29,29,28,29,28,27,27,27,26,27,27,27,26,26,27,26,26,27,26,26,27,27,27,27,26,25,27,27,28,27,28,27,27,28,27,28,27,26,26,26,26,24,23,25,23,22,22,23,21,20,21,20,19,18,18,16,14,12,10,9,8,7,6,6,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,4,4,4,4,4,4,4,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,6,6,6,6,7,7,6,7,7,8,9,9,10,12,12,12,14,15,16,15,17,18,16,17,19,20,20,21,21,22,24,24,24,26,26,26,27,25,25,26,26,24,25,25,26,26,26,26,27,27,28,27,27,28,27,28,27,28,28,28,28,28,28,28,28,28,28,28,29,29,28,28,28,27,28,28,28,28,28,28,28,25,27,27,25,24,24,22,21,21,19,18,17,16,14,13,12,11,10,8,8,7,8,8,7,8,8,8,9,9,9,10,10,10,12,10,10,12,13,11,12,14,13,12,13,12,12,11,11,11,11,12,12,13,13,14,13,12,12,13,12,11,10,10,10,10,9,9,9,9,8,8,7,7,6,6,6,7,6,6,6,7,6,6,7,7,7,7,7,8,8,8,8,8,7,7,6,6,5,4,4,4,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,5,4,4,5,5,6,5,6,7,7,7,6,5,4,4,4,4,3,3,3,3,4,4,4,4,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,6,6,6,5,6,6,6,6,6,6,5,5,5,4,4,4,5,4,4,5,5,4,4,5,5,4,5,5,5,5,6,6,6,6,7,6,5,6,7,6,6,7,7,6,7,6,7,7,6,6,7,6,6,6,6,6,6,6,6,5,5,6,6,5,6,6,6,6,7,7,7,7,7,8,7,8,8,8,9,8,8,8,8,8,8,8,8,8,7,7,7,8,8,7,7,7,8,8,8,9,8,8,8,8,9,8,9,8,9,9,8,8,8,8,8,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,5,6,5,5,5,6,6,8,9,9,11,12,12,12,13,15,16,19,20,19,22,22,22,21,21,22,22,25,22,24,25,23,26,24,26,26,26,25,27,26,26,26,26,26,26,24,26,27,26,26,27,27,25,27,26,24,24,25,25],[29,29,29,29,29,29,29,28,29,28,27,27,27,26,27,27,27,27,26,27,26,27,27,27,27,27,26,27,28,26,26,27,27,28,27,28,26,27,28,27,28,27,26,26,26,26,25,24,25,23,23,23,23,22,20,21,20,20,19,18,16,15,12,11,10,9,8,7,7,6,6,5,5,4,4,5,4,4,4,4,4,3,4,4,3,3,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,5,5,5,5,5,6,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,4,4,3,4,4,4,3,4,4,4,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,7,7,6,8,8,7,7,7,8,8,9,9,10,12,12,13,14,16,16,15,17,18,17,18,20,20,21,20,21,24,24,24,25,27,26,26,27,25,25,26,24,24,25,26,25,25,25,26,26,27,27,26,27,27,28,28,27,28,27,28,28,28,28,28,28,28,28,28,29,28,28,28,28,26,29,28,27,28,28,28,28,25,27,27,26,25,25,24,22,21,20,19,18,16,15,13,12,11,10,9,9,9,8,8,8,9,9,9,10,9,9,10,10,10,11,10,10,11,13,12,12,14,13,13,14,12,11,11,11,11,10,11,11,12,13,14,14,13,12,12,12,11,10,10,10,10,10,9,9,9,8,8,8,8,7,7,8,8,7,7,8,8,7,7,8,8,8,8,8,8,9,9,9,9,8,8,6,6,6,5,4,4,4,5,5,4,4,5,5,4,4,5,5,4,5,5,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,6,6,7,7,7,7,6,6,5,5,5,5,4,4,4,4,4,4,5,5,5,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,5,4,4,5,4,4,5,5,5,4,5,5,5,6,6,6,5,6,7,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,3,4,4,3,3,4,4,4,5,5,5,6,7,7,6,6,7,7,6,6,6,6,6,6,5,5,5,5,5,5,5,6,6,5,5,6,6,6,6,6,7,7,7,7,8,7,7,7,7,7,7,7,7,8,8,7,7,8,8,8,7,7,7,8,7,7,7,6,7,7,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,10,9,9,9,9,8,9,9,8,9,9,8,9,9,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,10,10,9,9,8,9,9,8,8,8,7,7,7,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,7,8,9,9,11,12,12,11,12,14,15,18,17,19,20,21,20,19,20,22,20,23,21,22,23,22,25,24,25,25,25,23,26,25,25,25,25,26,25,23,25,26,25,26,26,26,25,25,26,24,24,25,25],[28,28,27,28,28,28,28,27,27,26,26,25,25,26,25,26,25,26,25,25,26,26,25,25,26,25,24,25,25,24,25,26,25,26,25,25,25,25,25,25,26,25,24,24,24,23,24,22,21,21,21,20,20,20,19,18,18,17,17,16,15,15,12,11,10,9,8,8,6,7,6,6,5,5,5,4,4,4,4,4,4,3,4,4,3,4,5,5,4,4,4,4,3,3,3,3,2,3,3,2,2,2,2,2,2,3,3,3,3,3,4,3,3,2,3,3,2,3,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,4,4,4,5,5,5,6,5,6,6,6,6,5,5,4,4,4,3,3,3,3,3,2,2,3,3,2,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,5,5,5,5,6,6,5,6,6,6,6,7,7,6,6,7,7,7,8,7,8,8,7,7,7,7,7,7,7,7,7,8,8,9,10,11,12,13,13,14,16,15,14,16,17,15,16,17,18,18,18,19,20,21,20,22,23,24,22,24,23,23,23,23,20,22,23,23,23,22,22,25,25,25,25,25,26,26,26,25,26,26,26,26,26,26,27,27,26,27,27,26,26,27,26,26,26,26,26,26,27,27,27,26,25,26,25,25,24,22,22,19,19,18,15,16,14,14,14,12,11,10,9,8,8,8,8,8,8,9,9,9,9,10,10,11,11,11,11,12,12,13,13,12,14,13,14,12,12,11,11,12,11,11,12,11,12,13,13,13,13,13,12,12,11,11,11,11,11,10,10,10,9,9,8,9,8,7,7,7,7,7,8,8,8,7,7,8,7,8,8,8,8,8,8,8,8,8,8,6,6,6,5,5,4,4,5,5,4,4,5,5,5,5,5,5,5,6,6,5,5,6,6,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,6,6,5,5,5,4,4,5,5,5,4,5,5,6,6,5,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,7,6,7,6,6,7,7,6,6,6,6,6,6,7,6,7,7,7,6,7,6,6,7,7,7,7,6,7,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,3,4,4,4,4,4,5,5,5,6,6,6,7,6,6,6,7,7,7,6,6,6,6,6,6,5,5,5,5,6,6,6,5,6,6,6,6,7,7,6,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7,8,8,8,7,8,7,7,7,7,6,6,7,7,7,7,7,8,7,8,8,8,9,9,9,8,9,8,8,10,9,9,9,10,10,9,10,9,9,9,9,8,9,9,8,8,8,8,8,9,9,9,9,9,9,9,10,9,9,9,10,10,9,9,8,9,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,7,8,8,9,11,12,11,11,12,13,14,16,16,17,20,20,19,18,19,19,19,20,21,20,21,21,22,22,23,23,24,24,23,24,24,25,23,25,25,22,22,24,25,25,25,24,24,24,24,23,21,23,25],[28,28,28,28,28,28,28,27,28,27,26,26,27,26,26,27,26,27,26,26,27,27,26,27,27,26,27,27,26,26,26,26,27,28,26,27,27,26,27,26,27,26,26,26,26,26,24,24,25,22,21,22,23,20,20,22,20,19,19,19,16,15,13,12,11,9,8,8,8,7,7,6,6,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,3,3,3,3,4,4,3,3,3,4,3,3,3,3,2,3,3,2,2,2,2,1,1,1,1,1,0,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,2,3,3,4,3,4,4,4,4,5,5,5,5,5,4,5,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,3,2,2,2,2,2,2,3,3,2,3,3,3,4,4,4,4,5,5,5,5,5,5,6,5,4,4,4,4,3,3,3,2,3,3,3,2,3,3,3,3,3,4,4,4,5,5,4,5,5,5,6,5,6,5,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,5,5,4,5,5,5,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,5,4,4,4,4,4,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,7,8,8,8,8,8,8,9,8,8,8,8,7,8,8,8,8,8,8,10,10,11,12,13,14,14,16,16,17,16,17,18,18,19,20,20,21,21,20,23,24,23,24,24,24,24,25,24,24,24,25,25,24,23,25,26,26,24,26,26,26,25,26,27,27,27,26,26,27,27,27,27,27,27,28,27,28,27,27,28,27,28,27,27,27,27,27,28,28,28,27,26,27,26,26,25,24,23,21,21,19,18,19,15,15,15,14,12,11,10,10,10,10,9,10,10,11,10,10,11,11,12,12,12,14,12,12,14,13,13,14,15,15,14,13,15,13,12,12,12,12,13,12,14,14,14,15,14,14,13,14,13,12,12,13,12,11,12,11,11,10,9,10,9,9,8,9,9,8,9,9,9,8,9,9,8,8,9,9,9,9,9,9,9,8,9,7,7,7,6,6,5,5,5,6,5,5,6,6,5,5,6,6,5,6,5,5,5,6,5,5,5,6,5,5,5,6,5,5,6,6,6,6,7,7,8,8,7,6,5,5,5,5,4,4,5,5,5,5,5,5,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,8,7,7,7,7,7,7,6,7,6,6,6,7,7,6,6,7,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,5,5,5,5,6,5,5,5,5,5,5,4,5,5,5,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,5,6,6,6,6,6,6,6,6,6,6,7,7,7,8,7,7,8,8,8,9,8,8,8,8,8,8,8,9,8,8,8,9,8,7,8,8,8,8,8,8,7,7,7,7,7,7,7,8,7,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,11,10,10,10,10,10,10,10,10,9,10,10,9,9,9,10,9,11,10,10,10,10,10,10,10,10,10,10,10,11,10,10,9,10,10,9,9,9,9,8,8,8,8,8,8,7,8,7,7,8,7,7,7,7,6,7,8,9,9,10,12,12,13,12,13,14,16,17,18,18,21,20,21,20,20,21,22,23,22,23,24,23,24,23,26,26,24,23,25,25,25,26,25,25,26,24,25,25,25,25,25,25,24,25,25,24,23,25,26],[29,29,28,29,28,29,29,28,28,28,27,27,27,26,27,26,27,27,26,27,26,26,27,27,26,27,27,27,27,26,26,28,28,28,27,28,27,27,28,27,28,27,26,27,27,27,25,24,25,24,23,23,24,22,21,22,22,21,20,19,17,16,14,13,11,11,9,9,8,8,7,7,7,6,6,6,6,5,5,6,5,5,5,5,4,4,4,5,4,4,4,4,3,4,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,4,4,4,3,3,4,4,4,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,0,1,2,2,2,2,2,2,1,2,2,2,2,2,2,3,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,4,4,5,5,5,5,6,5,5,6,6,5,5,5,4,4,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,3,4,4,4,4,5,5,6,6,6,6,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,4,4,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,7,6,7,7,7,7,7,8,7,8,9,9,9,9,8,9,9,10,10,10,10,9,9,8,9,9,9,9,9,9,10,11,11,12,14,14,14,15,16,17,17,18,20,19,20,21,22,22,23,24,25,25,26,26,26,27,26,27,26,26,27,25,24,26,26,26,26,27,27,27,27,28,28,28,28,28,29,28,29,29,29,29,29,28,29,29,29,28,28,29,29,29,29,29,28,28,28,28,29,28,28,28,26,27,28,26,25,26,23,22,23,21,19,20,17,17,16,15,14,12,10,11,10,11,10,10,10,11,11,12,11,12,12,12,12,14,13,13,14,16,13,15,16,15,14,16,14,14,13,13,13,13,13,14,15,15,16,16,15,14,14,14,14,12,13,13,13,12,12,12,11,10,11,10,10,9,9,9,10,10,9,9,10,9,9,9,9,9,10,10,10,10,10,10,10,10,10,8,8,7,7,6,6,5,6,6,5,5,6,6,5,5,6,5,5,6,6,5,5,6,6,5,6,6,6,6,6,7,7,7,6,7,8,8,8,8,8,8,8,7,5,6,6,6,5,4,5,5,5,5,6,5,6,6,7,7,6,6,6,7,6,6,6,6,6,6,6,6,5,5,6,6,5,6,6,5,6,6,6,5,6,6,6,6,6,7,7,7,7,7,7,7,8,8,7,7,8,7,7,7,7,7,7,8,8,8,7,7,8,8,7,8,8,8,8,8,8,8,8,8,8,8,7,7,8,7,7,7,6,6,6,6,6,6,5,5,5,5,5,5,5,5,6,6,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,8,7,7,8,8,8,8,9,8,9,9,9,9,9,9,9,9,9,9,9,10,9,9,9,9,9,8,9,9,10,9,9,9,9,8,8,8,8,9,9,8,9,9,8,10,9,10,10,10,10,10,10,10,10,11,11,11,10,11,11,10,10,11,10,10,10,10,10,10,10,9,9,10,10,11,10,11,10,10,11,10,10,11,11,10,11,11,11,10,10,10,10,10,9,10,9,9,9,9,9,9,9,8,9,8,9,8,7,8,8,7,7,7,9,9,10,11,12,13,14,13,14,16,17,19,19,19,22,22,22,20,21,22,21,24,22,23,24,23,25,25,26,25,26,24,26,27,25,26,26,27,26,23,26,27,27,26,27,26,25,26,27,25,23,25,26],[28,28,28,28,28,28,28,29,28,27,27,26,27,26,26,26,27,27,27,28,28,27,28,28,27,27,27,27,27,27,27,28,28,28,27,28,27,27,27,27,28,26,26,27,27,27,25,25,26,25,24,23,24,23,22,23,21,21,20,19,17,16,15,14,12,12,12,11,10,10,9,9,9,8,7,8,7,6,7,7,7,6,7,6,6,6,7,7,7,6,6,6,5,5,5,5,4,5,5,4,3,5,4,5,4,5,5,5,5,6,6,6,5,5,6,6,6,5,5,5,5,5,4,5,4,4,3,3,2,2,2,2,1,0,1,2,2,3,5,3,2,4,3,2,3,4,3,3,4,4,4,4,5,5,5,6,6,6,6,6,6,7,7,6,6,6,5,5,5,6,5,5,5,5,5,4,5,5,3,4,3,4,4,3,4,4,3,3,4,4,3,4,5,5,5,6,7,7,6,7,8,8,8,8,8,9,8,7,7,6,7,7,5,6,5,5,5,5,4,6,5,4,4,5,5,6,6,6,6,6,6,7,7,7,7,7,7,6,7,7,6,7,6,6,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,8,7,7,7,7,7,6,7,7,5,7,7,6,6,6,7,6,8,8,7,7,7,8,8,8,8,9,8,9,10,9,9,11,10,10,10,12,11,11,10,11,11,11,11,11,11,12,11,11,10,11,12,11,10,11,12,12,14,14,14,16,17,17,18,20,19,19,20,21,20,20,22,21,22,23,23,25,25,25,26,26,28,26,27,25,25,26,25,25,26,26,25,26,26,26,28,28,28,27,28,28,29,28,28,28,28,28,28,28,28,29,29,29,28,28,28,28,28,28,28,27,28,28,27,28,28,28,28,26,28,28,27,26,25,24,24,23,22,20,20,18,17,18,16,14,13,12,12,14,13,12,13,13,14,13,13,13,13,14,13,14,15,15,14,15,18,16,16,17,18,17,17,15,15,14,14,14,14,15,15,17,17,18,18,19,17,17,18,16,14,14,15,15,14,14,13,13,13,12,13,12,12,11,12,12,12,12,12,12,12,12,12,12,12,11,12,12,12,12,12,11,10,12,10,11,10,9,9,8,8,9,8,8,7,8,8,7,8,9,8,7,8,9,8,8,9,9,8,8,9,8,9,9,9,9,9,9,8,9,9,10,10,10,10,10,9,8,8,8,8,7,6,7,8,7,7,8,9,8,9,9,9,9,9,9,9,8,9,8,9,8,8,8,8,7,8,8,8,8,8,8,8,9,8,8,8,8,8,8,9,9,9,9,10,10,9,9,10,11,11,9,10,10,10,9,10,10,9,10,10,11,10,9,9,10,10,10,10,10,10,10,10,9,10,10,10,10,9,9,9,9,10,8,9,7,8,7,7,8,7,7,6,7,7,6,6,7,8,8,8,9,9,9,10,9,9,9,9,9,9,10,9,9,9,10,9,9,8,8,9,9,9,9,10,9,10,10,9,10,10,10,11,11,11,11,11,11,11,11,12,12,11,11,11,12,12,12,11,11,12,12,11,11,11,12,11,11,11,10,10,10,10,10,10,11,10,10,11,11,11,11,11,11,12,12,12,12,12,12,11,13,13,14,13,13,13,13,12,13,13,13,12,13,14,13,12,12,12,13,11,14,13,13,13,11,14,12,12,13,12,13,13,13,13,12,12,14,12,11,12,12,12,11,11,12,11,11,11,11,10,11,11,10,10,10,11,10,10,10,11,11,11,12,13,14,14,14,15,17,17,19,20,20,22,23,21,21,22,23,22,24,23,23,23,24,26,25,26,25,27,25,26,27,27,28,26,27,27,26,25,27,27,26,27,25,26,26,27,26,24,26,26],[27,27,27,27,27,28,28,27,27,26,25,24,26,25,25,25,26,26,25,26,27,26,26,26,26,26,26,26,26,26,25,27,27,27,26,27,26,26,27,26,27,25,26,25,26,25,24,24,25,23,22,22,22,21,20,22,20,19,20,20,18,17,16,16,15,14,13,12,12,13,12,11,11,10,10,10,9,9,9,9,11,9,10,10,9,9,11,10,9,9,9,8,8,7,7,7,7,7,7,6,6,7,8,5,6,6,7,6,6,7,7,7,7,6,8,8,7,7,6,6,6,6,5,5,5,4,4,4,3,4,3,2,2,1,0,1,3,3,6,5,3,6,7,3,6,6,5,4,6,8,6,6,7,8,6,9,9,9,8,9,9,9,9,9,9,8,8,8,8,8,7,6,5,6,5,4,5,5,4,4,3,4,5,4,4,4,4,4,4,5,4,5,5,6,5,7,7,6,6,7,7,8,9,9,9,9,9,9,8,7,7,6,6,7,5,5,6,6,5,6,7,5,5,8,7,5,8,9,8,7,8,8,9,9,9,9,8,8,8,8,7,7,7,7,7,8,7,6,7,8,8,6,8,8,8,6,6,7,7,7,7,6,8,10,8,7,10,8,8,10,10,8,10,9,11,9,8,7,8,7,6,7,9,8,7,7,10,8,9,9,9,7,9,9,8,9,10,10,9,10,10,10,11,11,11,10,11,12,11,12,12,13,12,13,13,13,14,14,14,14,14,14,13,13,12,13,14,13,12,13,14,14,15,16,17,18,18,18,18,19,20,19,20,21,20,19,21,22,22,23,23,24,24,24,24,25,26,24,25,24,23,25,25,23,25,25,26,25,26,25,27,26,27,26,27,28,27,28,27,27,28,27,27,27,27,28,28,27,28,27,28,28,27,27,27,28,28,27,27,28,27,27,28,26,27,27,26,25,25,25,22,23,21,20,19,18,17,17,16,16,16,14,14,15,15,14,14,15,16,15,15,16,15,17,17,16,17,17,16,18,18,18,17,19,18,18,19,18,17,17,17,16,16,18,18,18,18,19,19,19,18,17,18,17,16,18,17,17,16,16,15,16,15,14,15,16,15,13,13,15,14,13,13,14,13,13,14,14,13,12,14,13,13,13,14,11,12,13,11,12,10,10,11,9,8,9,9,9,8,9,10,9,9,10,11,10,10,9,10,10,10,10,10,10,10,10,10,10,10,11,10,11,10,10,11,11,11,12,11,11,10,10,9,10,9,9,9,11,10,10,9,11,10,10,12,11,11,11,12,11,10,10,11,11,10,10,11,10,11,10,10,10,11,10,11,9,10,11,10,10,11,10,10,10,12,11,10,11,11,11,11,11,12,13,12,11,12,13,12,10,12,11,12,11,12,11,11,10,12,13,12,11,12,12,11,12,11,11,12,11,12,12,12,12,12,12,13,11,10,10,10,10,10,10,10,10,8,9,11,9,9,9,12,11,9,12,10,11,11,12,11,10,11,11,11,11,11,11,12,12,12,11,10,10,11,11,11,11,12,10,11,12,11,12,12,12,13,13,13,13,13,14,13,14,13,14,14,13,13,14,14,14,12,13,15,13,13,13,13,13,13,13,13,13,12,13,13,12,12,13,13,12,14,14,13,14,13,14,15,13,15,14,14,14,14,14,15,15,15,14,15,14,15,15,14,15,14,15,15,15,13,14,16,16,14,17,14,14,15,15,16,14,15,15,14,15,15,16,14,15,13,15,14,13,13,14,15,13,13,14,12,12,12,12,12,12,12,12,11,12,11,10,11,11,12,12,12,12,13,15,15,13,16,15,18,17,18,19,21,21,21,20,22,22,20,24,22,23,24,23,25,25,25,25,26,23,26,27,25,27,25,26,26,25,25,26,25,25,26,25,25,26,26,24,23,24,25],[28,28,28,28,28,28,28,28,27,26,27,25,27,26,26,26,27,27,26,27,27,26,26,27,27,26,27,27,27,27,26,27,27,28,26,28,27,27,27,26,27,26,26,26,26,26,25,24,25,24,24,25,24,23,23,23,22,22,21,21,19,19,17,16,15,14,14,14,12,13,11,12,11,11,11,10,9,10,9,10,9,9,10,9,10,10,10,9,8,8,9,7,10,9,8,7,10,8,8,7,12,8,8,6,8,8,7,6,8,8,8,8,8,9,9,8,8,8,8,7,6,7,7,7,7,6,4,4,6,4,3,4,5,2,1,0,1,2,3,3,2,4,4,4,4,6,4,5,9,8,6,9,9,9,9,11,10,9,9,9,9,10,9,9,11,9,8,10,10,9,9,9,8,8,8,7,7,7,5,5,5,6,6,5,5,6,5,4,6,7,5,5,6,7,6,8,6,6,7,8,7,7,7,8,9,8,8,8,7,6,6,6,5,5,5,6,6,6,6,6,7,8,7,9,9,9,9,10,10,9,9,10,10,10,10,10,10,9,9,9,9,9,9,8,9,9,9,9,9,9,10,9,8,8,9,7,8,8,8,8,7,9,10,9,8,8,11,9,9,10,8,9,9,8,8,8,8,8,7,7,6,7,8,8,7,8,10,11,9,9,10,10,10,11,10,11,10,11,10,11,11,11,11,13,12,11,12,13,12,12,14,14,13,13,14,13,15,14,14,15,14,14,15,14,12,13,14,13,12,14,15,14,14,15,16,17,18,19,21,21,20,20,21,22,20,21,23,23,23,24,24,25,25,24,26,26,26,25,26,26,24,25,25,25,26,26,26,27,26,26,27,28,28,27,27,28,28,28,28,28,28,28,28,27,28,29,28,28,28,28,28,27,28,28,27,28,28,28,28,28,28,28,29,27,28,27,27,27,26,25,24,23,22,22,22,20,18,20,18,16,16,15,14,17,15,16,17,16,18,16,16,17,16,18,17,17,18,18,17,19,19,19,18,20,18,18,19,19,18,16,17,17,19,18,19,20,20,19,20,19,18,18,20,18,16,17,18,17,17,17,17,16,17,15,16,16,13,14,13,14,15,15,14,14,14,14,14,13,15,15,14,15,14,14,13,13,12,14,12,12,12,11,12,10,10,11,11,10,10,11,11,10,9,11,11,9,11,10,9,11,10,10,9,12,10,8,11,10,10,9,10,10,10,11,10,11,11,11,12,10,10,8,8,9,9,8,8,10,9,8,8,9,9,10,10,10,11,10,10,10,11,10,11,9,10,10,9,10,11,10,9,10,10,10,10,9,12,11,10,12,12,11,11,12,12,12,11,12,13,12,13,13,13,14,14,12,13,13,13,12,12,13,13,12,12,13,11,12,13,11,12,12,12,11,11,12,12,11,12,12,12,11,12,12,12,12,12,11,12,11,10,10,9,12,10,12,10,9,12,10,10,9,10,10,10,10,11,11,11,11,11,11,10,11,11,12,12,12,11,12,11,11,11,10,11,12,12,12,11,12,12,12,12,13,12,13,13,13,13,13,12,14,14,13,14,14,13,13,14,14,14,14,13,13,14,13,12,13,13,13,12,13,13,13,13,13,12,12,12,13,13,13,13,13,14,14,13,14,15,14,15,14,15,14,13,14,15,14,15,15,16,17,15,15,15,14,14,15,15,15,14,15,15,16,14,18,14,16,15,14,17,14,15,15,15,16,15,16,16,15,14,15,14,14,14,13,13,12,14,13,14,14,13,13,13,14,13,14,13,13,14,13,14,14,13,13,14,14,16,15,16,17,18,18,20,20,22,22,24,23,24,22,22,23,24,25,25,25,25,25,27,26,26,26,26,27,26,27,26,28,26,26,27,27,26,27,27,27,27,26,26,26,27,26,25,26,26],[28,28,28,28,28,28,28,28,28,27,26,26,26,27,26,27,26,27,27,27,27,27,27,27,27,26,26,27,27,27,27,27,27,28,26,27,27,25,27,26,27,25,26,25,26,26,25,23,24,23,22,22,23,21,20,21,21,19,19,20,18,16,15,15,12,12,12,10,10,9,9,9,8,7,6,7,7,6,6,6,6,5,6,5,5,5,5,5,5,4,4,5,3,4,4,4,4,4,4,4,5,4,4,4,5,4,5,5,5,5,6,6,5,6,6,6,6,6,7,6,6,6,5,5,5,5,4,4,4,4,3,4,3,2,2,1,0,1,2,2,2,2,2,4,2,3,4,4,4,5,4,5,5,5,5,6,5,6,6,7,7,6,7,7,6,6,7,7,5,7,7,6,5,7,6,5,5,6,5,4,4,5,4,5,4,5,4,3,4,5,3,3,4,5,4,6,5,4,6,6,6,6,6,6,6,7,6,5,5,4,4,4,3,3,3,3,3,3,3,4,4,4,5,5,5,6,6,6,6,7,6,7,7,8,8,8,6,7,7,7,7,7,7,6,7,7,6,7,7,7,7,6,7,7,7,6,5,6,6,6,7,6,7,7,7,6,7,6,6,6,6,6,6,6,6,5,6,5,5,4,5,4,5,6,5,5,6,5,6,6,7,6,7,7,7,7,8,8,7,7,8,9,9,9,10,9,10,10,10,10,10,12,11,10,11,12,13,13,12,12,13,13,11,11,10,11,12,11,10,11,12,12,12,13,14,15,15,16,17,18,18,18,19,20,19,20,22,22,22,23,22,24,24,25,25,26,25,26,25,25,25,25,25,25,25,25,25,25,26,25,27,27,28,27,26,28,28,27,27,27,28,28,28,28,27,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,27,28,28,28,27,27,26,25,26,26,23,22,21,21,19,18,19,16,15,15,14,13,13,13,14,12,14,14,14,14,15,15,16,14,16,17,16,15,18,18,17,17,19,19,18,18,18,16,15,16,16,16,16,17,18,18,18,20,19,18,17,18,17,16,16,16,16,16,16,15,15,14,13,14,13,13,11,11,13,12,12,12,12,11,11,13,13,11,11,13,12,11,13,12,11,10,12,10,10,9,9,9,8,7,8,8,8,7,8,8,7,7,8,8,8,8,7,7,7,8,7,6,7,8,7,6,7,7,6,7,7,7,8,7,8,9,9,9,8,7,6,6,6,6,5,4,6,5,6,5,6,7,7,8,8,7,7,7,6,7,7,6,6,7,6,6,7,6,5,6,7,6,6,7,7,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,10,12,10,10,10,11,10,9,10,9,9,9,10,10,9,9,9,10,8,8,9,9,8,8,9,9,8,9,9,9,9,8,9,9,8,7,6,7,6,6,7,6,6,6,6,6,6,5,6,6,7,7,7,8,8,8,8,10,8,7,9,9,8,8,9,9,9,9,8,8,6,7,8,8,7,9,9,8,8,9,9,10,9,10,10,10,10,11,11,10,12,10,10,11,12,10,11,12,11,11,11,10,12,11,9,11,11,11,10,11,10,9,11,10,11,10,9,11,11,10,11,13,12,11,11,13,12,11,12,12,12,12,11,13,14,13,13,13,13,13,13,14,13,13,13,13,13,14,12,13,13,13,12,14,13,13,13,13,14,13,13,13,13,14,13,14,13,13,11,12,13,12,11,12,12,11,11,12,11,10,10,11,10,10,11,10,10,9,9,9,9,9,9,10,11,11,13,14,15,13,16,16,19,17,20,20,23,23,23,22,22,23,22,23,23,23,26,24,25,25,26,26,26,25,26,27,26,26,26,26,27,25,26,26,27,26,27,25,25,27,27,26,24,26,26],[29,29,29,29,29,29,29,29,29,28,28,27,28,27,28,27,28,28,27,28,27,27,28,28,26,27,28,27,28,28,26,28,28,29,27,28,27,27,28,27,28,27,27,27,27,26,25,24,25,23,22,23,23,22,20,22,20,19,19,19,17,16,13,12,10,10,9,8,8,7,7,6,6,5,5,5,5,4,4,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,3,2,2,2,3,3,3,3,4,4,4,4,5,5,4,4,4,4,4,5,4,5,5,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,4,3,3,4,4,4,4,5,4,5,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,3,3,3,3,4,3,3,3,3,2,3,3,2,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,2,2,2,2,2,2,3,3,3,3,3,3,4,5,4,5,5,5,5,5,5,6,6,5,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,5,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,5,4,5,5,5,5,5,6,5,6,6,6,6,6,7,7,7,7,8,7,8,8,9,8,8,9,9,10,9,9,10,9,9,8,8,8,9,8,8,9,9,10,10,10,12,12,13,13,15,15,17,16,18,20,20,18,21,22,22,22,24,25,25,26,27,27,27,26,27,24,26,27,25,25,26,26,26,26,26,26,28,28,28,27,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,28,29,28,28,29,29,29,29,28,28,28,27,27,26,25,24,23,22,21,21,18,17,17,14,13,12,10,9,10,10,10,9,10,10,11,11,11,11,12,12,12,13,13,13,14,15,14,14,16,15,15,15,14,14,13,12,13,13,14,14,15,15,16,15,15,15,14,15,14,13,13,13,13,13,12,11,11,10,10,9,10,9,8,9,9,9,8,8,9,8,9,9,10,9,9,10,10,10,10,10,9,9,9,8,8,7,7,6,6,6,6,6,6,5,6,6,5,5,6,6,5,6,6,5,5,6,6,5,5,5,5,5,5,6,5,5,5,6,6,6,7,7,7,7,7,6,5,4,4,5,4,4,4,4,4,4,5,5,5,6,5,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,5,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,6,7,7,6,7,6,6,7,7,7,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,6,6,8,6,6,7,7,7,7,7,7,7,6,6,6,5,5,6,6,6,6,6,6,6,7,6,7,7,7,7,8,7,7,7,8,8,8,8,8,8,8,8,8,8,9,7,8,8,7,7,8,7,8,8,7,7,7,7,7,7,7,7,7,7,7,8,8,7,8,8,8,8,8,9,9,8,9,9,10,10,10,10,9,10,9,10,9,9,10,10,9,9,10,9,8,9,9,9,9,10,10,9,10,10,10,10,10,10,10,11,10,10,9,9,9,10,8,9,9,8,8,9,9,8,9,8,8,8,8,8,8,7,8,8,7,7,7,9,9,10,10,11,13,13,13,14,15,17,18,20,19,22,22,21,20,22,23,22,24,23,23,26,24,25,25,26,26,25,24,26,26,25,27,25,26,26,24,25,27,26,27,26,27,26,27,27,26,25,27,26],[29,29,28,28,28,29,28,28,28,27,27,26,27,26,26,27,27,28,27,27,27,26,27,27,26,26,27,26,27,27,26,27,28,28,26,27,27,26,28,26,27,26,27,25,26,25,23,24,24,22,21,22,23,20,19,21,19,17,18,19,16,14,13,11,10,9,9,8,7,7,7,7,6,6,5,5,5,5,5,5,5,4,4,4,4,3,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,5,4,5,4,4,4,4,3,4,4,4,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,3,3,5,5,4,5,5,5,4,5,4,4,4,3,3,3,3,2,2,3,3,2,3,3,3,3,3,4,4,4,5,5,4,5,5,5,5,6,6,6,5,5,6,5,4,5,5,4,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,4,4,5,5,5,4,5,5,5,5,5,4,4,5,4,4,4,4,4,3,4,4,4,4,4,4,5,4,4,4,5,4,5,5,6,5,5,6,5,6,6,7,6,7,7,7,7,7,7,7,8,8,8,8,8,9,10,10,9,9,9,9,9,8,8,8,9,8,9,9,9,10,10,10,11,13,14,13,15,15,17,15,17,18,18,18,21,21,21,21,21,22,23,24,24,25,25,25,25,24,24,24,24,24,24,24,24,25,25,25,26,26,27,26,26,27,27,27,27,28,27,27,27,27,27,28,28,27,27,27,28,27,27,27,28,26,28,27,27,27,27,27,28,27,26,26,26,25,24,24,23,22,20,19,19,17,16,16,13,12,11,11,10,11,10,11,10,11,11,11,11,12,12,12,13,12,14,13,13,14,15,14,15,16,17,15,16,15,14,13,14,14,13,14,14,16,16,15,16,16,15,15,16,13,13,13,13,13,13,13,11,11,11,10,10,10,9,9,9,9,9,9,9,9,8,9,10,9,9,9,10,10,10,10,10,10,9,9,8,7,7,7,6,6,5,6,6,5,5,6,6,5,5,6,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,7,7,8,7,7,6,5,5,5,5,4,4,4,4,4,4,5,5,5,6,6,6,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,7,6,7,7,7,7,7,7,8,7,7,7,7,7,7,7,7,6,7,7,6,6,7,7,7,7,6,7,7,6,6,7,7,7,7,7,7,7,7,7,7,6,6,5,5,5,5,5,4,5,4,4,5,4,4,4,4,5,5,5,6,6,6,7,7,6,6,7,7,8,7,7,7,7,7,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,8,7,8,8,8,8,8,8,8,8,8,7,8,9,8,8,8,8,8,8,7,8,7,8,8,8,8,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,8,9,9,9,9,9,11,10,10,10,10,10,10,10,10,9,10,9,9,10,10,9,9,10,10,9,10,10,10,10,10,11,10,10,10,10,10,11,11,9,10,9,10,10,9,9,9,9,8,8,9,9,7,8,8,8,7,8,8,7,7,8,7,7,7,8,8,10,10,12,13,13,12,14,15,16,17,20,18,22,22,22,22,22,22,21,23,23,23,26,24,26,24,26,25,26,24,27,26,25,27,26,25,26,25,25,25,26,26,26,26,25,26,26,25,25,26,26],[28,29,28,28,28,28,28,27,28,26,26,25,25,26,25,25,25,26,25,26,25,26,26,25,26,25,25,26,25,25,25,25,26,26,25,26,25,25,26,25,26,25,24,24,25,24,22,22,22,21,20,20,20,20,18,19,18,17,17,17,15,14,12,11,9,8,8,7,7,6,6,6,5,5,4,4,4,4,4,4,4,3,4,3,3,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,2,3,2,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,4,4,4,4,4,4,5,4,4,4,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,4,4,4,4,3,4,4,3,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,4,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,7,8,7,7,8,7,7,8,8,8,9,9,11,12,13,12,13,15,15,14,15,17,16,16,18,18,19,20,19,21,21,21,22,23,23,23,24,23,22,23,25,23,22,23,23,25,24,23,25,25,27,26,25,26,26,26,27,26,26,26,26,26,27,28,28,28,27,27,27,27,26,27,26,26,27,25,27,27,26,26,27,27,26,25,25,25,24,22,21,20,19,18,18,16,14,14,12,11,10,9,9,9,9,9,9,9,9,10,10,10,10,11,11,11,12,11,11,13,13,12,13,14,14,13,13,13,13,12,12,11,12,12,12,14,14,15,14,14,13,12,14,12,12,12,12,12,11,11,10,10,9,9,9,8,8,7,7,8,7,7,8,8,7,7,8,8,7,8,9,9,8,9,9,8,8,8,7,6,6,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,4,5,5,5,5,5,4,5,5,5,5,5,5,5,6,6,6,7,7,7,6,5,5,5,5,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,4,4,4,4,4,4,4,3,4,3,3,4,4,4,4,5,5,6,6,6,7,6,6,7,6,7,6,6,6,6,6,6,5,5,5,5,5,5,6,5,5,6,6,5,6,6,6,6,7,7,7,7,7,7,7,7,7,8,7,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,7,7,7,7,8,7,7,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,8,9,9,8,9,9,8,8,8,8,8,9,9,10,9,9,10,9,9,9,9,9,9,10,9,9,8,9,9,8,8,8,8,7,7,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,7,8,9,9,11,12,12,11,13,13,16,16,18,18,21,21,21,20,20,21,20,24,22,22,25,24,25,24,26,26,25,23,26,25,25,27,25,25,26,25,25,25,24,24,24,25,24,26,26,23,24,24,25],[29,29,29,29,29,29,29,28,29,28,27,27,27,27,27,27,27,27,27,28,26,27,27,26,27,27,26,27,27,27,27,28,27,28,27,28,26,27,27,27,27,27,26,26,26,26,24,23,24,23,22,21,22,22,19,20,20,19,17,18,15,13,12,10,9,8,7,6,6,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,3,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,3,4,4,5,4,4,4,4,4,4,4,3,3,2,3,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,6,7,7,7,6,7,8,7,6,7,6,7,7,7,6,7,7,7,8,8,9,11,12,12,13,13,15,14,17,18,17,17,20,20,21,21,21,22,23,23,24,25,26,25,26,25,22,25,23,23,25,24,24,25,25,26,26,26,26,26,27,27,27,27,27,27,27,28,27,27,28,28,28,28,28,27,28,28,28,28,28,26,28,27,27,28,28,27,28,27,27,27,26,25,24,24,22,21,20,18,19,16,14,13,12,11,10,8,8,8,8,8,7,8,8,8,9,8,9,9,10,10,11,10,11,11,12,11,11,12,12,12,12,11,11,11,11,11,10,11,11,11,11,12,12,11,11,10,11,11,10,10,10,10,9,9,9,9,8,8,7,7,6,7,6,7,7,6,6,7,6,6,7,7,7,7,8,8,8,8,8,8,7,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,6,5,5,5,6,5,5,6,5,5,5,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,6,6,7,6,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,6,5,5,6,6,6,6,6,6,6,6,7,7,6,7,8,7,7,7,7,8,8,8,8,8,7,8,8,7,8,7,7,8,8,7,7,7,7,7,8,8,8,7,8,8,7,8,8,8,8,8,8,8,8,7,8,8,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,5,5,6,7,7,9,9,10,11,12,11,13,13,15,18,17,17,20,19,20,19,20,22,20,23,22,23,24,21,25,24,25,24,25,23,26,25,24,26,25,25,24,23,24,25,25,24,25,24,25,24,25,24,23,25,24],[29,29,29,29,29,29,29,28,29,28,28,28,28,27,28,28,27,28,27,28,27,27,28,27,27,27,27,27,28,27,26,28,28,28,27,28,27,28,27,27,28,27,26,26,26,25,24,23,24,22,21,21,23,20,18,20,18,18,18,17,15,13,11,9,8,7,6,5,5,5,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,4,3,4,4,4,3,3,3,2,2,2,2,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,2,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,9,11,11,11,13,13,15,13,16,16,16,16,18,19,19,19,19,22,23,22,24,25,26,25,25,24,23,24,24,24,24,25,24,25,24,25,26,27,27,26,27,27,27,28,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,27,28,27,28,27,27,28,27,28,28,26,27,26,25,25,24,23,22,21,20,18,18,16,14,13,11,10,8,8,7,7,7,7,7,7,7,8,8,8,8,8,9,9,10,9,9,10,12,10,11,12,12,12,12,11,11,10,10,10,10,10,11,12,12,12,12,12,10,10,11,10,9,9,9,9,8,8,8,8,7,7,7,6,6,6,6,6,6,5,6,6,6,6,6,6,6,7,7,7,7,8,8,7,7,7,5,5,5,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,3,3,4,4,3,3,4,3,3,4,4,3,3,4,4,5,5,5,6,6,6,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,4,4,5,4,4,5,4,4,4,5,4,5,4,4,5,4,4,4,5,5,4,5,5,5,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,4,4,5,5,5,5,5,5,4,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,5,5,6,6,6,6,6,6,6,6,6,5,5,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,6,6,8,7,7,7,7,7,6,7,6,6,7,7,6,6,7,6,6,6,6,6,7,7,7,7,7,7,7,8,7,7,7,8,8,7,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,5,5,5,5,4,5,6,7,8,9,10,11,12,11,13,13,15,17,19,19,21,21,22,20,21,22,21,24,22,23,24,23,26,24,26,25,27,24,26,26,26,27,25,26,26,24,25,26,26,26,26,26,25,26,26,25,25,25,25],[29,28,28,28,28,28,28,27,28,27,26,25,26,25,26,26,26,26,26,26,25,26,26,25,25,26,26,26,26,25,25,26,26,27,25,27,26,26,26,26,27,25,25,25,24,24,22,22,22,20,20,20,21,19,17,19,17,16,17,16,13,12,11,9,8,7,6,5,5,5,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,2,2,2,2,1,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,8,10,10,10,12,13,13,12,14,15,14,14,16,17,17,19,18,20,21,20,22,23,23,23,23,23,20,22,22,22,22,22,23,23,23,23,24,25,27,24,25,26,25,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,26,26,26,25,26,25,25,27,26,26,27,26,26,25,24,23,22,21,20,19,17,15,17,14,13,12,10,9,8,7,7,7,7,7,6,7,7,7,8,8,8,8,9,9,10,9,9,10,10,10,10,11,12,11,11,11,10,9,9,9,9,10,10,11,11,11,11,11,10,10,10,9,9,9,9,9,8,8,8,7,7,7,7,6,6,5,6,6,6,6,6,6,5,6,6,6,6,6,7,7,7,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,6,6,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,4,5,4,4,4,5,4,4,4,5,5,5,4,5,5,4,4,5,5,4,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,3,3,3,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,4,4,4,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,6,5,6,5,5,6,6,5,6,6,6,5,5,5,5,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,6,7,7,6,7,7,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,8,6,7,6,7,7,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,6,7,8,9,10,11,10,11,12,14,15,17,17,20,20,20,19,20,19,20,21,21,21,23,22,24,23,24,24,24,23,25,25,24,27,24,24,25,23,23,24,24,24,23,24,23,25,24,23,22,24,24],[29,28,28,29,28,29,28,27,28,27,26,27,26,26,26,26,26,25,27,26,25,27,26,25,26,27,25,26,26,25,25,26,26,27,25,26,25,26,26,25,26,26,25,25,25,25,24,22,23,22,22,20,21,20,19,19,18,18,17,16,14,13,11,9,8,7,6,5,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,3,3,2,2,2,2,2,1,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,6,6,5,5,5,5,5,5,5,6,6,6,7,8,9,10,12,11,13,14,14,13,15,16,15,15,17,17,19,20,18,22,23,21,23,25,24,24,25,23,23,23,23,24,23,24,24,23,24,23,25,25,26,24,26,26,26,26,26,26,26,27,26,27,26,27,27,27,27,26,27,27,27,27,27,26,27,26,26,27,26,27,27,25,26,25,24,24,23,23,20,19,19,16,17,15,13,12,10,9,8,7,6,6,6,6,6,7,6,7,7,7,7,8,8,8,9,8,9,10,10,10,10,11,11,10,11,10,10,9,9,9,8,9,10,10,11,11,11,10,10,10,10,9,9,8,8,8,7,7,7,7,6,6,6,6,5,5,5,6,5,4,5,6,5,5,6,6,5,6,6,7,7,8,7,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,6,6,5,4,3,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,5,5,4,4,5,5,5,5,5,4,4,4,3,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,4,5,6,5,5,6,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,7,7,7,6,7,7,6,7,6,6,6,6,6,6,6,5,6,6,7,7,6,7,7,7,7,7,7,7,7,7,6,7,6,7,7,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,4,5,4,4,4,4,5,6,7,8,9,11,11,10,12,13,15,17,18,18,20,21,21,19,19,20,21,23,21,22,23,22,24,23,25,24,25,23,26,25,24,26,25,24,25,24,25,25,24,24,24,25,24,25,24,23,23,23,23],[29,28,28,29,28,29,28,28,28,28,27,27,27,26,27,26,26,26,26,27,26,27,27,26,26,27,26,27,27,25,26,27,26,28,26,27,26,27,27,26,26,26,25,26,25,25,23,22,23,22,21,21,22,19,19,20,19,17,17,17,14,13,11,9,7,6,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,1,1,2,1,1,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,5,5,4,5,5,5,4,5,5,6,6,7,7,9,10,10,12,13,14,13,14,15,16,15,17,18,19,19,19,22,23,22,23,24,24,24,25,23,22,24,23,23,23,23,24,23,24,24,25,25,27,25,26,26,26,26,26,26,26,27,26,26,26,27,27,27,27,27,28,27,27,27,28,27,27,27,26,27,27,27,27,25,26,25,24,23,22,21,20,19,18,16,17,14,12,11,10,8,7,6,6,5,6,6,5,6,5,6,7,6,6,7,7,7,8,8,8,8,8,9,9,10,10,9,10,9,9,9,8,8,8,9,9,9,9,10,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,7,7,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,5,5,5,5,4,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,3,4,3,3,3,4,4,3,3,3,4,4,3,3,4,4,3,4,4,3,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,5,5,5,4,4,5,5,4,5,5,4,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,4,5,6,5,5,6,6,6,6,6,6,6,5,6,6,5,6,6,5,5,6,5,5,5,5,6,5,6,7,6,6,6,6,7,6,6,6,7,7,6,6,5,6,6,5,5,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,6,7,7,9,10,10,10,11,12,13,15,16,16,19,19,19,17,18,19,19,23,19,22,21,20,24,23,23,24,25,22,24,24,24,24,23,24,24,22,23,25,24,23,25,24,22,24,25,21,21,24,23],[29,29,28,29,29,29,29,28,29,28,27,27,27,27,27,28,27,28,28,28,27,28,28,27,28,28,28,28,29,27,27,28,28,28,28,28,28,28,28,28,28,26,26,27,26,26,23,23,24,21,21,21,22,19,19,19,17,17,18,17,13,12,10,8,6,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,1,1,2,2,2,2,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,5,5,6,6,7,8,9,9,11,11,14,12,14,15,15,14,16,17,18,19,19,21,22,21,23,23,24,23,24,22,21,23,22,22,23,23,23,22,23,24,25,24,26,24,26,27,27,27,27,27,27,27,27,26,27,28,27,28,27,27,28,28,27,27,27,25,26,27,26,28,27,27,28,25,25,26,24,23,23,20,20,19,17,16,15,13,11,10,8,8,6,6,5,5,5,5,5,5,6,6,6,6,6,7,7,7,8,7,8,9,8,9,9,10,9,9,10,9,9,8,8,8,8,8,8,9,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,6,5,5,5,4,4,4,5,4,4,5,5,4,4,5,5,5,5,5,6,6,6,6,6,5,5,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,5,4,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,6,5,5,6,5,5,5,5,4,5,5,5,5,5,5,5,4,5,5,5,5,6,5,5,5,5,6,5,6,5,6,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,5,5,6,7,8,9,10,9,11,11,13,14,16,17,19,20,19,18,19,18,19,21,20,21,22,20,24,23,26,24,25,24,25,25,25,27,24,25,25,23,24,26,25,24,24,24,23,25,25,22,21,24,25],[28,27,27,28,27,28,28,27,28,27,25,26,26,25,25,26,25,25,26,26,25,26,26,25,26,26,25,26,26,24,25,26,26,27,26,27,26,26,26,26,26,26,25,25,25,25,24,22,23,22,22,20,21,19,18,18,17,17,16,16,13,12,10,8,7,6,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,3,3,2,2,1,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,6,6,6,7,9,10,10,11,13,13,12,14,14,14,14,16,16,18,18,17,20,22,21,21,23,22,23,24,22,21,23,22,22,22,22,23,23,23,22,24,24,25,24,25,26,26,26,25,26,26,26,26,26,26,26,27,26,26,26,27,27,27,26,27,25,26,26,26,27,26,26,27,24,25,25,24,23,21,21,19,18,17,15,15,13,11,11,9,8,7,6,6,5,6,5,5,6,6,6,6,6,6,7,7,7,8,7,8,8,8,8,9,9,9,9,9,9,8,8,8,8,7,8,8,9,9,9,9,9,9,8,8,8,8,7,7,7,6,6,6,6,5,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,4,4,3,3,2,3,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,2,2,3,3,2,2,3,2,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,3,4,4,3,3,4,3,3,4,4,3,4,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,5,5,4,5,5,5,5,5,5,4,5,4,5,5,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,5,5,5,6,6,5,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,6,6,6,6,6,6,6,6,6,5,6,6,6,6,5,5,5,5,5,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,5,6,7,7,8,10,10,9,11,12,13,15,16,16,19,20,18,18,18,19,18,22,20,21,21,19,22,22,23,22,23,21,24,23,22,25,23,23,22,23,24,24,23,23,23,23,21,22,23,21,21,22,23],[28,28,28,29,28,28,28,27,28,27,26,27,26,26,26,26,25,25,26,26,25,27,26,24,26,26,25,26,26,24,25,26,25,27,25,26,25,26,26,25,26,26,25,25,24,25,23,22,22,21,21,20,21,19,18,19,18,17,16,16,13,12,10,7,6,5,5,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,3,4,4,4,4,4,4,5,5,6,7,8,10,10,11,12,13,12,14,15,15,14,15,16,18,17,18,20,21,20,22,23,24,24,24,22,21,23,23,22,21,23,23,23,23,23,23,24,25,24,24,25,25,26,25,25,25,26,26,25,26,26,26,26,26,26,27,26,26,26,26,25,26,26,25,26,26,26,26,23,25,24,23,23,22,20,18,18,16,15,16,14,11,11,9,8,6,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,8,8,9,9,9,9,8,8,7,7,7,7,7,8,8,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,6,5,5,4,4,4,4,4,4,4,4,4,5,4,4,5,4,4,5,5,5,5,6,6,6,5,5,4,4,3,3,3,3,2,2,3,2,2,3,2,3,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,5,5,4,4,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,4,5,5,5,6,5,5,5,5,6,5,6,5,6,6,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,5,5,7,7,9,9,10,9,11,11,13,14,16,16,18,19,18,17,19,19,19,22,19,21,22,21,24,23,24,23,24,23,24,24,23,25,23,23,23,23,23,24,24,24,24,23,22,24,23,22,21,23,23],[28,28,28,29,28,29,28,28,29,28,27,27,27,27,26,27,26,26,27,27,26,26,27,26,26,27,27,27,27,25,26,27,27,27,27,27,26,27,27,27,26,27,25,26,25,25,24,22,22,21,21,20,20,19,17,18,18,17,16,16,13,12,10,8,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,3,3,2,2,1,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,1,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,3,4,4,4,4,4,4,5,6,6,7,9,9,10,12,12,13,12,13,15,15,14,16,17,17,18,18,21,22,21,22,23,24,23,24,22,22,24,23,21,23,24,24,23,23,24,24,26,27,24,25,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,26,26,26,25,26,27,26,27,26,26,27,24,24,24,23,22,21,20,19,18,17,16,15,13,12,11,9,8,6,5,5,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,9,9,8,9,8,8,8,7,8,7,8,8,8,9,9,8,9,8,8,7,7,7,6,6,6,6,5,6,5,5,5,5,4,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,6,6,6,5,5,4,4,3,3,3,3,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,2,3,3,4,3,4,4,5,5,4,4,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,4,5,6,6,5,5,6,5,4,5,5,4,4,5,4,4,5,5,4,4,4,5,5,5,5,5,5,5,5,6,5,6,5,6,6,5,5,5,6,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,5,6,7,8,10,10,9,10,11,13,15,17,17,19,21,18,17,18,19,18,22,20,22,21,20,25,25,23,23,25,23,24,25,24,25,23,24,24,22,24,25,25,23,25,24,22,24,25,22,21,24,23],[28,28,28,28,28,28,28,27,28,27,26,26,26,26,26,26,26,26,27,26,25,26,26,25,26,27,26,27,27,25,26,27,27,28,26,27,27,27,27,27,27,27,26,26,26,26,24,23,23,23,22,21,22,20,18,19,17,18,16,16,12,11,9,7,6,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,3,4,4,4,4,4,4,5,5,5,7,8,9,9,11,12,13,11,13,14,14,14,15,16,17,18,17,20,22,20,21,23,24,23,24,22,21,23,23,22,22,23,24,23,23,23,24,25,27,24,25,26,25,26,26,26,26,26,27,26,26,26,26,26,26,26,27,27,26,26,26,25,27,26,26,27,26,26,27,24,24,24,23,23,22,20,18,18,17,15,14,12,10,10,8,7,6,5,5,5,5,5,4,5,5,5,6,5,6,6,6,6,7,6,7,8,7,8,8,9,8,9,9,9,8,8,7,7,7,7,7,8,8,9,8,8,8,8,7,7,7,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,5,5,4,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,5,4,4,4,4,4,5,5,5,5,5,5,5,6,5,6,5,5,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,5,5,6,7,8,9,10,9,10,11,13,13,15,15,18,19,17,17,18,18,18,21,18,20,21,20,22,22,23,22,23,21,23,23,23,25,22,22,23,21,22,23,22,22,22,22,21,23,23,22,20,21,22],[28,27,27,28,27,28,27,26,28,26,25,26,25,25,24,26,24,25,26,24,25,26,25,25,26,26,24,25,26,24,25,26,25,26,24,26,25,26,25,25,25,25,24,25,25,24,23,22,22,21,21,19,20,19,18,18,17,17,15,15,13,11,10,8,6,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,3,3,2,2,1,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,2,2,2,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,3,3,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,5,5,5,4,4,4,4,4,4,4,5,5,5,6,6,7,9,10,10,12,12,13,12,14,14,14,14,15,16,17,17,17,20,21,19,20,22,22,23,23,21,21,22,22,22,22,22,24,23,23,23,24,25,25,24,25,26,26,26,25,26,26,26,26,26,26,26,26,26,26,26,27,26,26,26,25,25,26,26,25,25,25,25,25,23,24,23,23,22,19,20,17,16,16,14,14,12,10,10,8,7,6,6,5,5,5,5,5,5,5,6,6,6,6,6,7,7,8,7,7,9,8,8,9,10,9,9,9,9,9,8,8,8,7,8,8,9,9,9,9,9,9,8,8,8,7,7,7,7,6,6,6,6,5,5,5,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,3,4,3,4,4,3,3,4,4,3,4,4,4,4,3,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,4,4,4,3,4,4,4,4,4,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,4,4,5,4,4,5,5,4,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,5,5,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,5,6,7,7,8,9,10,9,11,12,13,15,17,17,19,21,18,18,19,19,18,21,20,20,22,21,23,22,24,23,23,23,24,25,24,25,24,23,24,23,23,24,23,24,23,24,21,25,24,22,22,24,22],[28,28,28,28,27,28,28,27,28,27,26,27,27,26,26,26,25,26,26,26,26,26,26,26,26,27,26,27,27,25,26,27,27,28,26,27,26,27,27,27,27,26,25,26,26,25,24,23,23,23,21,21,22,20,19,20,19,18,17,18,15,13,10,8,7,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,3,3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,2,2,2,2,2,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,5,6,6,7,10,10,11,13,14,15,15,15,16,18,16,17,19,19,20,20,22,23,22,23,24,24,24,24,24,22,23,23,22,23,24,24,23,24,23,24,24,26,24,25,25,25,25,25,25,26,26,25,25,25,26,26,26,26,25,27,27,27,27,26,25,26,26,26,26,26,26,26,24,24,24,23,23,21,20,19,18,17,15,16,14,12,11,9,8,7,6,6,5,6,6,6,6,6,6,7,7,6,7,7,7,8,8,8,8,8,8,9,10,9,9,9,9,9,8,8,8,8,8,8,9,9,10,9,9,9,9,8,8,8,7,7,7,6,6,6,6,6,5,6,5,5,4,5,5,5,4,5,5,5,5,5,5,5,6,6,6,6,7,7,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,5,6,6,5,4,3,3,2,3,3,2,2,2,3,3,3,3,3,3,3,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,3,4,4,3,4,4,4,3,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,2,2,1,2,2,3,2,3,3,3,3,4,4,3,3,4,4,4,4,4,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,5,5,5,5,4,5,5,5,4,5,5,4,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,4,4,5,5,5,5,5,6,5,5,6,7,7,6,6,6,6,5,6,6,5,6,5,5,5,6,5,5,5,5,6,6,6,7,6,6,6,6,6,7,6,6,7,7,6,6,6,7,6,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,5,6,7,8,9,10,10,10,11,12,13,15,15,16,18,19,17,17,18,18,18,21,18,20,21,20,23,23,22,22,23,22,23,24,23,23,22,23,24,21,22,24,24,22,23,23,21,23,24,21,21,23,21],[28,27,28,28,27,28,28,27,28,27,26,26,26,26,26,26,26,26,27,26,26,27,27,26,27,27,26,26,27,26,26,28,27,27,27,27,26,27,27,26,27,27,25,26,25,24,23,22,23,22,22,21,21,19,20,19,18,19,18,18,14,13,11,8,7,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,4,4,4,3,4,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,4,4,4,5,5,4,4,5,5,6,6,7,7,10,10,10,12,13,14,13,14,16,15,16,18,17,17,19,19,21,22,21,22,23,24,23,24,22,23,24,23,22,24,23,23,23,23,23,25,24,26,25,25,27,26,26,26,26,26,26,26,26,26,27,27,27,27,26,27,27,26,26,25,25,26,26,26,26,26,25,26,25,24,24,24,22,21,20,20,18,18,16,15,14,12,11,9,8,7,6,6,6,6,6,5,6,6,6,7,7,7,7,7,7,8,8,8,9,9,9,9,10,10,10,10,10,9,9,8,8,8,8,9,10,10,10,10,9,9,9,8,8,8,7,7,7,7,7,6,6,6,6,6,5,5,5,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,6,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,4,3,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,3,3,4,4,3,4,4,3,3,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,4,5,5,4,5,5,5,4,5,5,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,6,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,6,8,8,9,10,11,10,11,12,14,16,17,17,20,21,20,18,19,20,20,22,20,22,22,21,24,25,24,24,25,24,24,25,25,24,24,25,25,23,23,25,25,23,24,24,22,24,25,23,21,24,24],[28,28,27,28,28,28,28,28,28,27,26,26,26,26,26,27,26,27,27,27,26,27,26,27,26,26,27,27,27,27,25,28,27,28,27,28,27,27,28,27,28,27,26,26,27,26,23,23,24,21,22,23,22,19,20,21,19,19,19,19,16,14,12,10,8,7,6,5,5,5,5,4,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,2,3,3,3,3,4,4,3,2,2,2,2,3,3,3,3,2,2,2,3,2,2,2,2,2,2,3,3,2,3,3,4,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,4,5,4,4,5,5,5,5,5,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,3,3,3,2,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,6,6,7,7,7,7,6,7,6,6,6,6,6,6,6,6,7,7,7,8,7,9,11,11,12,14,15,16,16,16,19,18,17,20,20,19,22,22,23,23,24,25,24,26,24,26,24,23,25,24,22,24,24,25,25,24,25,25,25,27,25,26,26,27,27,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,25,24,25,24,24,23,20,19,20,18,17,16,15,13,12,11,10,9,8,7,7,8,7,7,8,8,8,8,8,9,8,9,9,9,9,10,10,11,10,11,12,12,11,12,10,11,10,10,9,10,10,10,10,11,12,11,11,11,10,10,10,9,9,9,9,9,8,8,8,8,8,8,7,6,6,6,7,7,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,7,7,6,5,5,5,4,4,4,5,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,7,7,6,5,4,4,4,4,3,3,3,3,3,4,4,4,5,5,5,5,4,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,6,5,5,5,5,5,4,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,4,4,4,5,5,6,4,4,5,5,5,5,5,5,5,4,4,4,3,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,6,6,7,6,7,6,6,7,6,6,6,7,7,6,6,6,7,6,5,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,7,9,8,8,8,8,8,7,8,7,7,8,7,7,7,8,7,6,7,7,7,8,7,8,8,8,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,8,7,7,7,7,7,6,7,7,6,6,6,7,5,6,6,6,5,6,7,8,9,9,11,12,12,11,12,13,15,16,17,17,20,22,20,19,20,20,20,22,21,22,22,21,24,24,24,23,25,23,24,25,24,25,24,25,25,23,23,25,25,24,24,24,23,23,25,23,21,24,23],[28,28,28,28,28,29,28,28,28,27,26,26,26,26,26,27,26,26,27,26,26,27,26,26,26,26,26,27,27,26,26,27,27,28,26,27,26,27,27,27,27,27,27,26,26,26,25,23,23,23,23,22,22,21,20,20,19,20,18,18,15,14,12,10,9,8,7,6,5,5,5,4,4,3,4,3,3,2,2,3,3,2,3,3,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,2,2,2,2,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,5,4,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,2,1,0,1,1,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,5,5,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,4,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,6,6,5,6,6,6,6,7,7,8,9,8,10,12,12,12,14,15,15,15,16,17,17,17,18,19,20,20,20,22,23,22,24,25,25,24,25,24,24,24,23,23,24,24,25,24,25,24,26,26,27,26,26,27,27,27,27,27,27,27,27,27,26,27,27,26,27,27,28,27,26,27,27,26,27,27,26,27,26,27,27,24,25,24,24,23,21,21,18,18,17,16,17,15,13,13,11,9,9,8,8,8,8,8,8,8,9,9,9,9,9,10,9,11,12,10,11,12,13,12,13,14,15,13,13,12,13,12,10,11,11,11,12,13,14,14,14,13,12,12,12,12,11,11,10,10,10,9,9,9,8,8,8,7,7,7,7,7,7,7,7,8,6,7,8,8,7,8,9,9,9,9,9,8,8,8,7,7,6,5,5,5,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,5,5,5,6,6,6,7,7,8,8,7,6,5,5,4,5,4,4,4,4,4,4,5,5,5,5,5,6,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,5,6,6,6,5,6,6,5,5,6,6,6,6,5,6,6,5,5,5,6,5,6,5,6,6,5,5,6,5,5,5,5,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,3,3,4,4,4,5,6,6,5,5,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,5,4,4,5,5,5,5,6,5,6,6,6,6,7,7,7,7,6,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,5,5,6,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,9,9,9,9,9,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,8,8,8,8,8,9,9,10,9,9,9,9,10,8,9,9,10,9,8,8,8,8,8,7,8,7,7,7,7,7,7,7,7,6,6,6,6,6,7,8,9,10,10,11,13,13,12,13,15,16,18,18,19,21,22,21,21,21,21,21,23,22,22,23,22,24,24,25,24,25,23,25,25,25,26,24,24,26,24,25,25,25,25,25,25,24,26,24,24,23,25,24],[28,28,28,28,28,29,28,28,29,27,27,28,27,27,27,27,27,27,28,27,27,27,27,27,27,28,27,27,28,27,27,28,28,28,28,28,27,28,28,28,28,27,27,27,27,26,23,24,24,22,22,23,22,20,20,21,19,20,19,19,16,14,12,9,9,7,6,5,5,5,5,4,4,3,4,3,3,3,2,3,2,2,2,2,2,2,2,2,3,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,2,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,6,6,5,6,6,6,6,6,7,7,9,8,9,11,11,12,14,15,17,15,16,18,18,16,18,19,20,20,21,24,23,23,24,25,25,25,26,23,23,25,24,23,25,25,25,24,24,25,26,26,27,26,26,27,27,27,28,27,27,27,27,28,27,28,28,28,28,28,28,28,28,28,27,27,28,27,27,28,27,27,27,25,25,25,25,24,22,20,20,19,19,17,17,15,14,13,11,10,9,8,8,8,8,7,7,8,8,8,9,9,9,9,9,10,10,10,10,10,12,11,12,13,12,12,12,12,12,11,11,11,10,11,11,12,12,13,12,12,11,11,11,10,9,9,9,9,9,8,8,8,8,7,8,7,7,6,7,7,6,6,7,7,6,6,7,8,7,7,8,9,8,9,9,9,8,7,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,6,6,7,7,7,5,5,4,4,4,4,3,3,3,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,1,2,2,2,3,3,3,4,4,5,5,4,5,5,5,6,5,5,5,5,4,4,4,3,4,4,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,7,6,7,7,6,7,7,6,6,6,7,6,6,7,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,6,6,5,6,6,6,6,7,6,7,6,7,7,7,7,7,8,8,8,8,8,8,7,8,7,7,7,7,7,7,8,7,7,7,7,7,7,8,8,7,8,8,8,9,8,8,8,9,9,8,8,8,8,8,7,7,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,6,6,7,8,9,10,11,13,13,12,13,15,16,18,18,19,21,21,21,20,21,21,21,24,22,23,24,22,25,24,25,24,25,23,25,25,25,26,24,25,25,23,24,25,25,24,25,25,23,25,24,24,23,23,23],[28,28,28,28,28,28,28,27,28,26,26,25,26,26,26,27,26,27,26,27,27,26,26,27,26,26,27,26,26,26,26,27,28,28,26,28,26,26,27,26,28,26,25,25,26,25,23,23,24,21,21,21,21,20,18,21,17,18,18,17,15,14,12,10,9,8,7,7,6,6,6,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,4,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,4,4,4,4,4,3,2,2,2,3,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,4,4,4,4,5,5,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,1,2,1,1,0,1,2,2,2,2,3,2,2,2,2,2,2,2,3,2,2,3,3,3,4,4,4,4,3,4,4,4,3,4,4,4,4,4,5,4,4,5,5,6,6,6,6,6,6,6,7,7,6,6,6,6,5,4,4,5,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,5,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,5,5,5,4,5,5,4,5,5,5,5,5,5,6,5,5,5,5,4,4,5,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,8,8,7,8,8,9,9,8,8,8,7,7,7,6,7,7,7,7,7,8,8,9,9,10,11,12,12,13,15,15,14,16,17,16,17,18,18,18,20,20,21,21,21,23,24,25,24,24,24,22,23,24,23,23,25,24,25,24,23,25,26,27,25,26,26,26,27,27,26,26,27,27,26,27,27,27,26,27,27,28,27,27,27,26,26,27,27,26,27,26,26,27,25,24,24,24,22,22,21,18,19,17,16,16,14,13,13,11,10,9,9,8,9,8,8,9,10,11,11,10,11,12,12,12,12,13,13,12,13,15,14,14,15,15,15,15,15,14,13,13,13,13,14,13,15,14,15,15,15,14,13,14,13,12,11,12,12,11,11,11,10,9,9,9,9,9,7,8,9,9,8,9,10,8,8,10,10,9,9,10,11,11,11,11,10,10,9,8,7,7,6,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,6,5,5,5,6,6,6,7,7,8,8,7,6,6,6,5,5,5,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,8,7,6,6,7,6,6,7,7,6,6,7,7,6,6,6,7,7,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,4,4,4,4,3,3,3,2,3,3,2,2,2,3,3,3,4,4,4,5,6,6,5,5,6,6,6,6,6,6,6,6,5,4,4,5,5,5,5,5,5,5,5,6,6,5,6,6,6,7,7,7,8,8,9,8,8,8,8,7,7,8,8,7,8,7,8,7,7,7,7,7,6,7,7,6,6,6,7,6,6,6,6,6,7,7,7,7,7,8,9,8,9,9,9,9,9,10,10,10,10,9,9,9,9,8,8,9,8,8,9,9,8,7,8,8,8,10,10,10,9,10,10,9,10,10,10,10,10,11,10,10,9,10,10,9,9,10,9,8,9,10,8,8,9,8,8,8,9,8,7,8,8,7,7,7,8,9,10,10,13,14,14,13,14,16,17,18,20,20,21,22,22,21,21,22,21,23,22,21,23,23,23,24,25,23,24,23,25,26,24,26,24,24,24,25,24,25,25,24,25,25,23,24,25,23,22,23,25],[27,27,27,27,27,28,27,27,28,26,26,26,26,26,25,26,26,26,26,26,26,27,26,26,27,26,26,26,26,26,26,26,27,27,25,27,26,26,27,26,27,25,25,26,25,25,23,23,23,21,22,21,22,20,19,21,18,20,18,17,16,14,12,11,10,10,9,8,9,8,8,7,7,7,6,6,5,5,4,5,5,4,4,5,4,3,4,4,4,3,3,3,3,3,3,3,3,2,3,3,5,3,3,4,4,3,4,4,4,5,4,4,3,2,3,3,4,5,5,5,5,4,4,5,4,4,4,4,4,5,5,4,5,5,5,6,6,5,4,4,4,4,3,4,4,3,3,3,3,3,3,4,3,2,3,2,1,0,1,2,2,3,3,2,3,4,3,3,3,4,3,4,4,5,5,4,5,5,5,5,5,5,6,5,5,6,6,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,8,7,7,7,7,6,6,5,5,5,5,4,4,5,4,4,4,4,4,5,4,5,5,6,5,6,6,5,5,6,6,5,6,6,5,5,6,6,5,5,6,6,6,6,6,6,7,6,7,7,6,7,7,7,7,7,7,7,7,7,7,6,7,6,7,6,7,7,6,7,7,7,7,7,6,7,6,6,6,4,5,5,4,5,6,5,5,6,7,5,6,7,7,7,7,7,8,8,7,8,8,8,8,9,8,9,8,9,9,9,9,9,9,9,10,10,10,10,9,9,9,8,8,9,9,9,9,9,9,9,11,10,11,12,13,13,15,15,16,15,17,18,17,18,19,20,19,21,20,23,23,22,24,25,25,25,25,25,23,24,24,23,24,24,25,25,25,24,27,27,27,26,26,27,27,27,27,27,27,27,28,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,27,26,27,27,26,25,24,24,23,22,22,19,20,19,18,18,16,14,15,13,12,11,10,10,11,10,11,11,11,12,12,12,13,13,13,12,13,15,14,13,14,16,14,15,15,16,15,15,15,15,14,14,14,13,14,14,16,16,15,16,15,15,14,15,14,13,14,14,13,13,13,13,12,11,11,12,10,11,10,10,11,11,11,11,11,10,10,11,11,10,11,11,11,11,12,12,11,11,11,10,10,9,9,8,8,9,8,7,8,7,7,7,8,8,8,7,7,8,7,7,7,8,7,7,7,7,7,7,8,7,7,7,7,7,7,7,8,8,9,9,8,8,7,7,7,6,6,5,5,5,5,5,5,6,6,6,6,6,6,5,6,6,5,5,6,6,5,5,6,5,5,6,7,5,6,7,7,6,7,7,7,7,7,8,7,8,7,8,8,8,9,9,9,9,10,9,9,9,9,8,8,9,8,8,9,9,8,8,8,8,9,8,8,9,8,8,8,9,8,8,7,8,7,7,7,7,7,7,7,6,5,5,5,5,4,4,3,3,3,3,2,2,3,4,3,5,5,5,6,7,8,7,7,8,8,8,7,7,7,7,8,6,6,6,7,7,7,7,7,8,7,8,8,8,8,8,8,9,9,9,10,10,10,10,10,9,10,10,10,10,11,10,10,9,9,10,9,9,10,9,9,9,9,8,8,8,8,8,8,8,8,8,9,9,9,10,9,9,10,10,10,11,11,11,10,10,11,11,11,12,11,10,10,10,10,10,11,10,9,11,10,10,10,10,10,10,11,11,11,11,11,12,11,11,11,11,12,12,13,11,11,11,12,12,11,11,12,11,10,11,12,10,10,11,10,10,10,10,10,9,9,9,9,9,9,10,11,12,12,14,15,15,15,16,17,19,20,21,20,22,21,24,22,23,22,23,24,24,22,25,23,23,23,25,24,24,23,25,26,24,27,26,25,24,25,26,25,24,24,26,26,24,26,25,24,23,25,24],[28,29,29,29,29,29,29,29,29,28,27,27,28,27,27,27,28,28,28,28,27,28,28,27,27,28,27,27,28,28,26,28,28,29,27,29,27,28,28,27,28,27,26,27,27,26,24,24,25,22,22,22,22,21,21,21,19,20,19,19,17,15,12,10,9,8,7,7,6,6,6,5,6,5,5,4,4,3,3,3,3,3,3,4,3,3,4,4,4,4,3,3,3,3,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,4,2,3,2,3,3,3,3,4,3,3,3,4,3,3,4,4,3,4,4,4,4,5,5,6,5,5,4,4,4,3,3,3,4,3,2,3,2,2,2,2,2,2,1,1,1,1,0,1,1,3,3,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,7,6,6,5,5,5,5,4,4,4,4,3,3,4,3,3,4,4,3,3,4,4,3,4,4,4,4,5,5,5,4,4,5,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,7,6,6,6,6,6,6,6,6,6,7,6,6,6,7,6,6,6,6,7,6,5,6,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,6,5,6,5,6,6,6,6,7,7,7,7,7,8,7,8,9,9,8,9,8,9,9,8,9,8,8,8,7,8,8,8,7,8,9,8,10,9,10,12,13,13,14,16,16,16,17,20,19,18,21,22,21,22,24,24,25,24,25,26,27,25,26,25,24,25,24,22,25,25,25,26,25,26,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,28,27,27,28,27,27,28,27,26,27,24,25,25,24,24,22,21,20,19,19,17,17,15,15,13,12,11,11,9,9,9,10,10,9,10,10,11,11,11,11,12,12,12,13,13,13,14,15,13,15,16,16,14,15,14,15,14,12,13,13,13,14,14,14,15,14,15,13,14,13,12,12,12,12,11,12,11,11,10,9,10,10,10,9,9,8,10,9,8,9,10,9,10,11,11,10,10,11,12,11,12,12,11,10,10,9,9,8,8,7,7,7,6,7,7,6,6,7,6,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,6,7,7,7,8,8,8,9,9,7,7,7,7,6,7,6,5,6,6,5,6,6,6,7,6,7,6,5,6,6,5,5,6,5,5,5,5,4,5,5,5,5,5,6,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,8,7,8,8,8,7,7,7,7,7,8,7,8,7,7,7,8,7,7,7,7,7,7,7,8,7,7,6,7,6,6,6,6,5,5,4,4,3,3,4,3,3,2,2,3,2,2,2,3,4,4,5,5,6,7,7,6,6,7,7,6,6,6,6,6,6,5,5,5,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,9,8,9,10,8,9,9,8,8,9,10,8,8,8,9,8,8,8,8,8,8,7,8,7,7,6,7,6,6,7,7,7,8,8,8,8,8,9,9,8,10,10,9,9,9,10,10,10,10,10,9,10,9,9,9,9,9,8,8,9,8,8,8,9,9,10,10,10,9,10,11,10,10,10,10,10,11,12,10,11,10,11,11,10,10,11,10,10,10,11,8,9,10,9,8,9,10,8,8,9,9,8,8,9,10,11,11,12,14,15,15,14,15,18,19,20,21,20,23,23,24,23,23,22,24,24,24,23,25,23,25,25,26,25,25,24,27,26,25,27,25,26,25,26,26,26,26,25,27,26,24,26,26,25,24,25,25],[27,27,26,27,27,27,27,27,27,26,26,26,25,26,26,26,26,26,26,26,26,27,26,27,26,26,27,27,26,27,26,26,28,27,25,27,26,26,27,26,27,25,25,25,26,24,22,23,23,20,21,22,21,19,20,21,18,19,19,17,15,15,12,11,10,9,9,8,6,7,6,8,7,7,6,5,5,4,4,4,5,4,4,5,5,5,6,6,6,5,5,4,5,4,4,5,4,3,4,4,3,3,4,4,3,4,4,4,4,5,4,3,3,3,3,3,3,4,5,5,5,4,4,4,4,4,5,4,4,5,5,5,6,6,6,7,6,7,6,5,5,6,5,4,5,4,4,4,4,3,3,4,3,2,2,4,2,1,1,0,1,5,2,2,2,3,3,3,3,4,4,3,5,5,5,4,5,5,5,6,5,6,6,6,6,7,6,6,6,7,7,7,8,7,7,8,8,8,8,9,8,8,9,9,8,9,9,8,7,6,6,7,6,6,6,6,6,5,6,7,5,5,6,6,6,5,6,5,5,5,5,5,6,6,6,7,5,5,6,5,5,6,6,5,6,6,6,6,7,6,6,7,7,7,7,7,8,8,8,8,7,8,8,7,8,8,8,7,8,9,8,7,9,8,8,9,8,8,8,8,7,6,7,6,5,6,7,6,6,7,8,5,7,8,7,6,7,8,8,7,8,8,8,9,9,9,9,10,9,9,10,11,10,10,11,11,11,11,10,11,10,10,10,10,9,8,9,10,8,9,9,9,10,10,11,12,12,13,15,15,15,15,16,19,16,16,19,19,18,21,21,22,22,21,24,23,24,25,26,25,23,23,23,23,25,24,25,25,25,24,26,26,28,26,27,26,27,27,27,27,27,27,27,26,27,27,27,26,27,26,28,26,27,27,26,26,26,27,26,27,26,25,26,25,23,24,23,21,20,20,18,18,17,16,16,14,15,14,12,12,11,10,10,12,10,11,12,11,12,13,13,13,13,14,13,14,16,15,15,15,16,15,16,17,17,17,17,17,16,15,16,15,16,16,15,17,16,16,17,15,15,14,16,14,13,13,15,14,13,14,13,12,12,11,13,11,11,12,11,12,11,12,12,12,11,12,12,12,12,13,13,12,13,13,13,12,12,12,11,10,11,9,9,8,8,9,9,8,9,9,9,9,9,9,9,9,9,8,8,9,9,9,8,9,9,8,8,9,9,9,8,8,8,9,8,9,9,9,10,10,9,8,8,9,8,7,7,6,7,6,7,7,8,6,7,6,7,6,6,7,6,6,6,7,6,6,7,7,6,6,8,7,6,8,9,7,7,8,8,7,8,9,9,8,9,9,9,9,9,10,10,10,10,11,10,10,11,10,9,10,10,10,9,10,10,10,10,9,10,10,9,10,10,10,9,9,10,9,9,9,9,8,8,8,8,7,7,5,6,5,5,4,4,4,3,4,3,2,4,3,2,2,4,4,5,5,6,6,7,7,6,6,7,6,8,6,6,6,6,7,5,6,6,7,7,7,8,9,9,8,10,10,9,10,10,9,10,11,10,11,11,10,10,10,10,10,11,11,11,10,11,11,10,10,11,10,10,11,9,10,10,10,9,8,8,8,9,9,9,9,10,10,10,10,10,12,10,10,11,11,10,10,11,11,10,11,10,11,11,10,11,11,10,10,11,11,10,10,11,10,10,11,11,11,10,12,11,11,12,11,12,11,11,11,11,12,12,13,12,12,11,14,12,12,12,12,12,11,11,12,12,11,12,11,12,11,11,12,11,10,11,10,12,10,11,11,13,13,15,16,17,17,16,18,19,20,22,20,23,22,22,22,23,22,23,23,24,23,25,23,24,24,25,25,26,24,25,27,25,26,25,26,25,24,24,27,26,25,26,26,25,26,26,25,23,24,25],[28,28,28,28,28,28,28,28,28,27,26,26,26,27,26,26,26,27,26,27,27,27,27,27,27,27,27,26,27,26,26,27,28,28,26,28,27,27,27,26,27,26,26,26,26,25,23,22,24,21,21,21,22,21,20,20,17,19,19,17,15,14,13,9,8,7,6,5,5,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,5,5,6,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,5,4,4,4,5,5,5,5,5,7,6,6,6,7,6,6,7,7,7,7,6,5,5,4,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,5,6,5,5,6,6,5,4,4,4,4,5,4,4,5,5,4,5,5,5,5,6,6,6,5,5,5,4,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,7,7,7,7,7,6,5,6,7,6,5,6,7,7,7,8,9,11,11,12,14,15,16,15,16,18,17,17,19,19,19,21,21,22,22,23,25,23,24,23,25,24,22,24,24,22,24,23,24,24,24,24,26,26,27,26,27,27,27,27,27,27,27,27,26,27,27,27,27,27,27,26,26,26,26,26,26,26,27,26,26,27,26,25,26,24,25,25,24,23,22,20,19,19,16,16,16,14,14,12,11,10,9,8,8,7,8,8,8,9,9,10,10,10,10,11,11,12,12,12,11,13,13,13,14,15,15,15,15,14,14,13,12,12,12,12,13,13,14,15,14,14,13,11,12,12,11,11,11,11,10,10,10,9,8,8,8,8,7,7,7,8,7,7,8,8,8,8,9,9,8,9,10,10,11,11,11,10,10,9,8,7,7,6,6,5,5,5,5,5,5,5,6,6,5,6,6,6,5,6,6,5,5,5,5,5,5,5,4,4,5,5,4,4,5,6,6,6,7,7,8,7,6,5,5,4,5,5,4,4,4,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,4,3,4,4,3,4,4,4,4,5,5,4,5,5,6,5,6,6,6,6,6,6,6,6,6,6,7,6,6,6,7,6,6,5,6,6,5,5,6,6,5,5,6,5,6,5,5,5,5,4,4,4,4,3,3,3,3,2,3,2,2,2,2,2,2,1,2,3,3,4,4,4,5,5,6,4,5,5,5,6,5,5,4,5,4,4,4,3,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,6,7,7,8,8,6,7,8,7,7,8,8,7,7,7,7,7,6,6,7,6,6,6,6,5,6,5,5,5,5,5,5,5,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,9,8,8,8,8,7,7,8,8,7,7,8,7,7,7,7,7,8,8,9,8,9,9,8,9,8,9,9,9,10,9,10,9,10,10,9,9,10,9,8,9,9,7,8,9,8,7,8,8,8,7,8,8,7,7,8,9,9,11,12,14,15,15,14,16,17,19,19,20,20,22,22,24,22,23,21,24,24,23,24,24,24,26,25,25,25,26,24,25,26,25,25,25,25,25,25,26,26,26,25,26,25,24,25,25,25,23,24,25],[29,28,28,29,29,29,29,29,29,27,28,27,28,27,27,27,28,28,27,28,28,27,28,28,27,27,28,27,28,28,27,28,29,29,28,28,28,28,28,28,29,27,27,26,27,26,24,25,25,22,23,22,23,21,21,21,20,20,19,20,17,15,12,10,8,6,6,5,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,1,2,1,2,2,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,6,6,5,6,6,6,6,5,5,4,4,4,4,4,3,4,3,3,3,3,3,2,2,3,2,2,2,3,2,2,2,3,2,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,4,4,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,3,4,4,4,4,4,5,5,5,5,6,5,5,6,6,6,6,7,7,7,6,7,7,6,6,6,5,6,7,6,5,6,7,6,7,8,9,12,12,12,16,15,17,15,17,19,18,18,20,21,21,22,23,24,25,23,26,26,26,26,26,24,25,26,24,24,25,24,25,24,25,24,27,27,27,26,27,27,27,27,28,27,26,27,27,27,27,28,27,27,27,27,28,27,27,27,27,26,27,27,26,27,26,26,27,25,26,26,24,23,22,19,21,20,17,17,16,15,14,13,12,10,9,8,7,7,7,8,7,8,8,8,9,9,9,9,10,10,11,10,11,11,12,11,12,13,13,13,13,12,12,11,11,11,11,11,12,12,12,13,13,13,12,11,11,10,10,9,9,10,10,9,8,8,8,7,7,7,6,6,6,7,7,6,6,7,7,7,7,8,7,8,8,9,9,9,9,9,8,8,7,6,6,5,5,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,5,5,4,4,5,6,5,6,7,7,7,7,6,5,5,4,4,4,4,3,4,4,4,5,5,4,5,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,5,5,5,6,5,5,5,5,4,4,4,4,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,5,5,4,4,5,5,6,5,5,5,4,4,3,3,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,4,5,4,5,5,6,5,6,6,6,6,6,6,7,6,7,7,7,7,7,8,8,8,7,7,7,7,7,7,7,7,7,6,7,7,7,6,6,7,7,7,8,8,8,8,8,7,8,8,8,8,8,9,8,8,8,8,8,7,7,8,7,6,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,8,9,10,10,12,13,13,12,14,15,16,19,21,20,23,23,23,21,23,22,24,25,24,24,26,24,25,26,26,25,26,25,26,26,26,28,25,26,27,24,25,26,26,26,26,27,26,26,26,25,25,26,25],[28,28,28,28,28,28,28,28,28,27,26,25,27,27,26,26,26,26,26,27,27,26,26,27,26,27,27,26,27,26,25,27,27,28,26,27,26,26,27,26,27,25,25,26,26,25,23,23,23,20,22,22,20,21,21,20,18,20,18,18,16,14,12,9,8,6,5,5,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,3,2,2,3,3,3,3,2,3,3,2,2,3,3,2,3,3,2,3,3,3,3,3,3,3,3,4,4,3,3,2,2,2,2,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,4,4,5,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,6,6,5,5,6,6,5,6,6,6,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,7,6,6,6,5,6,6,5,5,6,6,6,7,8,10,13,12,13,16,17,16,15,17,18,17,17,19,19,18,20,21,21,21,21,22,23,24,23,24,23,22,22,22,22,23,22,24,23,21,23,25,25,26,24,26,26,26,26,27,26,25,26,26,25,26,26,26,26,27,26,27,26,27,26,26,26,26,26,25,26,25,24,26,24,24,24,24,22,21,20,18,19,18,16,17,14,13,13,11,10,9,7,6,7,8,7,8,8,8,8,8,8,9,9,9,10,10,10,10,10,11,11,12,13,13,13,13,11,12,11,11,10,10,11,11,11,12,13,11,13,12,10,10,9,10,9,9,9,9,8,8,8,8,7,7,7,6,6,7,7,6,6,6,7,6,6,7,7,7,7,7,8,8,9,8,8,8,7,6,6,5,5,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,4,5,5,6,7,7,7,6,6,5,5,4,4,4,4,3,4,4,4,4,5,4,5,4,4,4,3,4,4,3,3,4,3,3,4,3,3,3,4,3,4,4,4,3,3,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,6,5,6,5,6,5,6,5,5,5,5,5,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,5,4,5,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,6,6,7,6,6,6,6,6,6,6,5,5,5,5,5,4,5,4,5,5,5,5,5,6,5,6,6,6,6,6,7,6,6,7,7,7,7,8,8,7,7,7,7,7,7,6,7,7,7,6,7,7,6,6,6,6,7,7,8,8,8,8,8,7,8,8,8,8,8,8,8,8,7,8,8,7,7,8,7,6,7,7,7,6,7,6,6,6,6,6,6,6,6,5,6,6,7,8,10,10,12,13,13,12,13,15,16,17,19,18,22,22,22,20,22,21,21,22,22,23,24,23,24,24,25,24,24,23,26,26,24,26,25,25,25,25,24,25,24,24,24,24,23,25,25,24,23,24,24],[28,28,28,28,27,28,28,27,28,26,26,26,26,26,26,26,26,26,27,26,26,27,26,26,26,27,27,27,27,26,26,27,27,28,27,28,27,28,28,27,28,26,26,26,26,26,24,23,24,21,21,21,22,20,20,21,18,19,18,18,15,13,11,8,7,6,5,5,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,6,5,5,6,5,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,6,6,6,6,6,6,6,5,5,6,5,5,5,6,6,7,7,8,10,10,11,13,14,15,14,15,18,16,16,18,18,18,18,20,21,21,21,22,23,24,23,24,23,21,23,22,22,22,23,24,24,23,23,26,25,26,25,26,26,27,26,27,27,26,26,26,26,26,26,26,26,26,26,27,26,26,26,26,25,26,25,25,26,24,24,25,22,24,24,22,22,20,19,17,18,16,15,14,13,12,11,10,8,7,7,7,7,7,7,7,7,8,8,8,8,8,9,9,9,10,10,10,11,11,11,12,12,13,12,12,12,11,10,10,10,9,10,11,11,12,12,12,12,11,10,11,10,9,9,9,9,8,8,8,7,7,7,7,7,7,6,7,7,6,7,7,7,6,7,7,7,7,7,7,8,8,8,8,8,7,7,6,6,6,5,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,5,5,5,6,6,7,7,6,6,5,4,4,4,4,3,3,4,4,4,4,4,5,5,5,5,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,5,6,6,6,5,6,6,5,6,6,6,5,5,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,4,4,5,5,4,4,5,5,5,4,4,4,4,4,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,5,5,5,5,4,5,4,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,7,7,7,7,6,7,7,6,6,7,7,6,6,6,6,6,7,7,7,7,7,8,7,7,7,8,8,8,8,8,8,8,9,8,7,7,8,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,5,6,6,7,7,9,9,10,12,12,11,12,13,16,17,17,17,20,21,20,20,20,21,21,22,22,21,23,21,23,23,24,23,24,22,24,25,24,26,24,24,23,23,24,24,23,23,24,24,23,24,24,22,22,23,24],[28,28,28,28,28,29,28,28,28,27,27,27,27,26,26,27,27,27,26,27,26,26,27,27,27,27,27,27,27,26,26,28,27,28,27,28,27,27,27,27,27,27,26,26,26,26,24,23,25,23,22,21,22,20,20,21,19,19,18,18,15,14,11,8,7,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,4,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,5,5,4,5,4,5,5,4,4,5,5,6,7,7,8,11,11,11,15,14,16,17,16,18,18,17,19,19,20,21,22,23,24,22,24,25,24,25,25,23,23,24,23,23,23,24,24,24,24,24,26,26,27,26,26,27,27,27,27,26,27,27,27,27,26,27,27,27,27,27,27,27,27,26,27,25,26,27,25,27,26,26,27,24,25,25,23,24,22,21,19,19,18,16,16,14,13,11,10,8,7,6,6,5,6,6,6,6,6,6,7,7,7,7,8,8,9,8,9,10,10,10,11,11,12,11,11,10,11,10,9,9,8,9,10,10,11,11,11,11,10,10,9,9,8,8,8,8,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,7,7,8,7,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,5,5,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,2,2,1,2,2,3,3,3,3,4,4,5,4,4,4,5,5,5,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,6,6,6,6,6,6,5,6,6,5,6,6,5,5,5,5,5,6,6,6,6,6,7,6,7,7,7,7,7,7,6,7,6,7,7,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,4,4,5,6,7,8,9,10,12,12,11,12,13,14,17,18,18,21,20,21,20,20,21,21,23,22,22,23,22,24,25,26,24,25,25,26,25,25,26,24,24,25,23,24,25,25,24,24,25,24,25,25,23,22,24,24],[29,29,29,29,29,29,29,29,29,28,28,27,28,28,28,27,28,28,28,28,28,28,28,28,28,28,29,28,29,28,28,29,29,29,28,29,28,28,28,28,28,27,27,27,27,27,25,24,25,22,24,23,23,22,21,22,19,20,19,19,16,15,11,9,7,6,5,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,5,5,5,5,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,5,5,5,4,5,5,5,5,5,5,5,6,7,8,11,11,12,14,14,16,15,16,19,18,17,19,20,20,21,22,23,24,22,25,25,25,25,26,24,25,25,24,24,24,24,25,24,25,25,26,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,27,27,27,26,27,27,26,28,27,26,28,26,26,26,25,25,22,22,20,21,18,16,16,14,13,12,10,8,7,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,9,10,9,10,11,11,10,11,10,10,9,9,9,9,9,9,9,10,10,10,10,10,9,9,8,8,8,8,8,8,7,7,7,6,6,6,5,5,5,5,6,5,5,6,6,5,6,6,6,6,6,6,7,7,7,7,7,7,6,5,5,5,4,4,3,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,5,5,5,5,6,7,6,5,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,4,4,4,5,4,4,4,5,4,4,4,4,4,4,5,5,5,4,5,5,5,4,4,5,4,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,5,5,4,4,4,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,4,5,5,5,5,5,6,5,5,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,5,6,6,6,6,6,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,7,7,9,9,11,12,11,11,12,13,14,16,18,19,22,22,20,19,21,21,20,24,21,23,24,23,26,25,26,25,27,25,26,26,26,26,25,26,26,24,24,26,26,25,26,25,24,25,26,24,23,26,24],[27,28,27,28,27,28,28,27,28,26,25,25,25,26,25,26,25,26,26,26,26,26,26,26,26,26,26,27,27,26,25,26,26,28,26,27,26,26,26,26,27,26,24,25,26,25,23,22,23,20,21,21,20,20,19,20,18,19,18,16,14,13,10,8,7,6,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,5,5,4,4,5,5,4,5,6,5,5,5,4,4,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,3,2,2,3,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,3,4,4,4,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,6,6,7,8,11,11,11,14,14,17,14,15,18,17,15,17,19,17,18,20,21,20,20,22,22,23,23,23,22,21,23,22,21,22,22,24,22,22,23,24,24,26,24,26,26,25,26,26,25,25,25,25,26,25,25,26,26,25,25,26,25,25,25,25,25,25,25,25,26,24,24,25,23,23,24,23,22,21,20,17,18,16,14,15,12,12,11,9,8,7,7,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,9,9,9,10,11,11,11,11,9,10,9,9,8,8,9,9,9,10,11,10,10,9,9,8,8,8,8,7,8,7,7,7,7,6,6,6,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,6,6,5,5,5,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,5,5,5,6,6,7,6,5,4,4,3,3,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,4,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,5,5,6,6,5,6,6,6,6,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,6,7,6,6,6,6,6,6,6,5,6,6,5,5,5,6,6,6,6,6,6,7,7,6,7,7,7,7,7,8,7,7,7,8,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,7,7,9,9,10,11,11,10,11,12,14,16,16,16,20,21,19,18,20,20,20,23,20,22,23,21,23,24,25,23,25,22,25,24,24,25,23,24,25,24,23,24,24,23,23,24,22,24,24,23,22,24,23],[28,28,28,28,28,28,28,28,28,27,26,27,27,26,26,27,27,27,27,27,27,27,27,27,27,27,26,27,27,27,26,28,27,28,28,28,27,28,28,27,28,27,27,27,27,26,24,23,24,22,22,22,22,20,19,20,19,18,16,18,14,13,10,8,7,6,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,5,5,6,6,8,10,11,11,13,15,15,13,15,16,16,16,18,18,18,19,20,21,22,20,23,23,24,24,24,22,22,22,22,22,22,24,24,23,22,23,24,26,26,24,25,26,26,26,26,26,26,25,26,26,26,26,26,26,26,26,26,25,26,25,26,25,27,26,24,26,26,25,26,24,24,24,24,23,20,20,18,18,16,15,14,13,12,10,9,7,6,6,6,5,5,5,6,5,6,6,7,6,7,7,8,8,8,8,9,9,9,9,9,10,10,10,10,10,9,9,8,8,8,8,8,9,9,9,10,9,8,8,8,7,7,8,7,7,6,6,6,6,5,5,6,5,5,5,5,5,5,4,5,5,5,5,6,5,5,6,6,6,6,7,6,6,5,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,5,5,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,6,6,6,6,6,5,6,6,5,5,5,6,5,5,5,5,4,5,5,4,4,5,4,4,4,5,6,7,7,7,9,11,11,10,11,12,13,14,16,16,19,20,18,18,19,19,19,20,20,20,22,21,23,23,25,23,23,23,24,23,23,25,23,22,22,22,24,24,23,23,23,23,22,24,23,22,22,24,22],[28,28,28,28,28,29,28,28,28,27,27,27,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,27,27,28,28,28,28,28,27,28,28,28,28,27,27,27,27,27,25,24,25,24,23,22,23,21,20,22,20,20,19,19,16,14,11,8,7,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,1,2,2,2,2,2,2,2,2,3,2,2,3,3,4,4,4,4,4,4,4,4,4,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,2,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,4,4,4,4,5,4,4,4,5,5,6,6,8,11,12,12,15,15,16,16,17,19,18,18,20,20,21,21,21,24,24,22,24,25,24,25,26,24,24,23,22,22,23,23,25,24,23,24,25,26,27,25,26,26,26,27,26,26,26,26,26,26,26,26,27,26,26,26,27,26,27,27,27,26,27,26,26,27,26,26,27,24,26,26,25,25,23,21,20,20,17,16,15,14,12,10,10,8,7,6,6,5,6,6,5,6,6,6,7,7,7,7,8,8,9,8,9,8,9,9,10,11,10,10,11,9,10,9,9,8,9,9,9,9,9,10,10,10,9,9,8,8,8,7,7,7,7,7,6,6,6,5,5,5,5,4,5,5,4,4,5,5,5,5,5,6,5,6,6,6,7,7,7,7,6,6,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,5,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,3,3,3,2,2,3,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,6,6,6,6,6,7,6,7,7,6,7,7,7,7,7,6,7,7,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,4,5,4,4,4,5,6,7,8,8,10,12,11,10,12,14,14,16,18,19,22,22,21,19,21,21,20,24,21,22,24,22,25,25,25,25,26,25,26,25,26,26,25,25,27,24,24,26,26,25,26,25,24,25,26,24,22,26,25],[29,28,28,29,28,29,28,28,29,27,27,27,27,27,28,27,27,28,28,28,28,28,27,28,28,27,27,28,28,27,27,28,28,29,28,28,26,28,28,27,28,27,26,27,26,26,25,24,25,22,23,23,23,21,21,21,19,21,19,19,15,13,11,8,7,6,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,1,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,4,4,4,4,4,4,4,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,4,4,5,5,4,4,4,5,5,4,4,5,5,5,6,6,8,10,11,11,14,15,16,15,17,19,17,17,19,21,20,20,22,22,22,23,24,24,25,25,25,23,23,24,22,23,24,24,24,24,24,24,25,25,27,25,26,26,26,27,26,26,26,27,26,26,27,27,26,27,27,27,27,27,27,26,26,26,26,27,26,27,26,25,28,25,25,26,24,25,23,22,20,20,18,15,15,14,12,11,9,8,7,6,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,9,9,9,9,8,8,8,8,8,8,8,8,8,9,9,8,9,8,8,7,7,7,7,6,7,6,6,6,6,5,5,5,4,5,4,5,5,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,5,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,3,4,4,4,4,4,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,4,3,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,6,7,8,9,10,10,10,11,12,13,15,16,17,19,20,19,17,19,19,20,21,20,20,22,21,24,23,25,24,25,24,25,25,25,27,24,25,25,24,24,25,25,24,25,24,22,24,24,23,21,24,23],[27,27,27,27,26,28,27,26,28,25,26,25,25,25,24,27,25,25,26,25,25,26,25,25,26,26,25,26,26,24,25,26,25,27,26,26,25,26,27,26,26,25,24,25,25,24,24,22,22,21,21,20,20,19,18,19,17,17,16,15,13,12,9,7,7,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,2,2,1,2,2,2,2,1,2,2,1,1,1,1,1,1,2,1,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,5,6,7,9,10,10,12,13,13,13,14,15,15,14,16,16,17,18,18,19,20,21,20,21,22,23,24,23,21,21,22,21,21,22,24,23,22,22,23,24,26,23,24,25,25,26,25,25,25,26,25,25,26,25,26,25,26,26,26,26,25,25,25,25,25,25,25,26,24,24,25,22,22,23,22,21,20,19,17,17,16,14,14,12,10,10,8,7,6,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,9,9,8,9,8,8,7,7,7,6,7,7,7,8,9,8,8,7,7,7,6,6,6,6,5,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,6,6,5,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,4,5,4,4,5,5,4,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,5,5,6,5,5,5,5,5,5,5,4,5,5,4,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,6,7,7,8,9,9,9,10,11,12,13,14,15,17,20,18,17,18,18,18,20,19,19,21,19,22,21,23,21,22,22,23,22,22,25,22,22,23,22,22,23,22,23,21,22,20,23,22,21,20,22,22],[29,28,28,29,28,29,28,27,28,27,27,27,26,26,26,27,26,26,27,26,26,26,26,26,26,27,26,27,27,26,25,27,27,28,26,27,26,27,27,27,27,26,25,26,26,26,24,23,23,23,23,22,22,20,19,19,18,18,17,17,14,12,10,7,6,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,4,4,4,3,4,4,4,4,4,5,5,5,6,7,8,10,11,12,13,14,13,15,15,15,15,17,17,17,19,18,20,22,21,22,23,24,24,24,22,23,23,24,22,23,23,25,24,24,23,24,25,26,25,26,26,25,26,25,25,25,25,25,26,26,26,26,26,27,26,27,27,27,26,27,24,26,26,25,26,26,26,27,23,24,24,24,24,22,19,19,18,16,15,13,12,11,10,8,7,6,5,5,5,5,5,5,5,5,5,6,6,5,6,6,7,7,7,7,8,7,8,9,9,9,9,9,8,8,8,7,7,7,7,8,8,8,9,8,8,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,6,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,5,6,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,3,4,3,3,4,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,4,3,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,6,6,6,6,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,3,4,5,6,7,7,8,10,10,9,10,11,12,15,17,17,18,21,18,16,18,19,19,21,20,20,21,21,24,23,23,23,24,23,24,24,23,26,22,23,23,23,23,24,23,24,23,23,22,23,23,22,21,24,24],[28,29,29,29,29,29,28,28,28,27,27,28,27,27,27,27,27,27,27,27,26,27,27,27,26,27,27,27,28,26,26,27,27,28,27,28,27,28,27,27,28,27,26,27,26,26,26,24,25,24,24,22,23,21,21,21,20,20,18,19,16,14,11,9,7,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,1,2,2,1,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,5,4,4,4,4,4,4,4,4,4,5,5,6,6,8,10,11,11,13,15,16,15,16,18,18,17,19,20,20,21,21,24,24,23,24,25,26,25,26,24,24,24,23,23,23,24,25,23,24,24,24,25,26,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,27,26,27,27,27,27,26,25,26,27,26,26,26,26,27,24,25,25,24,24,23,20,20,20,18,16,16,14,12,10,9,8,7,6,5,5,5,5,5,6,6,6,7,6,6,7,7,7,8,7,8,8,8,9,9,9,9,9,10,9,9,8,8,8,8,8,9,9,9,9,9,9,8,8,8,7,7,7,7,7,7,6,6,6,5,5,5,4,4,4,4,5,4,4,5,5,4,4,5,5,5,5,6,6,6,7,7,6,6,5,4,4,3,3,2,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,6,6,6,5,5,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,7,7,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,6,6,6,6,6,6,6,7,6,6,6,7,7,6,6,6,7,6,5,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,4,5,6,7,7,9,10,10,10,11,12,13,15,16,18,19,20,18,16,18,20,18,23,19,21,22,21,24,24,23,24,25,23,25,24,24,25,24,24,25,22,23,25,25,24,25,24,22,24,25,22,20,25,25],[29,29,28,29,28,29,28,28,28,27,27,27,26,26,26,27,26,26,27,26,27,27,26,26,27,27,26,26,27,25,26,27,27,28,26,27,25,27,27,26,26,26,25,26,26,25,24,22,23,22,22,21,21,20,19,19,19,18,17,16,14,12,10,7,6,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,6,7,9,10,9,12,13,14,13,14,16,15,15,17,17,18,18,19,21,22,21,22,23,23,24,25,22,22,22,22,22,22,23,24,22,23,23,25,25,27,24,25,26,25,26,25,25,26,26,25,26,26,26,26,26,26,26,27,26,26,25,26,25,27,27,25,26,25,24,27,23,24,24,23,23,21,20,19,18,17,15,15,14,11,10,8,7,6,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,7,6,7,7,7,7,8,8,8,8,8,7,8,7,7,7,7,7,8,8,8,8,7,7,8,7,7,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,5,5,4,4,3,3,3,3,2,2,2,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,5,5,6,6,5,4,3,3,3,3,3,3,2,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,3,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,4,4,4,4,4,3,3,3,3,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,5,5,5,5,5,4,5,5,5,4,5,4,4,4,4,5,5,5,5,5,5,6,5,6,5,5,5,6,6,5,5,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,5,6,7,7,8,9,9,10,11,12,12,15,15,17,18,21,18,17,18,19,18,22,18,21,21,21,24,23,24,23,24,23,24,24,24,25,23,23,24,22,22,24,24,24,24,23,22,23,24,22,21,24,24],[28,28,28,28,27,28,28,27,28,26,25,27,25,26,25,26,24,25,26,25,25,26,25,25,26,26,25,26,26,24,25,26,26,27,25,26,25,26,26,26,26,26,24,25,25,25,24,22,22,22,22,21,22,19,19,18,18,18,16,16,13,11,10,8,7,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,3,2,2,2,2,2,1,2,2,1,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,4,4,3,4,4,4,4,4,5,5,6,6,8,9,10,10,12,14,14,12,14,16,14,14,16,16,18,18,17,19,21,20,21,23,23,23,24,22,22,23,23,22,23,23,24,24,23,23,25,25,26,24,25,26,26,26,26,26,26,26,26,27,26,26,26,27,27,26,27,27,26,26,26,24,26,26,25,26,26,25,26,23,24,23,23,22,21,19,17,17,16,15,14,12,11,10,8,7,6,6,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,8,8,8,9,10,9,9,9,9,8,8,7,7,7,7,8,8,9,9,8,9,8,8,8,7,7,7,7,6,6,6,5,5,5,5,5,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,5,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,4,5,5,5,5,4,5,5,4,4,5,5,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,5,6,7,7,8,9,10,9,10,11,12,15,16,17,18,21,18,18,18,18,18,21,20,20,21,20,23,23,24,23,24,23,24,24,23,25,23,23,25,24,24,24,23,24,23,24,22,23,23,21,21,23,22],[28,28,28,28,28,28,27,28,28,27,27,26,27,26,26,26,25,26,25,26,26,26,26,26,26,26,26,26,26,25,25,26,26,27,26,27,26,26,27,26,27,26,26,26,25,25,24,22,24,23,22,22,22,20,18,20,18,18,18,17,14,12,10,8,7,6,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,4,4,4,5,5,4,4,4,4,5,4,4,5,5,5,6,6,7,9,10,11,12,14,15,13,15,16,15,16,17,17,18,19,19,21,22,22,23,24,25,25,25,23,23,24,23,23,23,25,25,24,24,24,25,26,27,25,26,27,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,25,27,27,26,27,27,26,26,24,25,25,24,23,22,20,19,19,17,15,15,13,12,10,9,8,7,6,6,5,5,5,5,5,5,6,6,6,6,7,7,7,8,7,7,8,9,8,9,10,10,9,10,9,9,8,8,8,7,8,9,9,9,10,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,5,5,4,4,3,3,3,3,3,3,3,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,5,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,4,5,5,4,4,5,4,4,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,3,4,4,4,3,4,5,5,7,7,9,10,10,10,11,12,14,16,17,17,19,21,18,18,19,20,19,22,20,21,22,21,25,24,24,24,25,24,25,25,24,25,24,24,24,23,25,26,25,24,25,25,23,24,25,22,21,24,24],[28,29,28,29,28,29,28,28,28,28,27,27,27,26,27,27,26,27,26,27,26,26,27,26,26,27,27,27,27,25,26,27,27,28,27,27,27,28,27,27,27,27,26,27,26,26,24,23,24,24,23,22,23,22,21,22,21,19,19,19,16,14,12,9,8,7,6,5,5,4,4,4,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,2,2,1,2,2,2,2,2,2,2,3,3,3,2,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,4,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,3,2,2,2,2,2,2,3,2,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,5,5,5,6,6,7,7,8,10,11,11,13,14,15,15,15,18,17,17,18,19,20,21,21,23,24,24,25,25,26,24,26,24,24,26,23,23,24,25,25,24,25,25,26,26,27,26,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,26,28,27,27,28,27,27,27,24,25,25,24,24,22,21,20,19,19,17,16,15,13,12,10,9,8,7,7,7,7,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,8,9,9,10,10,10,10,9,9,9,9,9,9,9,9,9,10,10,9,9,9,9,8,8,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,7,7,7,7,6,6,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,5,5,5,6,6,7,6,5,4,4,3,4,3,3,3,3,4,4,4,4,4,4,4,5,4,4,4,4,3,4,4,4,3,3,4,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,4,5,4,4,4,5,4,4,5,4,4,4,5,5,5,5,4,5,5,4,5,5,5,4,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,3,2,2,2,3,3,3,4,4,4,4,5,5,4,4,5,5,5,5,5,4,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,6,6,6,6,5,6,5,5,6,6,6,6,6,6,6,6,5,6,6,5,6,5,5,5,5,5,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,6,7,6,6,6,6,6,6,7,7,7,6,7,7,7,7,7,7,7,7,8,7,7,6,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,4,6,6,8,8,9,10,10,11,11,13,13,17,16,18,19,20,19,17,19,20,19,22,19,21,22,20,25,23,25,23,25,23,26,25,24,25,24,25,24,22,23,25,25,23,25,24,22,24,25,22,22,23,24],[28,28,27,28,27,27,28,27,27,26,25,25,26,25,25,26,26,26,26,26,25,26,26,25,26,26,25,26,26,25,25,26,26,26,26,26,24,26,26,26,26,25,24,25,25,25,24,22,23,23,21,21,21,20,20,20,19,18,17,17,14,13,11,9,8,7,6,5,5,4,4,4,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,6,6,7,7,8,10,11,11,12,14,15,13,14,16,15,16,18,18,18,18,18,20,21,21,23,23,23,23,24,23,22,23,22,21,22,23,23,22,22,22,25,25,25,23,24,25,26,25,25,25,25,25,25,25,26,26,26,26,26,25,26,26,25,26,25,25,26,25,25,26,25,24,26,24,25,24,23,22,21,20,18,18,16,15,15,13,12,11,9,8,7,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,9,9,9,10,11,11,10,10,9,9,8,8,8,8,9,9,9,10,11,10,10,10,9,9,8,8,7,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,7,7,7,7,7,7,6,5,5,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,5,5,6,6,7,7,6,5,4,4,4,4,4,3,3,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,4,4,5,5,4,4,5,4,4,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,5,5,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,5,5,6,5,6,6,6,5,6,6,6,6,6,6,6,5,5,6,6,5,5,5,5,5,5,5,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,8,8,8,7,7,7,7,7,6,6,7,6,6,6,7,6,5,6,6,6,6,6,7,7,7,7,7,7,7,7,7,8,8,7,7,7,8,7,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,6,7,8,8,10,11,10,10,11,13,13,15,16,16,19,18,18,17,18,18,18,20,18,20,20,21,23,22,24,22,25,23,24,25,24,26,23,24,25,23,22,24,24,23,24,23,22,23,24,22,21,23,24],[28,27,27,27,27,27,27,27,27,25,25,25,25,24,24,25,25,25,25,25,25,25,25,25,25,25,24,25,25,24,24,26,25,26,25,25,24,25,25,25,25,24,24,24,24,24,24,22,22,21,21,20,21,19,19,19,18,18,17,17,14,13,11,9,9,7,6,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,4,3,3,3,3,3,2,3,2,2,3,3,3,3,3,3,3,3,4,4,3,3,2,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,2,1,1,1,2,2,2,2,2,2,2,3,3,3,3,4,4,5,4,5,5,5,5,6,6,6,6,5,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,4,3,3,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,7,7,8,8,10,12,12,12,14,15,15,14,15,16,15,16,17,18,18,18,18,20,20,21,22,22,24,23,24,22,22,23,22,21,22,22,23,22,23,23,24,24,25,23,24,25,25,26,25,25,26,26,26,26,25,26,26,26,26,25,26,26,26,26,26,24,26,25,25,25,25,25,25,23,24,24,23,22,21,20,19,18,16,15,14,13,12,11,10,9,8,7,7,7,7,7,7,7,7,7,7,8,8,8,8,9,10,9,9,11,10,11,11,12,12,11,12,10,10,9,9,9,9,9,10,10,11,12,12,11,10,10,10,9,9,9,9,8,8,8,7,7,7,6,7,6,6,7,7,6,6,7,6,6,6,7,6,6,7,6,6,7,7,8,8,7,7,7,6,6,5,5,4,4,3,4,4,4,3,4,4,4,4,5,5,4,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,5,6,6,6,7,7,7,6,6,5,5,4,4,5,4,4,4,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,6,5,5,5,6,5,6,5,6,5,6,6,6,6,6,5,6,5,6,6,6,6,6,5,5,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,4,3,3,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,5,5,5,5,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,5,5,5,6,6,6,6,6,6,7,6,6,7,7,7,7,7,8,8,8,9,8,8,8,8,8,8,7,7,8,7,7,7,7,7,6,7,6,7,7,7,7,7,7,8,8,8,8,8,8,9,8,8,8,8,8,8,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,7,7,8,8,9,10,11,10,12,12,13,15,15,16,18,18,17,17,19,18,19,20,19,20,20,20,23,21,24,23,24,22,24,25,23,25,23,24,23,23,23,24,23,22,23,23,23,24,23,22,21,23,23],[28,27,27,27,27,27,28,27,26,26,26,25,26,25,25,26,26,26,25,26,26,25,26,25,25,25,26,26,26,24,25,26,26,27,26,27,26,26,26,26,26,25,24,25,25,25,24,22,23,22,22,22,22,21,20,20,19,18,18,17,15,14,12,10,9,8,7,6,6,6,5,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,6,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,4,4,4,3,3,3,2,2,3,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,4,4,3,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,6,6,6,5,6,6,6,6,6,5,6,6,6,6,6,7,7,7,8,9,11,11,12,14,14,15,14,15,17,16,16,17,18,20,20,19,21,22,22,23,23,24,24,24,24,22,24,24,22,23,23,23,24,23,24,25,25,26,25,25,26,26,27,27,26,27,26,26,27,27,27,27,27,27,26,27,27,26,26,27,26,27,26,26,26,26,26,26,24,25,24,24,23,22,21,20,19,18,16,16,13,12,12,10,9,8,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,11,11,10,11,10,10,9,9,9,9,9,9,10,11,11,11,10,10,9,10,9,9,9,8,8,8,8,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,7,6,6,7,7,7,7,7,8,7,7,7,6,5,5,4,4,4,3,4,4,3,3,4,4,4,3,4,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,5,5,5,6,6,7,7,6,5,4,4,4,4,4,3,4,4,4,4,4,5,5,6,5,6,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,4,5,5,4,4,5,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,3,3,3,4,3,4,4,4,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,4,4,4,5,4,4,4,5,4,4,5,4,5,5,5,5,5,5,5,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,8,8,7,7,8,8,7,7,7,7,8,7,6,7,7,7,6,6,7,7,8,7,7,7,7,7,7,8,7,8,8,8,8,7,7,7,8,7,7,7,7,6,6,6,6,6,6,6,6,5,5,5,6,5,5,5,5,4,5,6,6,8,8,10,11,10,11,11,13,13,15,16,16,18,17,17,17,18,20,17,20,19,19,21,21,23,22,24,22,24,23,24,24,23,24,23,23,22,22,22,24,24,22,23,22,22,21,22,22,21,22,22],[28,28,28,29,28,28,28,27,28,27,27,26,26,26,25,27,25,26,26,26,26,26,26,26,26,26,26,26,26,25,25,26,26,27,26,27,26,26,27,27,27,26,26,26,26,26,24,23,24,23,21,21,22,21,19,21,20,19,17,18,15,13,11,9,8,7,6,5,5,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,2,2,2,2,2,3,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,3,4,4,4,5,4,3,3,3,3,3,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,6,5,5,5,4,5,5,5,5,6,6,7,7,7,8,10,10,11,13,13,14,14,15,17,16,16,17,18,19,19,19,22,22,22,22,24,24,25,25,25,22,24,23,23,24,23,24,23,24,24,25,26,27,26,26,27,26,26,26,27,26,26,26,27,26,26,27,26,27,26,28,27,27,27,27,27,27,27,27,27,27,27,28,25,26,26,25,24,23,22,20,19,18,16,16,15,12,11,10,9,8,6,7,6,6,6,6,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,10,11,10,10,10,9,9,9,8,8,8,8,9,10,10,11,10,10,10,9,9,8,8,8,8,8,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,7,7,7,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,6,6,6,5,4,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,5,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,4,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,7,7,7,6,7,6,7,7,6,6,6,7,6,5,6,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,5,6,7,7,9,10,10,10,11,13,14,16,16,16,19,19,18,17,18,19,19,22,20,22,22,21,23,23,24,24,24,22,24,25,24,25,24,25,25,23,23,25,24,24,24,24,22,24,24,23,21,24,24],[28,28,28,29,28,28,28,27,28,27,27,27,27,26,26,26,26,26,26,26,25,26,26,25,25,26,25,26,26,25,26,26,26,27,26,26,25,26,26,26,26,25,25,25,25,25,23,22,23,22,21,21,22,21,18,21,19,18,17,17,15,14,11,9,8,6,6,5,5,4,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,2,3,3,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,4,5,5,5,4,5,4,5,5,5,5,5,5,6,7,7,8,10,11,11,12,13,14,12,14,16,15,15,17,18,19,19,20,22,22,21,23,23,24,24,24,22,23,24,22,22,22,23,23,23,23,23,25,25,26,24,25,25,25,26,25,26,26,26,26,26,26,26,26,27,27,26,27,27,27,26,26,26,26,26,26,26,26,25,27,24,24,25,24,23,22,20,21,20,19,17,16,15,13,11,10,8,7,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,8,7,8,8,8,9,9,10,9,9,9,8,9,8,8,8,8,8,9,8,9,9,8,9,9,8,8,8,7,7,7,7,7,6,6,6,6,5,5,5,4,4,4,5,4,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,5,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,4,4,4,5,5,6,6,5,4,3,3,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,4,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,3,4,4,4,5,4,5,5,4,5,5,4,5,5,5,4,4,5,5,5,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,5,6,6,5,6,6,5,5,5,5,6,6,6,6,6,6,7,6,6,6,6,6,6,7,6,6,6,6,6,6,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,5,6,7,7,9,10,11,11,11,14,14,17,17,18,20,22,19,18,20,20,19,23,21,23,24,22,25,25,25,24,25,25,26,26,25,26,25,25,25,23,25,26,25,25,25,25,22,25,24,23,22,24,23],[28,27,27,28,28,28,28,27,27,26,26,25,26,25,25,26,26,27,26,26,26,26,26,26,26,26,25,25,26,25,24,26,25,26,25,25,25,25,25,24,25,25,25,25,23,24,24,22,22,21,21,21,21,20,20,20,19,18,17,16,14,13,11,9,8,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,6,6,7,7,8,10,10,10,12,12,13,12,14,14,16,15,17,17,18,18,19,21,22,20,22,22,24,24,24,22,21,23,21,21,22,22,24,23,23,23,25,25,26,24,25,24,25,26,25,25,25,25,25,25,25,25,25,25,25,25,26,26,25,26,25,25,25,26,26,26,25,25,27,24,25,25,24,23,23,21,19,20,17,16,16,14,12,11,9,8,7,6,6,6,6,6,6,6,6,6,6,7,6,7,7,7,7,7,7,8,9,8,8,10,9,9,9,8,8,7,7,8,7,7,8,8,9,10,9,10,9,8,8,7,7,7,7,7,7,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,7,7,6,6,6,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,5,5,5,6,6,6,5,4,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,6,6,5,5,6,6,5,5,5,5,5,5,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,6,7,7,6,6,6,6,6,6,6,6,6,6,5,5,5,6,6,6,6,6,6,7,6,7,6,6,6,7,7,6,6,6,7,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,5,4,4,4,4,4,4,5,6,7,7,9,10,11,10,10,12,13,15,16,16,18,20,16,17,18,19,18,22,20,21,21,21,24,24,23,23,25,22,23,23,24,23,21,24,24,22,22,23,23,23,23,23,22,21,24,23,22,22,23],[28,27,27,27,27,27,27,27,27,25,25,24,25,24,24,25,24,25,24,25,25,25,24,25,26,24,25,25,25,24,24,25,25,26,24,25,24,25,25,25,25,25,24,25,24,24,23,22,22,22,20,21,21,20,18,19,19,17,17,16,13,12,10,8,8,7,6,5,5,4,4,4,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,3,3,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,5,5,5,5,6,6,6,7,8,9,11,11,11,12,14,14,12,14,15,15,15,16,17,18,17,18,20,20,20,22,22,24,22,23,23,21,23,22,21,22,22,22,23,22,22,24,24,25,24,25,25,25,26,25,25,25,25,25,26,25,26,26,26,26,25,26,26,26,25,26,24,25,25,25,26,25,25,26,24,25,24,23,23,21,20,19,19,17,16,15,13,12,11,9,8,7,7,6,6,6,6,6,6,6,6,6,6,6,6,7,7,8,7,8,8,9,9,9,10,9,9,9,9,8,7,7,7,7,7,8,9,9,10,9,10,9,9,9,8,8,7,7,7,7,6,6,6,6,5,6,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,4,4,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,3,4,4,3,4,4,3,3,4,4,3,4,4,4,4,3,4,4,4,4,4,5,4,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,6,7,6,6,6,6,6,6,6,6,5,5,5,6,6,6,6,6,6,6,6,7,6,6,6,7,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,3,4,5,6,7,7,9,10,10,9,11,11,12,15,14,15,17,17,17,16,18,18,18,21,18,20,20,20,23,21,22,23,23,20,23,23,23,23,22,23,23,22,22,23,23,22,23,22,22,23,23,22,20,22,22],[29,28,29,29,28,29,28,28,28,28,27,27,27,26,26,27,26,27,26,26,26,26,26,26,26,26,26,26,27,25,25,26,26,26,26,26,26,26,26,26,26,25,25,25,25,25,23,23,23,23,21,21,23,20,19,21,19,18,18,18,15,13,11,9,7,6,5,5,5,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,4,4,4,5,5,4,5,5,5,6,7,7,8,10,10,11,12,13,14,13,15,16,15,15,17,17,18,19,19,21,22,22,23,24,24,24,25,24,23,25,23,23,24,24,24,24,24,24,25,25,27,25,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,26,28,27,27,27,27,26,27,27,26,27,27,26,27,24,25,25,25,24,23,21,20,19,18,17,16,15,13,11,10,8,7,6,6,6,6,6,5,6,5,6,6,6,6,7,7,7,8,7,8,8,8,9,9,9,9,9,9,8,8,8,7,8,7,8,8,9,9,9,9,9,8,9,8,8,7,7,7,7,6,6,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,5,4,4,3,3,2,3,3,2,3,3,3,3,3,3,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,4,5,5,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,6,5,5,6,5,5,5,5,5,6,6,6,5,6,6,6,6,6,6,6,6,6,5,6,5,6,6,5,5,5,5,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,5,5,6,6,9,11,11,10,12,15,15,18,18,18,20,21,20,19,20,20,20,23,21,23,24,22,25,25,25,25,25,23,25,25,25,25,25,24,25,23,25,25,25,24,25,25,24,25,26,24,23,26,25],[28,28,28,28,28,28,28,27,28,27,26,26,26,25,25,25,25,26,25,26,25,25,26,26,25,26,25,26,26,25,25,26,26,27,25,26,25,26,26,26,26,25,25,25,25,25,23,22,23,22,21,21,21,20,19,19,19,18,17,16,14,13,11,8,7,6,5,5,4,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,3,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,4,4,5,5,4,4,4,5,5,5,4,5,5,6,6,7,8,10,10,10,12,13,14,12,14,16,15,15,17,18,18,17,19,21,21,21,22,23,24,24,24,22,22,24,22,22,22,23,23,23,23,23,24,24,26,24,24,25,25,26,25,25,25,25,25,25,25,26,26,26,26,26,27,26,26,26,26,25,26,26,25,25,26,25,26,23,25,25,24,23,22,21,20,19,18,17,15,15,12,11,9,8,7,6,6,6,6,6,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,8,8,8,7,7,7,7,8,8,8,9,8,9,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,6,6,6,5,5,4,4,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,4,4,5,5,5,5,4,4,3,3,2,3,2,2,2,3,3,3,3,3,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,3,3,2,3,3,3,3,4,4,4,4,5,5,4,4,5,5,5,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,5,6,6,5,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,5,6,6,8,9,10,10,10,12,13,16,15,17,19,20,18,18,19,21,17,22,19,22,21,21,24,23,23,23,24,22,25,24,23,23,23,23,23,20,23,23,23,22,23,23,22,22,24,21,22,23,23],[27,27,27,27,27,27,27,27,27,25,25,24,25,24,24,25,25,26,25,26,26,26,26,26,26,25,25,25,25,25,25,26,25,26,26,26,25,25,26,25,25,25,24,24,24,24,24,22,22,22,20,20,21,19,18,19,18,17,17,16,14,13,11,9,8,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,4,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,4,5,5,6,5,6,6,7,7,8,9,11,11,12,13,13,15,12,14,16,15,15,17,18,18,18,18,20,21,20,23,22,24,22,24,22,22,22,22,21,21,23,23,22,22,22,24,24,25,24,25,24,25,26,25,25,25,25,25,25,25,26,26,25,26,26,25,25,26,25,25,25,25,25,24,26,25,26,26,24,25,25,24,23,21,21,20,19,19,15,16,13,12,11,10,9,8,7,6,6,6,6,6,6,6,6,6,6,7,7,7,7,8,7,8,9,9,9,9,10,10,10,9,9,8,8,7,7,7,8,8,9,9,10,10,10,9,9,9,8,8,8,7,7,7,7,6,6,6,6,6,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,6,6,6,5,4,3,3,3,3,3,3,3,3,4,3,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,3,4,4,4,4,5,5,5,5,6,6,5,5,6,6,5,5,5,5,5,5,4,4,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,6,7,6,6,6,7,6,6,7,6,5,6,5,6,6,6,6,6,6,7,6,7,6,7,6,7,7,6,6,6,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,4,5,6,7,7,9,10,10,10,10,13,13,16,16,17,19,19,18,17,19,19,19,21,20,22,21,21,23,22,23,23,24,22,23,24,24,25,23,24,24,23,22,23,24,24,24,23,22,22,23,22,20,22,23],[28,28,28,28,28,28,28,27,27,26,26,25,26,25,25,25,25,26,25,26,26,25,26,26,26,26,26,26,26,25,25,26,26,27,26,27,26,26,27,26,27,26,25,26,26,25,25,23,24,23,21,21,22,19,19,20,19,17,17,17,14,13,10,9,7,7,6,5,5,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,6,6,6,7,7,9,10,10,11,12,12,14,13,14,16,16,16,17,19,19,19,20,22,22,22,23,24,25,24,25,24,22,25,23,22,23,23,24,24,24,24,26,25,27,26,26,27,27,27,27,26,27,27,27,27,27,27,27,27,27,27,28,27,27,27,27,26,27,27,27,27,27,27,27,25,26,26,24,24,23,21,20,20,18,17,17,14,13,11,10,9,7,7,6,6,6,6,6,6,6,6,6,6,7,6,7,8,8,7,8,9,9,9,10,10,10,9,10,9,9,8,8,8,8,8,9,10,10,10,10,10,9,9,9,8,8,8,8,8,7,7,7,7,6,6,6,5,5,4,4,5,5,4,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,5,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,4,3,3,3,2,3,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,4,4,3,3,3,3,3,4,3,3,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,4,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,4,5,5,4,5,5,5,4,5,5,5,5,4,4,5,5,4,5,5,4,5,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,5,6,6,7,7,6,6,7,7,6,6,6,5,6,6,6,6,6,6,5,5,5,5,6,6,6,6,6,6,6,7,6,6,6,7,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,5,6,7,7,9,11,10,9,11,12,13,17,16,17,20,19,18,18,18,20,19,22,21,21,22,21,24,24,25,24,25,23,25,26,25,25,24,25,25,23,24,25,25,25,25,23,24,23,25,24,22,24,25],[29,28,29,29,28,29,28,28,28,27,27,27,27,26,26,26,26,27,25,27,26,25,26,26,25,26,26,26,27,25,25,26,26,27,26,27,26,26,26,26,26,26,25,25,25,25,23,22,23,22,21,21,21,19,18,20,19,18,17,17,15,13,11,9,8,6,6,5,5,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,4,3,3,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,1,2,2,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,4,5,4,5,5,5,5,5,6,6,7,7,8,10,10,11,12,13,14,13,14,16,15,15,17,18,18,18,20,21,22,22,23,23,25,23,25,23,22,24,22,21,23,24,23,23,23,24,25,24,26,25,26,25,26,26,26,25,26,26,26,26,26,26,26,26,27,26,27,26,27,26,27,25,26,27,26,27,26,25,27,24,24,25,24,23,23,21,20,20,19,17,17,15,14,12,10,9,7,6,6,6,6,6,5,6,6,6,6,6,6,7,7,7,8,7,8,8,8,8,9,9,9,9,9,9,8,8,8,8,7,8,8,8,9,9,9,9,8,9,8,8,7,7,7,7,7,6,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,6,6,6,6,6,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,4,4,5,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,6,6,6,5,5,5,5,5,6,5,5,6,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,5,6,6,7,9,11,11,11,11,14,15,18,18,18,21,23,20,19,20,22,20,24,22,22,22,22,25,24,25,24,26,24,26,26,25,25,25,25,26,23,24,26,25,24,25,25,23,25,26,23,23,25,24],[29,28,28,28,28,28,28,28,27,27,27,26,27,26,26,26,27,28,26,28,27,26,27,27,26,27,27,27,27,27,26,27,27,27,26,27,27,27,27,27,27,27,26,26,25,26,25,24,24,24,22,22,22,21,20,21,19,18,17,16,15,13,11,9,8,7,6,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,0,1,1,1,1,2,2,2,3,3,3,3,4,3,3,3,4,4,3,3,3,3,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,3,4,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,5,6,6,6,5,5,5,5,6,6,5,6,6,7,7,8,9,11,11,11,12,14,14,13,14,17,15,17,18,19,19,20,20,23,23,23,25,24,25,24,25,24,23,24,22,22,23,24,24,23,23,24,25,25,27,25,26,25,25,26,26,25,25,25,26,26,26,26,26,26,27,26,27,27,26,26,26,26,27,27,27,27,26,26,27,25,26,26,25,24,23,22,21,21,19,17,17,15,13,13,10,9,8,7,6,7,6,6,6,7,6,7,7,7,7,7,7,7,8,8,8,8,9,9,9,10,10,10,10,9,9,9,8,8,8,8,9,9,10,11,10,11,10,10,8,8,8,8,7,8,8,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,7,7,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,4,5,6,6,6,5,4,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,6,6,5,5,6,6,5,5,5,5,5,5,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,7,6,7,6,6,6,7,7,6,6,6,7,6,6,6,6,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,6,7,8,9,10,12,11,10,14,15,17,17,18,19,22,19,18,20,22,18,23,21,21,23,22,25,25,24,24,26,24,25,25,24,25,24,24,26,23,23,24,24,24,24,24,22,24,25,24,23,24,24],[27,27,27,27,27,27,27,26,27,25,25,24,25,24,24,24,24,25,24,25,25,24,25,25,25,25,25,25,25,25,24,25,26,27,24,26,25,25,25,24,26,26,25,24,24,24,23,22,23,20,20,20,20,18,17,19,18,16,17,16,14,13,11,9,9,8,7,7,6,6,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,4,4,4,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,2,3,2,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,5,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,6,6,6,7,7,7,6,6,6,6,6,6,6,6,7,7,8,8,10,12,12,12,13,12,14,12,15,15,15,17,18,18,17,18,19,21,21,21,23,22,24,22,23,22,21,22,22,22,22,22,22,22,22,22,24,24,25,24,25,26,26,26,25,25,25,25,25,25,25,26,26,26,26,26,27,24,26,26,26,25,25,25,25,26,26,26,26,25,25,24,24,24,23,22,20,20,17,17,16,14,13,12,11,10,9,8,8,7,7,7,6,7,7,7,8,7,7,8,8,8,9,8,9,10,10,10,11,12,11,11,11,10,10,8,8,9,9,9,11,11,10,11,11,11,10,10,10,9,9,9,8,8,8,8,7,8,7,6,6,6,6,5,5,6,5,5,6,6,5,6,6,6,6,6,6,7,8,7,7,7,6,6,5,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,5,4,3,3,3,3,3,3,3,3,4,3,4,4,5,5,6,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,4,5,5,4,4,5,4,4,4,4,4,4,5,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,5,5,5,6,5,6,6,6,6,5,6,7,6,6,6,6,5,5,4,4,4,4,5,4,4,5,4,4,4,5,4,4,5,5,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,7,8,8,8,7,8,7,7,7,7,7,7,7,7,6,6,6,7,7,7,7,7,7,8,7,8,7,7,7,8,7,7,7,7,7,7,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,6,7,8,8,10,11,10,9,11,12,13,16,17,17,20,19,18,16,18,18,19,19,19,19,20,21,22,23,23,22,23,22,23,23,23,24,22,23,24,22,21,23,23,23,24,24,22,22,24,23,20,23,23],[29,28,28,28,28,28,28,28,27,27,26,26,27,26,26,26,26,27,25,27,27,26,27,27,26,27,27,27,27,27,25,27,28,28,27,28,27,27,28,27,27,27,26,26,26,26,24,24,24,22,22,22,22,19,19,20,19,18,18,18,15,14,11,9,8,8,6,6,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,3,3,3,2,2,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,6,6,6,6,6,7,7,8,8,10,11,12,12,13,14,15,13,15,18,16,17,20,21,19,20,22,23,23,24,24,25,27,25,26,24,23,25,24,22,24,23,24,24,23,24,26,25,26,25,27,26,27,27,27,27,26,27,27,27,27,27,27,27,28,27,28,27,28,27,27,26,27,27,26,27,27,27,27,26,26,26,26,23,24,22,22,21,19,18,18,15,14,13,11,10,9,7,7,7,7,7,6,7,6,7,7,7,7,8,8,9,9,8,9,10,10,10,11,12,12,11,11,10,10,9,9,9,9,10,10,11,12,12,12,11,10,10,11,10,9,9,9,9,8,8,8,7,7,7,6,6,6,5,5,6,5,5,6,6,5,5,6,6,6,6,6,7,7,8,7,7,7,6,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,6,6,6,5,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,4,3,4,4,4,4,4,4,4,4,4,4,4,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,5,6,5,6,5,6,6,6,6,6,7,8,7,7,7,7,6,7,6,6,7,7,6,6,7,6,6,6,6,6,7,7,7,6,6,7,7,7,7,7,7,7,7,6,6,6,7,6,6,6,6,5,5,5,5,5,5,5,5,4,4,5,4,4,5,5,4,4,5,6,7,8,8,10,12,12,11,12,14,15,18,17,19,21,21,21,19,19,22,21,23,21,22,22,24,25,25,26,25,25,24,26,25,25,27,25,25,26,25,25,26,24,25,26,25,24,24,25,25,22,24,26],[29,29,28,28,28,28,28,28,27,27,27,26,27,26,27,26,26,27,25,27,26,25,26,26,26,26,27,26,27,26,25,26,27,27,26,27,27,26,27,27,27,26,26,26,26,26,24,23,24,23,22,21,22,21,20,20,19,18,18,18,16,14,12,10,9,8,7,6,6,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,2,3,3,3,2,3,3,3,3,3,4,3,3,3,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,5,4,4,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,6,6,6,6,7,7,6,7,7,7,8,8,9,11,12,11,13,14,15,14,15,18,17,17,19,20,19,20,21,23,22,23,24,24,25,25,25,24,22,24,22,22,23,23,24,24,24,24,25,25,27,25,26,25,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,27,27,27,27,27,27,26,26,26,25,24,24,23,23,22,19,19,18,16,14,13,12,10,8,7,8,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,10,10,10,10,11,11,10,11,10,10,10,10,9,9,9,10,10,11,11,10,11,10,10,10,9,9,9,9,8,8,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,8,8,7,7,7,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,7,5,4,3,3,2,3,3,3,3,3,4,3,4,4,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,6,5,6,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,6,7,6,6,7,8,8,7,7,7,7,6,7,7,6,7,7,6,7,7,6,6,6,6,6,7,7,7,7,7,7,7,8,7,7,7,7,8,7,7,7,7,7,7,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,6,7,8,8,9,11,11,11,11,15,16,18,16,18,21,22,20,20,21,22,20,24,21,22,24,22,24,25,25,25,26,24,26,26,25,26,26,26,26,24,25,26,25,25,25,25,23,26,26,24,24,26,24],[27,28,27,27,28,27,28,28,26,26,26,24,27,25,25,26,27,27,25,27,27,25,26,27,26,26,27,27,27,27,26,27,27,28,26,27,26,27,28,27,27,26,26,26,26,26,24,24,24,23,20,21,22,20,19,21,20,18,18,18,17,15,13,12,10,9,9,9,8,7,7,7,6,5,5,5,5,5,5,5,5,4,5,4,4,4,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,7,7,6,6,6,6,7,6,6,6,6,6,6,5,5,5,4,4,5,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,3,2,3,2,2,1,1,1,1,0,1,2,2,4,4,4,4,5,4,5,5,6,5,5,4,4,4,4,3,3,3,2,3,3,3,3,4,3,3,3,4,4,4,4,4,5,4,5,5,6,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,3,3,3,3,2,3,3,2,2,3,3,3,3,4,4,4,3,4,3,3,2,3,3,4,3,4,4,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,7,7,6,7,7,7,8,7,8,8,9,8,8,8,8,8,8,7,8,9,8,8,8,9,9,10,10,11,12,13,13,14,15,16,15,16,18,17,17,19,20,19,21,22,23,23,22,24,24,25,24,25,24,23,24,23,22,23,24,24,24,25,24,26,25,27,26,26,26,26,26,27,27,26,27,26,26,26,26,27,27,27,27,27,27,27,26,27,26,26,26,27,27,26,26,28,26,26,26,25,24,23,24,22,21,20,19,19,17,15,15,13,12,10,9,9,9,9,9,9,9,9,9,10,9,10,10,10,10,11,11,11,12,13,12,12,13,13,13,12,11,11,11,11,10,10,11,11,12,14,14,13,14,13,13,13,12,11,11,11,11,11,10,10,9,10,9,9,9,8,7,7,8,8,7,8,8,8,8,9,8,8,9,10,9,9,10,9,9,8,9,7,7,6,6,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,5,4,4,4,5,5,4,5,5,5,5,5,6,5,5,6,6,6,7,8,8,8,7,6,5,5,4,5,5,4,5,6,5,5,6,6,7,7,7,7,7,6,7,7,6,6,6,6,6,5,5,6,5,5,5,4,5,5,5,4,4,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,7,7,6,6,6,5,5,6,6,5,5,6,5,5,6,6,6,6,5,6,6,6,6,6,6,7,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,5,5,5,6,6,6,6,6,7,7,7,8,7,8,9,8,8,8,8,8,8,8,8,7,7,7,6,6,5,6,6,6,5,6,6,5,6,6,6,6,7,6,6,6,7,7,8,7,8,7,7,8,8,7,7,7,8,7,7,7,8,8,7,7,8,8,7,8,8,7,7,7,7,6,7,7,7,6,7,8,7,7,8,8,8,8,8,8,8,8,8,9,10,9,9,10,9,9,9,9,8,9,9,8,9,9,9,8,8,8,8,9,9,9,8,9,10,9,9,8,8,9,10,10,9,9,8,10,9,8,9,8,8,8,7,8,7,7,7,7,7,7,7,7,6,7,7,6,6,6,7,8,9,10,11,13,14,13,14,15,17,18,17,18,21,20,20,20,22,23,19,23,21,21,23,22,25,26,25,24,24,24,25,26,25,26,25,26,26,25,24,25,26,26,26,24,25,26,26,25,23,25,25],[28,28,28,28,28,28,28,27,28,27,26,26,27,26,26,27,27,27,27,27,27,26,26,27,26,26,28,27,27,27,26,26,28,29,27,27,27,28,28,27,28,27,26,26,27,27,25,25,25,24,23,24,23,21,20,22,21,20,19,19,18,15,14,13,12,11,10,10,9,9,8,8,7,7,7,7,7,7,7,7,7,7,7,6,5,5,5,6,5,5,6,6,5,6,6,5,6,6,6,5,7,7,6,6,8,7,6,7,7,8,8,9,8,8,8,8,8,8,8,7,7,7,6,6,6,6,6,5,5,5,5,4,4,4,4,5,4,3,4,4,4,4,4,5,6,4,5,5,5,6,6,5,6,8,6,8,7,7,8,8,9,8,8,8,8,8,8,7,7,7,7,6,6,6,6,5,5,6,5,5,5,6,4,4,5,3,3,3,3,2,2,2,2,1,0,1,2,3,4,3,5,5,4,4,4,5,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,5,5,6,5,6,6,6,6,7,7,7,8,9,7,7,8,7,7,7,7,6,7,6,6,5,6,5,5,4,4,5,5,5,4,5,5,4,4,3,4,3,4,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,4,4,4,4,5,5,4,4,5,5,5,5,5,6,5,5,6,7,6,7,7,7,8,8,8,8,8,8,8,10,9,9,9,9,10,10,9,9,10,11,9,10,9,10,10,10,10,10,10,11,11,12,12,13,13,14,15,15,16,17,17,19,19,19,21,22,22,22,23,24,25,25,26,26,27,25,27,26,24,26,24,24,25,25,25,25,27,26,28,26,28,27,27,27,27,27,27,27,27,28,28,27,27,28,28,28,28,27,28,28,28,28,28,28,27,28,28,28,28,28,28,27,26,26,26,25,26,25,22,23,21,21,21,18,17,17,15,14,12,11,10,11,11,10,10,11,10,11,12,11,11,12,12,13,13,12,13,14,14,14,15,16,16,15,15,13,14,12,12,13,13,14,14,14,16,16,15,16,15,15,15,13,14,14,13,13,13,12,12,12,11,10,11,11,10,9,9,10,9,9,9,10,9,9,10,9,9,9,10,10,10,10,10,10,10,10,8,8,7,6,6,6,5,6,6,5,4,6,5,5,4,5,5,5,5,5,6,4,5,6,6,5,6,6,5,6,7,7,6,6,6,7,7,8,8,8,8,7,6,5,4,5,5,4,4,5,5,5,6,6,7,6,7,8,8,8,7,8,8,7,7,7,7,6,6,7,7,5,6,7,6,5,7,7,5,5,6,6,5,6,6,6,5,6,6,6,6,8,7,7,7,8,7,7,7,7,7,6,7,7,6,6,7,7,6,7,7,7,7,6,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,7,8,8,8,7,8,7,8,7,8,7,8,7,7,8,8,8,8,9,8,9,9,10,9,8,9,10,9,9,9,9,9,8,7,8,7,8,7,8,7,7,7,7,7,7,7,7,8,7,8,8,8,8,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,8,9,9,9,8,9,9,9,9,8,9,8,8,9,8,8,9,9,9,9,9,9,10,9,10,10,10,9,10,10,11,11,10,11,11,10,11,11,10,11,10,10,10,11,10,10,11,10,10,11,11,10,10,10,11,10,11,10,10,10,11,11,10,10,9,10,9,9,9,10,10,9,9,9,8,8,8,8,7,7,8,8,6,8,7,6,6,7,8,9,10,10,12,14,13,13,14,14,16,18,18,19,22,22,20,19,21,21,21,24,21,22,23,22,25,25,26,25,26,24,26,26,25,26,25,25,27,25,25,26,26,26,26,25,25,26,26,26,23,26,26],[29,28,28,28,29,28,28,29,28,27,28,26,28,28,27,27,28,28,26,28,27,26,27,28,26,27,28,27,27,28,26,27,29,29,28,29,28,28,29,28,29,28,28,27,28,28,26,26,27,26,24,26,25,24,22,24,24,22,21,21,19,17,17,16,13,14,13,12,11,13,11,11,10,10,10,10,9,9,9,10,10,9,10,9,8,8,9,9,9,10,9,9,10,9,9,11,10,9,9,10,10,10,8,8,10,9,9,9,10,9,11,11,10,10,11,11,10,11,10,10,9,9,8,9,8,8,7,7,8,7,7,7,5,5,6,7,6,5,6,6,5,6,7,7,7,9,8,9,10,10,9,8,10,9,9,10,10,9,10,10,10,11,10,10,11,10,10,10,10,9,9,10,9,8,8,8,7,7,7,8,8,7,7,6,6,6,3,4,4,3,2,3,3,2,1,0,1,2,3,3,4,6,5,4,5,5,5,6,5,6,4,4,5,5,5,5,7,7,4,7,8,8,9,8,8,9,10,9,9,9,8,10,10,10,10,11,10,10,10,9,10,10,9,9,10,9,8,8,9,8,7,8,8,7,7,7,5,6,7,6,7,7,7,7,6,8,7,6,8,6,6,5,6,5,7,5,5,5,4,4,5,6,7,8,8,6,8,8,8,9,9,9,10,10,9,10,8,10,10,10,11,10,11,11,11,11,12,12,12,11,13,13,12,12,13,13,14,14,13,14,14,13,12,13,12,13,14,14,12,13,14,14,12,13,15,15,16,17,16,17,18,19,20,22,22,21,23,24,25,24,25,27,26,27,28,27,27,27,27,27,26,27,26,25,26,26,27,26,26,27,28,28,29,28,28,28,28,28,28,28,28,28,28,28,27,28,29,29,28,28,29,29,29,28,28,28,28,28,28,29,29,28,28,28,28,27,27,27,26,26,26,24,23,23,22,21,19,20,17,17,15,14,14,14,13,14,15,14,17,14,16,15,14,15,15,15,16,16,16,17,16,18,18,19,18,19,18,17,15,16,17,15,16,17,16,16,18,19,18,19,18,18,17,16,16,17,16,16,15,15,14,15,15,14,15,14,13,14,13,14,13,14,13,13,13,13,13,13,13,13,13,13,14,13,12,12,12,13,11,11,11,9,10,9,9,11,10,8,8,11,8,10,8,9,9,9,10,9,9,8,10,9,7,9,11,8,11,10,9,10,9,9,9,9,8,10,10,9,10,9,8,7,6,7,9,6,7,9,8,8,7,7,8,9,9,10,10,11,10,9,11,11,9,10,10,9,9,9,10,10,9,10,10,12,10,10,11,10,12,11,11,11,11,11,11,11,10,11,10,11,11,11,12,12,11,10,12,10,11,13,11,10,10,11,10,9,10,10,11,10,10,11,12,10,11,12,11,10,12,10,11,11,11,11,11,11,12,10,10,10,11,10,10,11,9,11,10,10,12,11,10,11,11,11,11,11,11,12,11,12,12,11,11,11,11,12,12,12,11,12,12,11,11,11,11,13,11,12,11,11,11,12,11,12,11,11,13,11,11,11,11,12,12,13,12,12,12,12,12,12,12,13,11,12,12,12,12,12,11,12,12,11,11,12,11,12,11,12,12,12,12,13,13,12,12,12,12,12,14,13,12,12,13,12,13,14,13,13,13,13,14,13,14,14,13,14,13,13,13,14,12,14,15,15,12,15,13,14,13,13,14,12,13,13,13,13,14,15,12,14,12,14,13,12,13,13,12,13,12,11,11,12,11,11,12,12,12,12,11,12,11,11,10,9,11,11,12,14,15,16,15,15,17,16,18,19,19,21,22,23,23,21,22,23,23,25,24,23,25,24,26,27,27,27,28,27,27,27,27,27,27,26,28,27,26,25,27,27,27,27,27,27,28,27,26,27,27],[28,27,28,28,28,28,28,27,27,27,26,25,26,26,26,26,26,26,25,27,26,25,26,27,26,27,27,26,27,27,26,27,28,28,27,28,27,27,28,27,28,27,27,26,27,27,25,24,26,25,22,23,24,22,21,23,22,20,21,20,19,17,16,15,12,13,13,11,11,11,10,10,9,9,8,9,8,8,9,8,9,9,8,7,7,7,7,8,7,7,8,7,7,8,7,8,8,8,8,8,9,8,8,8,10,9,8,9,10,11,10,10,10,9,10,11,11,10,10,10,10,10,9,9,9,10,8,7,8,8,7,7,6,5,5,5,6,5,6,6,6,6,7,7,8,8,7,8,7,9,9,9,10,10,9,10,10,10,10,10,10,9,10,10,9,9,9,9,9,9,9,9,8,8,9,8,7,7,7,8,7,7,6,6,5,5,4,4,4,3,3,4,3,2,2,1,0,1,2,1,2,2,3,3,3,4,4,4,4,5,4,3,3,5,5,4,5,6,6,6,7,7,7,7,9,10,9,8,9,9,8,9,9,9,10,11,10,10,10,10,9,9,9,9,10,9,9,7,9,8,7,7,7,7,7,7,5,6,6,6,6,6,7,6,6,6,6,5,5,6,7,5,4,6,6,4,4,3,3,3,4,5,6,7,7,8,7,7,7,8,8,8,8,8,9,9,9,9,8,9,10,10,10,11,10,10,11,11,11,11,13,14,12,11,12,12,13,13,14,13,13,13,12,12,11,11,13,12,11,13,14,14,13,14,15,15,16,17,16,16,17,19,20,20,20,20,21,21,23,23,24,25,26,25,26,26,27,26,26,26,24,25,25,25,25,25,25,26,26,25,28,26,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,29,28,28,28,27,28,27,28,28,28,28,28,28,28,27,27,27,26,24,25,24,23,23,22,22,19,18,19,17,16,15,15,14,14,14,14,13,14,14,14,13,15,15,14,14,16,16,14,14,17,16,16,16,19,18,18,18,16,17,15,15,15,16,16,17,17,18,18,18,19,18,18,17,15,16,16,16,16,16,15,15,15,15,14,15,12,13,12,12,12,12,12,12,12,12,12,12,12,11,11,12,11,11,12,12,12,11,11,10,10,9,9,9,8,8,9,8,7,7,8,8,7,7,8,7,7,8,7,8,7,8,7,8,7,8,8,8,8,7,7,7,8,7,8,7,8,9,8,9,8,6,6,5,5,6,5,5,7,6,6,6,6,7,7,7,8,8,9,7,7,8,8,7,8,8,7,7,8,9,8,7,8,8,7,8,8,8,8,8,8,9,9,9,9,9,10,8,10,11,10,10,11,10,11,10,9,11,9,10,9,10,8,8,9,9,8,7,8,9,10,9,7,10,9,8,8,10,8,8,9,9,10,9,9,9,9,9,8,7,8,8,8,9,8,9,10,9,9,10,9,10,9,10,10,9,10,9,10,9,11,9,8,10,11,10,11,10,10,10,10,10,9,9,8,8,10,8,9,9,9,9,9,9,10,10,10,11,10,10,10,10,11,11,10,11,11,10,10,11,11,10,10,10,11,12,10,10,11,11,10,11,11,10,10,11,11,11,11,11,11,11,12,11,12,11,11,12,12,11,11,12,12,12,11,12,13,13,12,13,13,13,12,14,13,12,13,13,13,13,14,12,13,13,14,13,14,14,13,13,12,13,13,14,13,13,12,13,13,12,11,10,11,11,12,11,11,11,10,9,11,10,9,9,10,10,9,9,10,9,9,9,9,9,9,9,10,11,11,14,13,14,15,15,17,17,18,20,20,23,21,22,21,22,22,21,23,22,22,25,22,25,24,26,25,26,24,26,26,26,27,25,25,27,26,25,26,26,26,26,26,25,26,27,26,24,26,27],[28,28,28,28,28,29,29,27,28,27,27,27,27,26,27,26,27,26,26,27,26,26,27,27,26,27,27,26,28,26,25,27,28,28,27,28,27,27,28,27,28,27,27,27,27,27,25,25,26,25,24,23,24,22,20,22,21,21,20,20,18,17,15,13,11,12,11,10,10,9,9,8,7,7,7,8,7,8,8,7,7,8,7,6,6,6,5,6,6,6,6,6,6,7,6,7,7,7,7,8,8,7,7,7,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,9,7,6,7,6,6,6,6,5,5,6,6,5,5,5,5,5,6,7,8,6,7,7,6,8,8,8,8,9,8,9,9,9,10,9,9,9,10,9,9,8,9,8,8,9,9,8,7,8,8,7,8,7,8,7,6,6,6,7,6,7,4,5,5,4,4,3,3,3,1,1,1,0,1,1,1,2,2,3,3,4,4,4,5,4,4,4,4,5,4,5,5,5,5,6,7,7,9,8,7,7,7,7,8,8,7,8,8,9,9,10,9,9,9,9,8,8,8,8,8,7,7,8,7,7,8,7,7,7,7,7,7,7,6,6,6,6,5,6,5,6,6,5,5,3,4,4,4,5,5,3,4,3,3,3,4,5,4,5,5,6,6,5,6,8,6,6,7,6,6,8,7,7,7,8,7,8,8,8,8,9,8,8,10,10,10,10,11,11,11,11,11,12,11,11,11,11,10,10,9,10,11,10,10,11,11,12,12,12,12,14,14,14,15,16,17,18,19,20,19,19,21,22,23,23,24,25,25,26,27,27,28,26,27,26,25,27,24,25,26,26,25,26,26,27,28,27,28,27,28,29,29,28,28,28,28,29,28,28,28,29,29,29,28,28,29,29,29,29,29,28,28,29,29,29,29,28,29,27,27,28,27,25,26,25,24,23,22,22,21,19,17,17,15,15,13,12,12,11,12,11,11,12,11,12,12,13,13,14,13,14,15,14,15,15,16,16,16,18,17,16,17,14,16,14,13,15,14,15,16,17,17,18,17,17,16,17,16,15,15,15,15,15,14,13,14,13,13,12,12,12,10,10,10,10,10,10,11,11,11,10,11,11,11,11,11,12,11,11,11,11,12,11,10,10,9,8,8,7,8,7,7,7,6,7,7,7,6,7,8,7,6,5,7,6,6,6,8,5,6,6,6,5,5,7,7,5,6,6,6,7,8,8,9,6,5,5,4,4,5,4,4,5,5,6,6,6,6,7,6,7,6,7,7,6,6,7,7,6,6,7,6,5,7,6,5,6,6,5,6,6,7,6,6,7,6,6,6,6,7,6,6,7,8,8,8,8,9,9,8,8,8,7,8,8,7,6,7,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,7,7,7,8,7,7,7,8,7,7,6,7,7,7,7,7,7,9,9,7,8,8,8,8,8,8,8,9,8,9,8,9,9,8,9,9,10,10,9,10,9,8,8,7,7,6,6,7,6,6,7,7,6,6,7,7,7,7,7,7,7,8,8,9,9,9,8,9,9,8,8,9,8,7,8,8,9,8,7,8,9,9,8,8,9,8,9,9,9,8,8,9,8,8,8,9,9,8,9,9,10,9,10,11,10,10,11,11,11,9,11,11,11,10,11,11,10,11,11,11,11,12,11,10,10,11,11,11,11,11,11,11,11,11,12,12,11,11,11,12,10,10,8,11,11,10,9,10,10,8,9,10,9,8,9,9,8,9,9,9,8,9,8,8,8,8,9,10,11,11,14,14,14,15,16,16,17,20,19,20,22,22,22,21,22,22,21,24,22,23,24,23,24,25,26,26,25,24,27,26,26,27,27,27,27,26,27,27,27,27,26,26,26,27,27,26,25,26,26],[29,29,29,28,29,29,29,29,28,28,28,26,28,27,28,27,28,28,27,28,27,26,28,27,26,27,28,27,28,27,25,27,28,29,27,28,27,28,28,28,29,28,28,28,28,28,26,25,27,25,23,23,25,23,22,24,23,21,21,21,20,18,15,15,13,13,12,11,12,10,10,9,10,9,9,10,8,9,9,9,9,9,11,9,8,8,7,8,6,6,8,7,7,8,7,7,8,8,7,8,8,8,8,7,9,8,8,8,9,9,10,10,9,8,10,10,9,10,9,9,9,9,8,8,8,8,8,7,7,7,7,6,6,6,5,6,5,5,5,5,5,6,5,7,7,6,7,8,8,8,8,9,9,8,8,8,8,9,9,10,9,10,10,10,9,9,10,9,9,9,8,9,8,8,8,7,8,8,8,9,7,8,8,6,7,8,6,5,5,4,4,4,5,4,1,2,2,1,0,1,1,2,3,2,3,4,4,4,4,4,4,4,3,4,4,4,5,5,5,6,7,6,9,8,8,9,10,9,9,9,9,9,10,10,11,11,9,9,11,9,8,10,10,9,9,9,8,8,9,8,9,8,9,7,8,7,7,8,7,7,7,7,6,7,6,7,8,5,6,5,6,4,5,6,6,5,5,3,3,2,3,6,6,6,6,7,6,7,8,8,9,8,8,9,9,8,9,9,9,10,9,10,10,10,12,11,10,11,11,11,11,12,12,12,12,12,12,13,13,12,13,12,12,11,11,11,13,12,12,12,13,14,13,13,13,15,16,15,16,17,17,18,19,21,20,21,24,23,23,24,25,26,26,26,27,27,28,27,27,27,26,28,24,23,26,26,26,26,26,27,28,27,28,28,29,28,28,28,28,28,28,28,29,28,28,29,29,29,29,28,29,29,29,29,29,28,29,29,29,28,29,28,29,27,28,28,27,26,26,26,26,24,24,23,22,20,20,19,17,16,16,13,13,14,13,13,12,13,14,13,13,14,13,14,14,14,16,15,15,15,17,15,16,17,17,18,18,16,16,16,15,15,15,15,16,16,18,18,17,18,17,17,16,15,15,15,16,15,15,14,15,14,13,13,13,13,12,12,12,13,12,12,12,12,13,12,12,12,12,12,12,13,12,13,13,13,12,12,11,11,11,10,10,10,9,9,9,8,8,10,9,8,8,8,7,8,7,7,7,6,7,7,8,8,8,6,7,7,7,8,7,8,8,8,7,8,9,9,9,8,6,5,5,5,5,5,5,5,6,6,5,6,7,8,7,8,9,9,8,8,9,8,8,8,8,8,7,7,8,7,7,8,8,7,8,8,8,8,8,9,9,8,8,9,10,9,9,10,9,10,10,10,12,10,10,9,10,10,9,9,9,10,7,8,9,7,9,8,8,9,8,8,10,8,8,8,9,8,9,9,9,10,10,9,9,10,9,8,9,9,9,10,9,9,9,10,9,9,10,9,9,9,8,9,10,9,10,9,11,11,10,10,10,11,10,11,10,10,10,10,10,9,9,8,8,9,8,9,9,9,8,8,9,9,9,9,10,10,9,10,11,11,11,11,9,11,11,10,9,10,10,9,9,10,10,9,9,10,10,10,10,10,10,10,10,10,11,10,9,11,10,10,10,10,10,10,11,11,12,11,11,11,11,11,11,13,12,12,12,12,11,11,12,12,11,12,12,12,11,12,12,11,11,13,11,13,12,13,11,12,13,12,12,12,11,12,12,13,11,12,10,13,11,11,11,11,11,10,10,11,10,9,10,10,11,9,10,11,9,10,10,10,10,8,10,12,12,12,14,15,15,15,16,17,19,21,20,22,24,24,23,22,24,24,22,26,23,24,25,24,26,27,27,26,27,26,26,27,26,27,26,27,27,26,26,28,27,27,27,27,27,27,29,26,26,27,27],[29,29,28,28,29,29,28,28,28,27,28,27,28,27,27,28,28,28,27,28,26,25,27,27,26,27,27,27,27,27,26,27,28,29,27,28,28,28,28,28,28,27,27,27,27,27,25,24,26,24,24,23,24,24,20,23,22,20,20,19,19,16,15,14,12,12,12,12,10,11,9,10,8,8,8,9,8,8,8,9,8,8,10,7,7,8,8,9,8,8,8,8,8,8,8,9,9,9,8,8,9,9,8,8,9,8,9,9,9,9,11,10,9,9,10,10,9,10,10,9,9,9,8,8,7,8,7,7,7,6,7,6,6,6,6,7,6,6,6,6,6,6,7,7,7,8,8,7,10,9,8,7,9,9,8,9,10,8,8,9,9,10,9,9,10,8,8,8,9,8,8,8,8,8,8,7,7,7,7,7,6,6,6,6,6,6,5,5,4,4,3,3,3,3,2,2,2,1,1,0,1,2,2,2,3,3,3,4,4,5,5,4,4,5,5,4,6,7,5,7,7,8,8,7,8,8,8,7,8,8,8,8,9,9,10,10,10,9,10,8,9,10,9,9,9,8,8,7,8,7,6,6,7,7,6,7,7,6,6,6,6,6,6,6,6,6,6,5,5,6,4,4,4,4,5,5,4,3,4,4,4,4,5,7,7,7,8,6,7,7,8,8,7,8,8,8,8,8,8,9,9,9,8,9,10,9,9,11,10,10,11,13,11,11,12,12,13,13,13,13,13,12,12,11,11,12,12,12,11,12,12,13,13,12,14,15,15,15,14,15,16,18,18,19,18,20,19,20,22,23,23,25,25,25,27,26,27,26,27,27,24,26,26,24,25,26,26,25,26,27,27,27,28,27,28,28,28,28,28,28,28,27,27,28,28,28,29,29,28,28,29,28,29,28,28,28,28,28,28,28,28,27,28,28,27,27,27,27,26,26,25,24,24,22,22,20,18,19,17,16,14,13,12,13,12,13,13,13,14,14,14,13,14,14,13,15,16,14,14,15,17,16,17,18,18,18,17,15,16,14,14,14,15,16,17,17,19,19,18,18,17,16,17,17,15,15,16,16,15,15,14,14,14,13,14,13,12,11,11,12,11,11,11,12,12,11,11,11,12,11,12,11,11,12,12,11,12,11,10,10,9,9,9,8,8,9,7,7,7,8,7,7,6,8,8,7,8,8,7,6,8,7,6,7,9,7,7,8,7,7,7,7,8,8,7,8,9,8,9,8,6,6,5,5,7,5,5,7,6,6,6,6,6,8,7,8,8,8,8,7,8,8,8,8,9,8,8,8,9,9,8,8,7,8,8,8,7,7,9,8,7,8,9,8,8,9,8,8,9,9,9,10,10,10,10,9,11,9,9,9,9,8,7,8,8,8,7,8,8,9,8,7,9,9,8,8,9,8,9,8,9,9,9,10,9,9,10,8,9,9,9,9,9,10,9,10,9,8,9,9,8,9,9,10,10,10,9,9,10,10,10,9,10,11,10,10,10,10,10,10,9,9,9,9,9,10,9,10,8,8,9,9,9,10,10,9,10,9,9,10,10,10,10,10,10,11,11,10,10,10,11,10,10,11,10,10,10,11,10,10,11,11,10,11,10,10,10,10,11,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,12,12,12,11,13,12,11,12,12,12,12,13,11,11,12,13,12,14,13,13,12,12,12,12,13,11,11,12,12,13,11,12,11,12,11,11,11,10,10,10,10,10,10,10,10,10,10,10,9,10,9,10,9,8,8,9,11,11,11,13,13,14,14,14,15,15,16,18,19,20,22,23,22,20,22,22,22,25,23,23,25,24,25,26,26,25,27,25,25,27,26,27,25,26,26,26,25,26,27,27,27,26,26,26,27,27,25,27,28],[28,28,28,28,28,28,28,27,28,27,26,26,27,26,27,26,27,26,26,28,26,25,27,27,25,27,27,26,27,26,25,27,28,28,26,27,27,27,28,27,28,26,26,26,27,26,25,24,25,23,23,23,23,22,20,22,21,20,20,20,18,17,15,14,12,12,12,10,10,10,9,9,9,9,8,9,8,8,8,8,9,9,9,7,7,7,7,6,7,7,7,7,8,7,7,8,8,8,8,8,9,9,8,8,10,10,10,10,10,11,10,10,10,10,10,11,11,10,10,10,10,10,9,9,9,9,8,8,7,8,8,7,6,6,6,7,6,6,6,7,6,8,8,7,7,9,7,7,8,7,9,8,8,10,9,10,10,10,10,11,9,9,10,10,9,9,9,10,9,9,9,9,9,9,9,8,8,8,8,8,7,7,7,7,6,6,6,6,6,5,5,3,4,3,3,3,2,2,1,1,0,1,1,2,2,3,4,4,4,5,5,4,5,6,5,6,6,6,7,7,8,7,7,7,8,9,9,9,9,9,8,9,9,9,10,11,10,10,10,10,9,9,9,10,11,9,9,9,9,8,8,7,8,7,8,8,7,7,7,7,6,6,6,6,7,5,7,6,7,6,7,5,4,5,5,5,4,3,4,3,5,6,6,7,6,8,6,6,7,8,8,8,8,8,8,8,9,9,8,8,9,10,9,10,10,10,11,11,11,10,12,14,12,11,12,12,13,14,13,13,14,13,12,12,11,12,12,12,12,12,13,13,12,13,14,14,14,15,15,14,16,17,18,19,19,20,20,21,22,22,23,24,25,25,26,26,27,25,26,26,25,26,25,24,26,26,26,25,26,26,28,27,28,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,28,28,29,28,29,28,28,28,27,28,28,28,28,28,28,27,27,26,27,26,25,25,23,23,23,22,22,19,18,18,16,16,15,14,13,13,13,14,13,14,15,15,14,13,15,15,14,16,16,15,15,16,17,16,17,18,17,17,17,16,17,15,15,15,16,17,17,18,19,19,18,19,17,17,18,17,16,16,16,17,16,15,16,15,14,14,14,13,13,12,12,13,13,13,12,12,13,13,13,13,12,11,13,12,12,12,13,12,12,12,11,10,10,10,10,9,8,8,8,8,7,8,8,7,7,7,7,7,7,7,8,6,8,7,7,6,8,8,8,7,7,7,6,7,7,7,7,8,7,8,10,7,6,5,5,4,5,4,5,5,5,6,5,5,6,6,7,7,7,8,7,7,7,7,7,7,8,6,7,7,7,7,6,7,6,8,8,8,7,7,8,8,7,8,9,8,9,9,8,9,10,10,9,10,10,10,10,9,11,9,9,9,9,8,8,7,8,8,8,8,7,9,8,7,8,8,7,8,9,8,8,8,8,9,8,8,8,8,8,8,7,8,8,8,8,8,9,9,9,8,8,8,9,9,9,9,9,10,9,9,9,10,10,8,9,11,10,11,10,10,10,9,8,8,9,8,8,10,8,9,8,8,9,9,9,9,10,9,10,9,10,10,10,11,10,10,10,11,10,10,11,10,10,9,10,10,11,10,8,10,10,10,9,10,10,9,10,9,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,11,11,10,11,13,12,10,12,13,11,10,13,12,11,13,13,12,12,13,12,11,12,13,12,14,13,13,13,12,12,12,13,12,12,12,12,13,11,11,10,11,11,12,10,11,11,10,10,10,11,10,10,10,10,10,9,11,9,9,9,9,9,9,11,11,11,12,14,14,14,16,16,16,17,18,20,20,23,23,22,20,22,23,21,25,22,23,26,22,25,25,26,26,26,25,27,27,26,27,26,26,27,26,26,27,27,27,27,26,26,27,27,27,25,26,27],[29,29,28,29,29,29,29,28,28,28,28,27,28,27,27,27,27,27,26,28,26,26,27,27,26,27,27,27,27,27,26,27,28,29,27,28,28,28,28,28,29,28,27,28,28,27,26,25,26,25,24,24,25,23,21,23,22,21,20,21,19,17,15,14,12,12,11,12,11,12,10,9,9,9,8,10,9,9,9,9,8,9,8,7,6,7,7,7,7,7,6,7,8,7,7,7,8,8,7,7,9,8,8,8,10,8,8,8,9,9,10,10,10,10,10,10,10,10,11,10,9,10,9,9,9,10,8,7,8,8,7,6,6,6,6,6,5,5,5,5,6,6,6,7,9,7,7,8,8,8,9,10,9,10,8,10,9,9,11,9,11,10,11,10,10,10,11,9,10,10,10,9,10,10,9,8,10,9,8,8,8,8,7,7,9,6,6,6,6,6,5,3,4,3,2,3,2,2,1,1,1,0,1,1,2,2,4,3,6,5,5,4,6,5,4,5,5,7,8,8,9,8,11,9,8,10,9,9,10,10,9,10,10,11,11,12,10,10,11,10,10,11,10,10,10,10,9,10,10,9,8,9,8,8,9,9,8,8,7,7,7,8,6,6,9,8,10,7,7,5,6,5,5,5,5,4,5,3,2,2,4,6,6,7,7,8,9,8,9,10,7,8,8,8,8,9,8,8,9,9,9,10,10,9,10,11,10,10,11,11,11,11,12,12,11,12,13,12,12,12,12,12,12,11,11,12,12,12,12,12,12,13,13,12,13,14,15,14,16,16,17,18,18,19,20,20,20,21,22,23,23,25,26,26,26,26,28,25,28,26,24,27,25,25,27,26,26,26,26,27,28,27,28,27,28,29,28,28,28,29,29,29,29,29,28,29,29,29,29,28,30,29,29,29,29,28,29,29,29,29,29,28,29,27,27,28,27,25,26,25,23,23,22,22,21,19,17,18,16,15,14,12,13,12,13,12,11,13,13,13,13,14,13,15,14,15,16,15,15,15,18,15,16,18,17,17,17,15,16,14,14,16,15,16,17,17,18,19,18,18,17,17,17,16,15,15,15,16,14,14,14,14,13,13,13,12,11,11,11,11,12,11,11,12,12,11,12,12,12,11,12,12,12,13,12,13,13,12,12,11,10,10,10,9,10,8,8,9,8,8,8,8,7,7,8,8,7,5,8,7,6,6,9,6,5,7,7,5,5,7,7,6,6,6,6,7,9,8,8,7,6,5,5,5,6,5,5,6,6,6,5,6,6,6,7,7,7,7,7,6,7,7,6,6,6,7,6,6,6,8,6,6,7,8,6,7,7,6,7,8,7,6,7,8,8,7,8,9,10,9,9,9,10,9,9,9,9,8,9,9,7,7,7,6,6,6,8,6,7,7,6,7,7,7,6,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,10,9,9,9,8,9,9,9,9,9,9,10,9,9,9,9,9,9,10,11,11,10,11,9,9,9,8,8,7,8,9,7,8,8,8,7,7,8,8,7,8,8,8,8,9,9,9,10,9,8,9,10,8,8,9,9,8,8,9,10,9,8,8,9,9,9,9,10,10,10,10,10,9,9,9,9,9,10,9,9,9,10,10,10,9,11,11,10,10,11,11,11,10,11,11,11,11,11,11,11,13,11,11,11,12,11,11,11,12,11,12,12,12,12,12,12,12,12,12,11,12,12,12,11,11,9,11,11,10,9,11,11,9,9,11,9,9,9,10,9,10,10,10,10,10,10,9,10,10,10,11,12,12,14,15,15,15,16,17,18,21,21,21,24,23,23,22,24,23,22,26,23,25,26,24,25,26,27,27,27,25,27,27,27,28,27,27,27,26,27,28,28,27,28,28,27,28,28,26,26,28,27],[29,29,29,28,29,29,29,28,28,27,28,26,28,26,27,27,27,28,25,28,27,25,27,27,25,26,28,26,26,28,25,27,28,28,27,28,27,27,28,27,28,27,27,27,27,26,26,24,25,24,22,23,23,22,20,22,21,20,20,19,17,16,15,13,12,12,12,11,11,10,10,9,9,8,8,9,8,7,8,8,8,7,8,6,6,6,6,7,7,6,7,7,6,7,7,8,6,8,7,8,7,8,8,8,9,8,8,9,9,10,11,10,10,9,10,10,10,10,10,10,10,9,8,9,9,8,7,7,7,7,7,7,6,7,7,7,6,5,6,6,5,6,6,6,6,7,7,7,7,8,8,7,7,8,8,8,9,9,9,10,10,9,9,10,9,8,9,8,8,9,9,9,8,9,9,7,7,8,7,7,6,6,7,6,6,7,7,6,6,6,6,4,4,4,3,4,4,3,2,3,1,1,0,1,2,2,3,3,4,4,4,4,4,4,5,5,5,6,6,8,6,6,7,6,7,7,7,7,8,8,8,8,9,10,10,11,9,10,10,9,9,10,10,9,10,10,8,8,9,9,8,7,8,8,8,8,7,8,8,7,8,7,7,8,6,7,7,6,7,6,6,4,5,5,5,4,4,3,3,3,4,6,6,7,7,8,7,6,6,7,7,7,8,8,9,8,8,9,9,9,9,10,9,9,10,10,10,10,11,11,11,12,11,12,12,12,13,13,12,13,13,13,12,11,11,12,13,12,11,12,12,13,13,12,14,15,16,15,16,17,17,17,18,19,19,18,20,21,21,21,22,23,24,24,25,24,26,25,26,25,23,26,25,24,26,25,24,26,25,26,27,26,28,26,27,28,28,28,28,28,28,28,28,28,28,28,29,28,28,28,29,28,28,27,27,27,27,28,27,28,28,27,28,26,26,27,26,25,24,25,23,23,22,21,21,18,17,18,16,15,14,13,12,13,12,12,12,13,14,13,14,13,13,14,14,13,15,15,14,14,16,16,16,17,16,17,17,15,15,15,15,15,15,15,17,15,18,18,17,17,17,17,16,15,15,15,15,15,15,14,13,13,13,12,13,12,13,11,12,13,12,11,12,12,12,11,12,12,11,12,12,13,12,14,13,12,13,12,11,11,10,10,10,9,9,9,9,8,8,9,9,8,8,9,8,7,8,7,7,6,7,9,8,6,7,7,8,7,7,8,6,7,7,7,7,7,9,8,8,7,6,5,5,5,6,5,4,5,6,6,5,6,6,7,7,7,8,8,8,7,8,7,8,7,8,7,6,7,8,7,6,8,7,6,7,8,8,7,8,9,8,7,9,9,9,9,8,9,9,9,9,9,11,11,10,9,9,9,9,9,10,9,7,7,8,8,9,7,8,9,8,8,9,9,7,8,9,9,9,9,9,9,10,9,9,9,9,8,8,8,8,8,8,8,8,8,8,8,9,8,8,9,9,9,10,9,9,9,10,10,9,9,10,10,10,11,10,10,9,10,10,9,9,8,8,9,8,9,9,8,9,9,9,9,10,9,9,9,9,10,11,11,11,11,9,11,11,11,10,10,12,10,10,10,11,10,10,10,11,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,10,11,11,11,12,11,11,11,12,12,11,13,12,12,12,11,12,11,12,12,11,12,12,12,11,12,12,11,11,12,11,13,12,12,11,12,13,12,12,11,11,12,12,14,12,13,11,14,12,11,12,13,12,11,12,11,10,11,11,11,11,11,11,10,10,11,11,9,10,10,11,12,12,13,14,15,16,15,16,17,19,21,19,21,23,23,23,22,23,23,22,25,23,23,25,23,26,26,27,26,27,25,27,27,27,28,27,27,27,26,26,27,27,27,27,27,27,27,28,27,25,27,27],[28,28,28,27,28,28,28,28,28,26,27,24,27,25,26,26,26,27,24,27,26,24,26,26,24,25,27,26,25,27,26,26,28,28,26,27,27,27,28,27,28,27,27,25,26,26,24,22,25,24,20,21,23,21,19,22,21,19,19,19,18,16,15,14,13,13,13,12,12,13,11,11,10,10,10,11,9,9,10,11,9,9,10,8,8,8,8,10,8,7,9,8,7,9,9,9,9,10,9,8,10,9,9,9,10,9,10,9,10,10,11,11,10,11,12,11,11,11,12,11,11,11,11,10,9,9,9,9,9,8,9,8,7,7,7,7,7,7,7,7,6,7,8,8,7,9,9,9,10,10,9,10,11,9,9,10,11,10,10,11,10,11,10,10,11,10,10,10,10,9,10,10,10,9,9,9,8,9,9,8,8,7,8,8,6,6,7,6,5,5,6,4,4,4,5,3,3,3,4,3,2,2,1,0,1,2,3,4,5,5,5,5,4,5,5,6,7,6,6,6,7,8,7,8,8,9,8,9,9,9,10,10,11,11,11,11,11,11,11,10,11,11,11,11,12,11,10,9,10,9,9,8,9,9,8,8,8,8,8,7,7,7,8,7,6,6,6,5,6,6,6,4,5,5,5,4,4,3,4,4,4,4,6,6,6,8,7,8,7,7,9,8,8,9,9,9,10,10,9,10,11,12,11,11,12,11,12,13,12,12,13,15,14,14,14,14,15,15,14,15,15,14,13,14,13,13,13,13,13,13,13,13,13,14,14,15,14,16,15,16,17,17,17,18,19,20,19,20,21,23,21,24,25,25,26,26,26,25,26,25,25,25,25,25,25,26,26,25,26,26,27,27,28,27,28,29,28,28,28,29,29,29,28,29,28,28,29,29,29,28,28,29,28,28,28,28,28,28,29,29,28,29,28,27,27,27,27,27,26,26,26,24,24,23,23,20,19,20,17,16,15,15,13,14,15,14,14,15,15,16,14,15,16,16,15,15,17,15,15,16,17,16,18,18,19,18,18,16,17,15,16,16,18,18,19,18,20,19,19,19,18,17,18,17,15,16,18,17,17,16,16,15,15,15,15,16,13,14,13,14,14,13,14,15,14,12,13,14,14,13,14,14,12,13,14,13,14,12,13,13,12,11,11,11,10,10,9,10,9,9,9,8,8,8,8,7,8,7,7,6,8,8,6,7,9,7,7,8,9,8,7,9,9,9,8,8,9,9,9,9,7,6,5,6,6,5,5,6,6,6,6,5,6,6,7,8,8,9,8,8,9,9,8,8,10,9,8,9,10,8,8,10,9,8,9,9,8,8,10,10,8,9,10,10,10,10,10,10,11,11,11,11,12,13,11,11,12,10,10,10,10,9,8,9,9,8,8,8,9,10,9,8,10,10,8,9,10,10,9,10,11,10,11,10,10,10,10,9,9,10,11,10,10,10,10,11,9,10,10,10,10,9,10,10,10,10,10,10,10,11,10,9,10,11,10,11,11,12,11,11,10,10,10,10,10,11,10,11,10,10,10,11,10,11,11,11,10,10,12,11,12,11,12,11,11,12,12,11,11,11,12,10,11,12,12,11,11,12,11,11,12,12,11,12,11,12,11,11,12,12,12,12,13,12,11,12,13,12,13,13,14,12,12,11,11,13,12,12,13,13,12,12,14,13,12,13,14,13,14,14,13,13,13,13,14,15,14,14,13,13,14,14,14,13,12,13,13,13,12,12,11,12,12,12,12,12,12,11,10,12,11,11,11,12,11,11,11,11,11,11,11,10,11,10,11,11,12,13,14,14,15,15,17,18,18,18,21,21,23,23,22,21,22,21,22,24,24,23,25,24,26,25,27,26,25,24,27,26,25,26,26,26,25,26,26,27,26,26,27,26,26,26,28,26,24,27,27],[28,28,28,28,28,28,28,27,27,27,27,26,27,26,26,27,27,27,26,27,26,25,26,27,25,26,27,26,26,27,25,26,28,28,26,27,27,27,27,27,27,26,26,25,26,26,25,23,25,22,21,23,23,20,20,22,21,20,21,20,18,17,16,14,14,14,15,13,14,13,14,13,14,13,12,13,12,11,11,11,11,12,11,9,9,8,8,7,7,8,8,8,9,9,9,8,9,11,11,10,12,13,11,12,13,12,12,11,12,12,12,12,12,13,13,14,13,13,13,13,13,13,13,13,13,13,12,12,12,12,11,10,9,9,8,8,8,8,7,9,9,9,9,10,9,9,11,11,11,12,12,12,13,13,13,13,13,13,13,13,14,11,13,14,13,12,13,13,13,13,14,13,12,13,13,12,11,13,11,12,12,11,10,11,9,10,9,8,8,7,8,8,7,7,6,5,5,5,4,4,3,3,2,1,0,1,2,4,5,6,6,3,5,7,7,8,8,10,9,11,8,10,11,11,12,12,13,12,13,13,11,13,13,13,13,13,12,13,13,13,12,14,13,13,14,13,14,13,12,13,12,11,12,12,11,10,11,10,10,11,9,11,11,10,10,9,10,8,9,8,8,7,6,6,6,5,5,6,5,4,6,7,8,7,8,9,9,10,10,11,12,11,13,13,12,12,13,13,13,12,13,14,14,13,15,14,14,15,15,15,15,18,16,16,16,17,17,16,16,15,16,16,15,14,13,15,16,15,14,15,15,15,15,16,15,15,17,16,16,17,17,17,18,20,19,20,20,21,22,23,23,24,25,25,26,26,27,27,27,26,24,26,26,26,26,26,27,26,26,26,27,27,28,27,28,28,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,28,29,28,28,27,27,27,27,27,26,25,26,25,25,24,22,24,21,19,21,19,17,17,16,16,16,16,17,16,17,16,18,16,17,19,19,17,19,20,18,16,18,20,18,18,20,19,19,19,18,19,18,19,19,20,20,20,21,21,20,20,21,19,19,19,19,18,18,20,19,19,18,18,17,18,16,18,19,15,16,15,16,17,17,17,17,17,17,16,16,16,15,16,16,15,16,17,17,16,15,16,15,15,14,14,14,13,13,14,14,12,13,13,11,11,12,12,11,11,10,10,9,11,11,8,9,11,9,9,10,10,9,7,9,8,8,7,9,9,9,9,8,7,6,5,6,6,6,5,5,5,6,4,5,5,7,8,8,8,8,7,6,7,8,7,6,8,7,7,8,8,8,7,9,9,8,10,10,10,11,12,13,11,12,12,12,13,13,13,12,14,14,14,14,14,16,15,15,14,14,13,12,13,12,11,11,12,12,11,9,11,12,11,10,11,12,10,11,11,10,10,10,11,11,11,11,11,11,10,10,9,10,9,10,10,9,11,12,12,11,10,10,12,12,12,10,11,10,10,10,9,10,10,9,10,11,11,12,12,12,12,11,11,11,11,11,11,12,12,12,12,10,14,13,12,13,14,12,13,12,14,14,14,15,14,14,14,14,14,12,13,13,13,11,12,12,13,11,11,13,13,11,12,13,12,12,13,13,14,13,13,14,14,13,14,15,14,13,14,15,15,14,15,14,14,13,13,15,13,13,16,13,12,12,16,14,13,16,15,14,16,17,14,14,16,16,15,17,16,15,16,16,16,16,16,15,14,15,14,15,15,13,12,14,15,14,14,14,16,14,14,15,15,14,14,14,14,14,14,15,13,14,15,14,14,14,14,13,14,16,17,16,17,18,19,19,21,20,21,22,24,23,24,23,25,23,23,26,24,25,27,25,27,26,28,28,27,26,28,27,26,28,27,27,27,26,27,28,28,27,28,28,28,28,28,27,26,28,28],[29,29,28,28,29,29,28,28,27,27,27,25,27,26,27,26,26,27,24,27,26,24,27,27,24,26,28,26,26,28,25,27,28,29,27,28,28,28,28,28,29,28,28,27,27,26,25,23,26,24,21,23,24,22,21,23,22,20,21,20,18,16,16,16,14,15,15,13,13,13,13,12,13,13,11,12,11,11,11,11,11,12,10,8,8,9,7,7,6,6,9,8,8,11,10,11,11,12,11,11,12,11,11,11,13,12,12,13,14,14,14,14,13,13,15,15,15,14,15,14,14,14,15,14,12,13,12,11,12,11,10,9,10,10,9,10,8,8,9,9,9,9,10,9,10,12,11,11,11,12,12,12,13,12,11,13,12,12,12,13,14,12,13,13,12,12,12,13,12,13,13,13,12,14,13,11,12,13,12,12,11,12,11,10,10,10,9,9,9,9,10,7,8,8,6,5,4,5,4,4,3,4,3,2,1,0,1,2,3,5,4,4,5,6,6,7,8,9,9,9,10,10,11,10,11,12,12,12,12,13,13,13,13,15,14,15,15,14,14,13,15,15,14,15,15,14,14,14,14,14,12,12,14,13,12,11,11,11,12,11,11,12,12,11,10,9,10,10,9,8,9,7,6,7,7,6,6,5,4,4,5,5,6,7,7,8,9,9,9,10,11,12,13,13,12,14,14,14,14,13,14,14,15,14,15,15,17,16,17,16,16,19,17,17,17,17,19,18,17,17,17,16,17,15,15,16,17,15,15,16,16,16,15,16,16,15,17,17,16,18,17,18,19,19,19,21,22,22,23,24,23,24,26,25,26,26,27,26,27,26,25,26,26,26,26,26,26,27,26,27,28,28,29,27,28,29,29,29,29,29,29,29,29,28,29,29,29,29,29,28,29,28,29,28,28,28,28,29,28,29,28,28,29,28,28,28,28,26,26,26,26,24,24,23,22,22,20,21,19,18,18,17,16,17,18,18,16,18,18,18,17,17,19,18,19,19,19,18,19,20,21,20,19,21,20,20,21,19,20,18,18,19,19,19,21,22,22,21,20,22,21,20,20,20,18,19,20,20,20,19,19,18,18,17,19,19,19,18,15,17,18,17,17,17,19,16,17,17,18,17,17,17,15,17,17,17,16,16,16,14,16,14,15,15,15,14,14,14,12,13,13,13,11,12,12,10,11,10,10,9,11,10,9,8,9,8,8,8,9,9,7,8,9,9,8,9,9,9,11,10,8,7,5,5,5,4,5,4,4,5,5,5,6,7,8,8,7,9,8,7,8,7,7,7,8,6,6,7,8,7,7,8,8,8,9,11,9,10,11,13,11,11,12,13,13,12,13,14,14,15,15,16,16,16,15,15,14,13,14,14,13,12,11,11,11,12,11,9,11,12,10,9,11,12,10,9,11,9,10,11,11,11,10,8,11,10,9,10,8,9,9,10,11,10,11,12,12,11,11,12,12,12,11,11,11,10,10,11,9,11,11,9,9,11,10,12,12,13,11,11,10,12,10,10,11,12,10,11,12,12,11,12,12,13,12,13,14,12,13,14,14,15,15,14,13,15,15,13,13,14,14,12,14,12,13,13,12,12,13,13,11,13,13,11,13,13,14,14,11,14,14,14,12,14,15,13,14,15,15,14,15,16,16,14,14,16,16,14,15,16,14,14,17,16,14,16,16,15,15,16,15,15,15,16,15,16,16,17,16,15,16,15,17,14,15,15,16,17,14,16,13,15,15,14,16,15,14,13,15,16,14,14,15,16,15,15,15,16,14,15,17,16,15,15,15,15,15,16,17,17,16,18,18,20,21,21,22,21,25,24,24,23,24,24,23,25,24,23,27,23,26,25,28,26,27,25,28,27,26,27,27,27,26,25,27,28,27,26,28,27,27,28,28,26,26,27,27],[28,28,28,28,29,29,28,28,28,27,27,27,28,27,27,27,27,28,26,28,27,25,28,28,26,27,28,26,27,28,26,27,28,28,27,28,28,27,28,27,28,27,27,26,27,27,24,24,26,24,21,24,24,22,21,24,22,20,22,21,19,17,16,15,15,13,14,13,13,12,12,11,11,11,9,10,9,9,8,9,9,8,8,7,7,7,5,6,5,6,6,6,6,7,7,8,7,8,8,8,9,8,9,9,10,10,11,12,12,11,12,13,11,10,11,13,12,14,12,14,13,10,12,13,11,10,11,10,9,9,10,9,7,8,8,9,9,7,9,7,8,7,8,7,8,8,9,8,8,9,9,10,8,9,9,9,10,10,10,11,11,9,12,11,10,9,11,10,9,10,11,9,9,12,11,9,10,12,10,10,8,9,9,8,8,9,8,8,8,7,9,9,7,7,6,6,5,5,6,5,4,4,3,3,2,1,0,1,2,4,4,2,4,4,5,5,4,6,6,8,7,7,9,7,8,10,10,8,9,10,10,10,12,12,12,12,11,12,12,13,10,12,12,12,11,12,12,11,10,12,11,9,10,11,10,10,10,11,10,11,9,9,10,10,8,9,8,9,9,7,8,7,6,7,7,6,6,5,4,3,5,4,5,5,6,8,7,8,7,8,8,9,10,11,10,10,11,11,11,11,11,13,13,11,13,14,13,13,14,14,15,15,15,15,15,16,16,16,15,15,15,14,13,14,12,14,15,13,13,14,14,15,15,14,15,16,15,16,17,18,18,18,18,19,19,20,20,21,20,23,23,23,25,24,25,25,27,26,27,26,24,27,25,25,26,26,26,27,25,26,28,27,28,28,28,28,29,28,28,28,29,29,28,28,29,29,29,29,29,29,29,29,29,29,28,28,28,29,28,29,28,28,28,27,27,28,28,26,26,26,24,24,24,22,22,21,20,20,18,17,16,15,15,15,15,16,14,16,17,16,17,17,17,18,17,18,19,18,18,19,21,19,19,22,20,20,21,20,20,18,18,19,19,19,20,21,22,22,22,22,20,21,20,19,18,19,20,19,19,18,17,18,17,16,16,16,15,15,15,16,16,15,15,16,16,15,16,16,16,15,16,16,15,17,16,16,16,15,14,14,15,14,13,13,12,12,13,12,11,11,12,12,11,10,10,10,11,9,9,9,10,10,9,9,10,9,8,8,8,8,8,8,8,8,9,9,10,9,10,9,7,7,5,6,5,4,5,4,4,5,5,6,4,6,7,7,7,7,6,6,8,6,5,6,8,6,6,8,7,6,6,8,7,8,9,9,9,10,9,10,9,11,10,11,13,12,11,12,13,13,14,14,15,15,15,12,12,13,13,13,11,10,11,10,10,11,11,9,11,10,9,11,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,9,8,8,8,8,8,7,8,9,8,8,8,8,8,9,9,9,10,8,9,9,8,10,9,8,9,10,10,11,10,11,11,11,9,10,10,9,10,11,9,11,11,10,11,12,11,12,12,11,12,12,13,13,12,13,15,13,13,14,14,13,12,14,13,12,13,12,13,13,12,12,13,14,12,12,14,13,13,12,13,12,12,13,13,12,14,14,13,12,14,14,14,14,14,14,15,14,13,14,15,15,14,14,13,13,14,14,14,15,15,15,14,16,14,14,15,15,15,16,15,16,15,15,15,15,16,14,14,15,15,15,14,14,12,14,14,13,13,14,14,13,14,15,13,14,14,14,13,14,15,16,13,14,15,14,14,14,14,14,14,15,17,17,17,18,19,20,21,20,23,23,26,23,24,24,25,24,24,27,24,26,28,24,27,27,28,27,28,27,29,28,28,28,29,28,27,26,28,28,28,28,29,28,28,29,29,28,27,28,28],[29,29,29,29,29,30,30,28,29,28,28,28,28,27,28,28,28,28,28,28,27,27,28,27,27,27,27,27,27,27,26,28,27,28,27,28,27,28,28,27,28,27,26,27,27,26,25,24,25,23,22,23,23,22,21,22,22,21,20,20,18,16,15,13,12,11,11,10,9,10,9,9,8,9,8,10,6,7,6,7,8,6,6,6,5,4,4,5,4,4,4,4,4,5,5,5,5,6,6,6,7,6,7,7,7,7,7,7,8,8,8,8,7,7,8,8,8,9,8,8,8,7,8,7,7,7,7,7,6,7,7,6,6,6,6,7,6,5,6,6,5,5,5,6,6,6,6,7,6,6,6,7,6,6,6,7,6,7,8,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,6,8,8,7,7,6,7,7,7,6,7,7,7,7,6,6,5,6,6,6,6,6,4,5,5,4,4,3,4,3,2,1,0,1,1,2,2,3,3,4,4,3,4,7,6,6,5,6,7,7,7,8,8,7,8,8,8,8,9,9,9,9,8,8,9,8,9,9,8,8,9,9,8,8,8,8,7,8,8,8,8,8,8,7,8,7,7,7,7,7,8,8,7,7,6,6,6,5,5,5,4,5,5,2,3,3,3,4,4,4,5,6,6,7,7,8,8,9,8,9,8,8,9,8,9,9,9,9,10,10,10,11,10,10,10,11,11,11,11,12,11,12,11,10,12,11,11,11,11,10,10,11,11,11,10,11,11,12,12,12,14,14,13,16,16,17,17,17,19,19,18,20,19,21,22,22,23,24,24,25,26,27,24,27,25,24,26,24,22,25,26,25,25,25,26,27,26,28,27,28,27,27,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,29,27,28,28,28,28,27,28,28,27,28,26,26,27,26,25,26,24,24,22,22,21,21,19,17,19,14,14,13,11,11,12,11,10,12,12,13,13,14,13,12,14,13,13,14,14,13,14,16,15,15,17,17,16,16,15,16,14,14,14,14,13,16,16,16,18,17,16,16,14,16,15,14,14,13,14,13,13,13,12,11,11,11,11,12,11,11,11,11,11,12,11,11,12,12,11,11,12,11,12,11,13,13,12,12,13,12,11,10,10,10,9,9,9,9,9,9,9,9,9,7,9,9,8,9,7,7,7,7,7,7,7,7,5,7,6,6,6,5,7,7,7,7,8,9,9,8,8,5,5,3,4,4,4,3,3,3,3,3,4,4,4,5,5,6,6,4,4,5,5,5,4,6,5,4,5,5,5,5,8,6,6,7,7,7,6,9,9,8,8,9,9,9,10,8,9,10,10,10,10,10,10,10,10,10,10,10,9,9,8,8,8,9,8,8,7,8,9,8,8,8,9,8,8,8,7,9,8,8,8,8,9,8,8,9,6,7,7,7,6,6,5,7,6,6,6,7,6,6,7,6,7,7,7,8,7,7,7,7,8,8,7,9,9,8,9,8,9,9,8,7,8,8,8,9,9,9,8,9,9,8,10,9,8,8,10,10,9,9,10,10,11,9,10,10,10,10,10,10,10,9,10,10,9,9,10,9,10,10,9,9,10,9,9,9,8,10,9,9,9,10,9,9,11,10,10,11,9,11,10,10,11,10,11,11,12,10,10,10,10,10,10,11,10,10,11,11,10,9,10,11,11,10,12,11,11,11,10,12,10,11,11,10,11,11,11,11,11,10,12,10,10,11,11,11,12,11,11,11,11,11,10,12,14,11,11,11,12,11,10,11,11,11,12,13,13,14,15,16,16,17,17,19,20,20,21,24,24,24,23,24,24,23,27,25,25,27,24,27,27,28,27,26,24,27,27,26,28,27,26,27,26,26,28,27,27,28,28,27,28,28,26,25,28,27],[28,28,28,28,28,29,29,28,29,27,27,27,27,27,27,27,27,28,26,28,27,26,28,28,27,27,28,27,28,27,27,28,29,29,28,29,28,28,28,28,29,27,27,27,28,27,24,24,26,23,22,23,24,22,21,22,22,20,19,19,17,15,13,11,11,10,9,9,8,8,7,7,7,7,6,6,6,6,5,5,5,4,5,4,4,3,3,4,3,3,4,3,3,5,4,5,5,5,5,5,6,5,5,6,6,6,7,6,7,7,7,6,6,6,6,7,7,7,7,7,7,6,6,6,6,5,6,6,5,5,6,6,5,5,5,6,5,5,5,4,5,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,5,6,6,6,5,6,5,6,6,6,5,5,5,6,5,5,6,5,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,5,5,4,4,4,4,3,4,2,3,2,1,0,1,1,1,2,2,3,4,2,2,3,4,3,5,5,6,5,5,5,5,5,6,6,6,7,7,8,9,7,7,8,7,6,7,7,6,6,7,7,6,6,6,5,6,6,7,7,6,7,7,7,6,6,6,6,6,6,5,6,5,6,7,5,4,5,4,4,3,3,4,3,2,3,3,3,3,3,4,4,5,5,5,6,5,6,6,6,6,7,7,6,7,7,7,7,8,8,9,8,8,9,9,9,10,9,10,9,9,10,10,10,10,10,10,9,10,9,9,10,10,9,10,10,10,10,11,12,14,13,13,14,15,16,15,16,18,17,18,18,19,20,21,21,23,24,24,25,25,27,25,26,25,23,26,25,22,25,26,25,25,25,26,27,27,28,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,27,29,28,27,28,27,27,27,27,24,25,25,24,22,22,21,20,18,17,16,14,13,12,10,10,11,10,10,10,11,11,12,11,11,12,12,12,13,14,13,13,15,14,14,14,16,16,15,15,14,14,13,13,14,14,14,15,15,16,16,16,16,15,14,15,14,13,13,13,14,13,12,12,12,11,11,11,11,10,10,10,10,10,11,10,10,10,10,10,10,10,10,11,11,11,12,12,11,11,11,10,9,9,8,8,8,7,8,7,8,7,7,8,7,7,7,7,6,7,6,6,6,7,6,6,6,6,6,5,5,5,5,4,5,5,6,6,6,7,7,8,6,5,4,3,4,3,2,3,3,3,3,2,3,3,4,5,6,6,7,6,5,6,5,3,5,6,5,4,5,5,4,4,6,5,5,5,5,6,6,6,7,7,7,7,6,7,8,6,7,8,8,8,9,9,9,9,9,9,8,9,8,9,8,7,7,7,7,6,6,6,7,6,7,6,7,6,6,6,7,8,7,6,7,7,7,6,6,7,6,6,5,6,5,6,5,5,5,5,5,5,5,5,6,6,6,7,6,6,7,6,6,7,5,7,7,8,8,7,8,7,7,6,7,6,7,7,7,8,7,7,6,7,7,7,7,8,7,8,9,9,8,9,9,9,9,9,9,9,9,8,8,8,8,8,9,9,8,8,8,8,9,8,8,8,8,8,8,8,8,8,8,8,8,9,9,8,9,9,8,10,9,9,9,10,9,9,10,10,10,9,9,9,9,9,9,9,9,9,10,10,10,9,9,10,10,10,11,10,10,10,10,11,9,10,10,10,10,11,11,10,9,9,10,9,9,10,9,9,9,9,9,9,9,9,9,9,9,9,10,9,9,9,8,9,10,10,10,12,13,14,15,15,14,16,17,17,20,20,20,22,22,23,21,22,23,22,25,23,24,25,24,26,25,26,25,26,24,27,27,25,27,26,26,26,25,25,27,27,26,27,26,26,26,27,26,24,25,26],[29,28,28,29,28,29,29,28,29,28,28,28,28,27,27,27,28,28,27,28,28,26,28,28,27,27,28,27,27,28,27,27,28,29,28,28,28,28,28,28,29,28,28,27,28,27,25,25,26,24,22,23,25,22,22,24,22,21,21,21,19,16,15,12,11,11,9,10,9,9,9,7,9,7,7,7,6,6,5,6,7,5,4,4,4,4,3,4,2,4,4,3,4,4,4,4,5,5,4,4,6,5,5,5,6,6,6,6,7,8,8,7,7,7,6,7,8,7,8,7,7,7,6,6,6,6,5,5,6,6,5,5,5,5,5,5,4,3,3,4,4,3,3,5,4,4,4,6,4,5,6,7,5,6,5,5,5,6,6,6,7,6,8,6,6,7,7,7,6,7,7,6,6,7,7,7,7,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,3,4,3,4,4,4,5,4,4,5,4,4,4,3,2,2,1,0,1,1,2,2,2,3,2,3,3,4,3,4,6,5,7,8,8,8,6,7,6,7,8,8,9,8,8,8,9,8,8,8,8,7,8,8,7,7,8,7,7,8,7,7,7,7,6,7,6,7,7,7,6,6,6,6,5,6,4,5,5,5,5,5,5,4,5,4,3,2,3,3,4,4,4,4,4,4,5,7,7,7,7,7,8,8,8,9,8,9,8,9,9,8,9,10,10,9,10,10,10,10,11,11,10,11,11,11,11,11,11,11,11,10,10,10,11,10,10,11,12,11,12,11,12,13,13,13,16,16,17,17,17,20,20,19,21,21,21,22,23,24,25,25,26,26,27,26,27,26,26,27,25,25,27,26,25,26,26,27,28,27,28,27,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,28,28,28,28,28,29,28,28,28,28,27,27,26,26,26,25,23,24,23,21,22,19,19,17,15,14,13,11,11,11,11,10,11,11,11,12,12,12,12,13,13,13,13,14,14,14,15,14,16,17,16,15,16,14,15,14,13,14,14,14,16,15,17,17,17,16,15,15,15,14,13,13,14,14,14,12,12,13,11,10,11,12,10,10,10,10,11,10,10,11,11,11,11,11,10,10,11,12,11,12,12,11,11,11,10,10,10,9,9,8,9,8,8,8,8,8,8,8,9,8,7,7,8,7,6,7,7,6,6,5,6,6,5,5,5,5,5,5,5,6,6,6,7,7,8,6,5,4,3,4,3,2,3,6,2,3,2,3,3,4,4,4,4,4,4,3,5,4,3,4,4,4,3,4,4,4,4,5,5,6,6,6,7,6,6,7,7,7,7,8,9,8,8,9,9,9,9,9,9,10,9,9,8,9,8,10,8,8,8,7,7,7,7,6,7,7,6,6,7,7,6,7,7,6,6,7,7,7,6,6,7,6,6,5,5,5,4,5,6,5,5,5,6,6,5,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,8,7,8,7,7,6,6,7,7,7,7,8,7,7,8,8,9,8,8,9,9,8,9,10,9,10,9,9,9,9,8,8,9,8,7,8,8,9,8,7,8,8,8,8,8,8,9,9,9,9,9,9,9,9,8,9,10,9,9,9,10,10,9,10,10,10,10,10,11,10,10,10,10,10,10,10,10,9,10,11,10,10,11,10,10,10,11,10,11,11,10,11,10,12,10,11,10,10,10,11,10,10,10,8,10,10,10,9,10,10,10,9,10,9,10,10,10,9,9,10,10,9,9,10,9,9,9,11,11,12,12,14,15,15,13,15,16,18,19,22,23,24,25,24,22,24,24,23,26,24,25,26,24,27,26,27,26,27,26,28,27,27,28,27,27,27,25,27,28,28,27,28,27,27,28,28,26,25,26,26],[28,28,27,28,28,28,28,28,28,27,27,26,27,26,26,26,27,27,26,27,27,26,27,27,26,27,26,26,26,26,26,27,27,28,26,27,27,27,28,27,28,26,26,26,26,26,24,24,24,22,22,23,22,21,19,21,18,19,18,18,16,15,13,11,9,9,8,7,7,7,7,6,6,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,4,4,4,3,4,5,4,4,6,5,5,5,6,5,5,6,6,7,7,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,3,3,4,3,3,3,4,4,4,5,6,5,4,5,6,5,6,5,5,6,6,5,6,5,5,6,6,6,6,6,6,6,6,7,6,5,6,7,5,6,6,5,5,5,5,5,5,5,4,4,4,3,4,4,3,3,4,3,4,4,3,4,4,4,5,4,4,4,4,3,2,1,1,0,1,1,2,2,2,2,2,3,3,3,5,6,6,6,6,6,6,6,6,6,5,6,6,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,5,6,5,5,5,5,5,5,4,5,4,4,5,4,5,4,5,4,4,4,3,3,2,2,2,3,3,3,3,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,9,9,9,8,9,9,9,10,10,9,9,9,8,8,8,9,8,8,9,9,9,10,10,11,12,13,12,14,15,15,14,17,17,17,17,19,19,19,21,21,21,24,23,24,24,26,25,25,24,23,25,24,23,24,24,24,25,24,24,27,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,27,26,26,27,26,26,26,25,26,26,26,24,24,23,21,22,20,20,19,18,16,15,13,11,10,10,9,10,10,10,10,10,10,10,10,11,11,12,11,12,13,11,12,13,13,13,14,15,15,14,14,13,14,13,12,12,13,13,13,15,15,15,15,15,14,15,14,13,13,12,13,12,11,11,11,11,10,10,10,9,9,9,9,9,9,9,8,9,8,9,9,9,9,9,10,10,10,11,10,10,9,9,8,8,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,5,5,5,6,5,6,5,5,5,6,5,4,5,4,5,4,5,6,6,7,7,9,6,6,4,3,3,3,2,2,2,2,3,3,3,3,4,4,4,4,5,3,3,4,3,3,3,4,3,3,4,4,3,4,4,4,6,4,5,5,5,5,6,6,6,6,6,7,6,6,7,8,7,7,8,7,8,7,8,8,7,7,7,7,6,7,6,6,6,7,6,7,6,5,6,6,6,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,4,5,4,5,4,5,5,5,5,5,5,5,5,6,5,5,6,5,6,6,6,5,5,5,6,6,7,7,6,6,6,5,5,5,5,5,6,5,6,6,6,6,6,6,7,7,6,7,7,7,7,8,7,8,7,8,8,8,8,8,7,7,7,6,7,7,7,6,7,7,6,6,7,6,6,7,6,7,7,6,7,7,7,7,8,7,8,8,8,8,8,8,8,8,8,8,10,9,9,9,9,9,8,9,8,8,9,9,8,9,10,8,8,8,9,9,10,10,9,9,9,10,9,10,9,9,9,10,9,8,8,8,9,9,8,8,8,8,8,7,8,8,8,8,8,9,8,8,8,8,8,8,8,8,8,9,9,11,11,13,12,13,13,14,15,16,17,19,19,22,21,20,20,21,20,19,24,21,22,23,22,25,24,25,24,25,23,26,25,24,27,25,24,25,26,25,26,25,25,25,25,24,26,25,26,23,24,25],[29,29,28,28,28,29,29,28,28,27,28,27,28,26,27,27,28,28,26,28,27,26,28,27,26,27,28,27,28,27,27,28,28,29,28,28,27,28,28,27,28,27,27,27,27,27,24,24,25,24,22,22,23,21,20,21,20,19,19,19,16,15,13,11,10,9,8,8,7,7,6,6,6,6,5,6,5,6,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,6,5,6,6,6,7,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,3,3,3,3,3,3,4,3,4,5,4,3,5,5,5,5,6,5,5,5,6,6,5,5,5,5,5,6,6,5,6,6,6,6,6,5,5,6,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,3,3,4,3,3,3,4,3,3,4,4,3,3,2,2,2,2,1,0,1,2,2,2,2,3,2,3,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,4,5,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,7,8,8,8,8,8,9,8,8,8,8,7,8,8,8,8,8,8,8,10,10,11,12,12,13,15,15,16,15,16,18,18,18,19,21,20,20,21,22,23,24,24,25,26,25,26,25,24,26,24,22,25,25,24,25,26,25,27,26,27,27,27,28,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,27,27,27,27,27,27,28,27,27,27,27,27,26,26,26,26,24,24,23,22,23,20,19,18,15,16,12,11,10,9,8,9,9,8,9,9,9,9,9,9,10,10,10,10,12,11,11,12,12,12,12,14,14,13,13,12,13,11,11,11,11,12,12,13,14,14,14,13,13,13,13,12,12,11,11,11,11,10,10,10,9,9,9,8,8,8,8,8,7,8,8,8,7,8,7,8,8,8,9,9,9,10,9,9,9,9,7,7,7,6,6,6,6,6,5,5,5,5,5,5,4,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,8,7,7,6,5,4,3,3,3,2,3,2,2,2,2,3,3,3,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,4,3,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,5,6,6,6,6,7,6,7,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,6,5,4,5,6,5,5,6,5,6,5,5,5,5,5,6,5,5,4,4,4,4,5,4,4,4,5,5,5,4,5,5,5,5,5,6,5,5,5,5,6,5,5,6,6,7,7,6,6,6,6,5,5,5,5,5,5,5,6,5,5,5,5,6,5,6,5,6,6,6,6,7,7,6,7,6,7,6,6,7,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,7,8,7,7,8,8,8,8,8,8,7,8,8,8,8,8,8,8,8,9,8,9,8,8,8,8,8,8,8,7,8,8,7,8,7,7,7,7,7,7,7,7,7,7,6,7,7,7,7,7,6,6,7,8,8,9,10,11,12,13,12,14,14,16,18,18,19,21,22,21,19,21,22,21,23,21,23,24,22,24,24,25,25,25,24,25,26,24,26,25,25,25,25,25,26,26,26,26,26,25,26,26,25,24,25,26],[29,28,29,29,29,29,29,29,29,29,29,28,29,28,28,28,28,28,27,28,28,27,28,28,27,28,28,27,28,27,27,28,28,28,28,28,28,28,28,28,28,28,27,27,27,27,25,24,25,24,23,23,24,22,21,22,21,20,19,20,17,15,13,11,9,9,7,7,7,7,6,5,5,4,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,4,4,4,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,2,2,3,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,2,2,1,1,1,0,1,1,1,2,1,2,2,2,2,3,3,3,3,4,3,3,3,4,4,5,5,6,6,5,5,5,5,4,5,5,4,4,5,4,4,4,4,3,4,4,4,4,4,5,4,5,4,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,3,2,2,4,3,3,4,4,3,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,8,8,8,7,8,8,8,7,8,7,7,7,8,7,7,8,9,9,8,10,12,12,12,14,15,17,16,17,19,19,18,20,20,21,21,23,24,24,25,26,26,26,25,26,25,23,26,24,24,25,26,26,25,26,26,26,27,28,26,27,27,27,28,27,27,27,27,27,27,27,28,28,28,28,28,29,28,28,28,28,27,28,28,27,28,28,28,28,26,27,26,26,25,25,24,23,23,21,21,20,18,16,15,12,11,10,8,8,8,8,8,8,9,9,9,9,8,9,10,9,10,10,10,10,11,11,11,12,13,12,12,13,11,11,11,11,10,10,11,12,12,12,14,12,12,11,12,11,11,10,10,10,10,9,9,9,9,8,8,8,8,7,7,8,7,8,7,7,8,7,8,8,8,7,8,8,8,9,9,9,9,8,8,7,7,7,6,5,5,5,5,5,4,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,7,8,8,6,4,4,3,3,3,2,2,3,3,3,2,3,3,4,4,4,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,6,5,5,6,6,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,4,5,5,5,5,4,4,4,4,4,4,4,5,5,5,6,6,5,6,6,6,6,6,6,6,7,7,7,7,6,6,5,4,4,5,5,5,4,5,5,4,5,5,5,5,6,5,5,6,6,7,7,7,7,7,7,7,7,6,6,6,6,6,6,7,7,6,6,6,6,7,6,6,6,6,7,6,7,6,6,6,6,6,7,6,6,7,7,7,8,7,7,8,7,7,7,8,8,8,8,8,8,7,7,7,7,8,7,7,8,8,7,7,8,8,7,9,8,8,8,8,9,8,8,8,8,8,9,8,8,8,8,9,8,8,7,7,7,7,6,7,7,7,7,6,7,6,7,7,6,7,7,6,6,6,8,8,10,10,11,13,13,12,13,14,15,16,18,18,21,22,20,19,21,22,21,24,21,22,23,23,25,25,25,25,25,23,26,25,25,26,24,24,25,24,24,26,25,25,26,25,24,26,26,25,23,25,25],[28,28,27,28,27,28,28,27,28,27,26,27,26,26,26,27,26,26,27,27,26,27,27,26,27,27,26,27,27,26,26,27,27,28,27,27,27,27,28,27,28,27,26,26,26,26,23,23,23,21,22,21,21,20,19,19,18,17,16,16,14,13,11,9,7,7,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,3,3,3,3,2,2,2,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,7,7,7,8,10,10,10,12,12,13,12,14,15,15,14,16,17,18,18,19,21,22,21,24,24,24,23,24,23,21,23,22,21,23,22,23,24,23,22,26,24,27,25,26,27,27,26,27,26,26,26,26,26,27,26,27,27,27,27,28,27,27,26,26,26,26,26,26,27,26,26,27,26,26,25,25,24,23,23,20,19,18,18,18,15,13,12,10,9,8,7,7,7,7,6,6,7,7,7,7,7,8,8,8,9,10,9,9,10,10,10,11,12,11,10,10,10,10,9,9,9,9,10,10,11,11,12,12,11,10,10,10,9,9,9,9,9,8,8,8,7,7,6,6,6,6,5,6,6,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,6,6,5,5,4,4,4,3,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,7,7,5,4,3,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,4,4,4,4,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,5,6,6,6,7,7,7,6,6,7,6,7,7,7,6,7,7,6,6,6,7,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,8,8,10,11,11,11,12,12,14,16,17,18,20,20,20,18,20,20,20,23,21,22,22,22,24,24,26,25,24,23,25,25,24,27,25,24,26,25,24,25,23,25,24,25,23,25,24,24,23,24,24],[28,28,28,29,28,29,28,28,28,28,27,27,27,26,26,27,26,27,27,27,27,27,27,27,26,27,26,27,27,26,26,26,27,27,26,27,27,27,27,26,27,27,26,26,26,25,24,23,23,22,21,21,21,20,19,20,18,18,17,16,14,13,11,9,8,7,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,3,3,3,4,3,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,3,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,3,2,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,3,3,3,3,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,6,7,8,8,9,11,12,11,12,13,14,13,14,16,16,16,18,18,19,18,19,21,22,21,24,24,25,24,25,23,22,24,22,22,22,23,23,23,22,22,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,26,26,26,26,26,26,26,26,25,25,26,26,25,26,25,25,25,25,25,23,22,21,20,19,17,17,15,13,13,11,9,8,7,7,7,7,7,6,7,7,7,7,7,8,8,7,9,9,9,9,9,10,9,10,11,11,10,11,9,10,9,9,9,9,9,10,10,11,11,11,11,10,10,10,10,9,9,9,9,8,8,7,7,7,6,6,6,5,5,5,5,5,5,5,6,5,5,6,6,5,6,6,7,7,8,7,7,7,7,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,6,6,5,4,3,3,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,4,5,5,5,5,5,5,4,4,4,3,3,3,4,3,3,3,4,3,4,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,5,5,5,6,5,5,6,6,6,6,6,7,7,7,7,7,6,6,6,6,6,7,6,6,6,7,6,6,6,6,6,6,7,7,6,7,7,7,7,7,7,6,7,7,6,6,6,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,4,5,4,4,4,5,6,7,8,8,10,11,10,10,12,13,14,17,17,17,20,21,20,18,20,21,20,22,20,22,22,21,24,23,25,24,25,24,25,25,25,26,25,24,25,23,25,25,24,25,25,25,23,25,24,23,22,25,24],[29,29,29,29,28,29,29,28,29,28,27,27,28,27,28,27,27,27,26,27,26,26,27,26,26,26,26,27,27,26,26,27,27,28,27,27,26,28,27,27,27,27,26,26,26,26,24,23,24,23,22,21,22,20,19,20,19,18,17,17,14,12,10,8,7,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,2,2,2,3,2,3,2,3,2,3,3,3,2,3,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,6,6,7,8,9,10,10,11,13,14,12,14,16,16,15,17,19,19,19,20,23,22,23,24,24,24,24,25,23,22,24,23,22,23,24,24,24,24,24,25,25,26,25,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,28,27,27,27,27,25,26,26,26,27,26,26,27,25,25,25,24,24,23,22,21,20,20,18,18,16,13,12,10,8,7,6,6,5,6,6,5,6,6,6,6,6,7,7,7,7,8,7,7,8,8,8,9,9,9,9,9,9,9,8,8,8,8,8,9,9,9,10,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,4,4,4,5,4,4,5,5,5,5,5,5,5,5,6,6,6,7,7,7,6,6,5,4,4,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,6,6,4,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,2,2,2,2,2,2,2,2,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,6,7,8,9,11,10,10,12,12,13,16,17,17,19,20,19,17,19,21,20,23,20,23,22,22,26,23,24,24,25,22,25,24,24,24,24,24,24,22,23,24,23,23,24,24,23,24,24,22,21,23,23],[28,28,28,29,28,29,29,28,29,28,27,28,27,27,27,27,27,28,27,27,27,27,27,27,27,28,27,28,28,27,26,28,27,28,28,28,28,28,28,28,28,28,27,27,27,26,25,24,25,23,22,23,22,20,19,20,19,17,18,17,14,12,10,8,7,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,2,2,2,3,3,2,2,2,2,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,5,4,4,5,5,5,6,6,7,9,9,9,11,13,14,12,13,15,15,14,16,17,17,18,19,20,22,20,21,23,24,24,24,23,22,23,21,22,23,23,24,24,23,23,25,25,26,25,25,25,26,26,26,26,26,26,27,26,26,26,26,26,27,26,27,27,27,27,27,26,27,27,26,27,27,26,27,26,26,26,25,23,24,21,21,20,18,16,16,14,13,12,9,8,7,6,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,8,8,8,9,9,9,9,8,8,7,7,7,7,8,8,8,9,9,8,8,8,8,8,7,7,7,7,7,7,6,6,6,5,5,5,5,4,4,4,4,5,4,4,5,4,4,5,5,5,5,5,5,6,6,6,6,5,5,4,4,4,4,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,6,6,6,4,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,5,6,5,6,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,5,6,7,7,9,10,10,10,11,12,13,15,17,18,19,20,19,18,20,19,19,22,20,23,22,21,25,23,24,24,24,23,26,24,24,25,24,24,24,23,23,25,25,23,24,24,23,24,24,24,21,24,24],[28,27,28,28,27,28,28,27,28,27,26,26,26,25,25,26,26,26,26,26,26,27,26,26,26,26,26,26,27,25,25,26,26,27,26,26,26,26,26,26,27,26,26,25,25,25,23,23,23,21,21,20,21,19,18,19,17,17,16,16,13,12,9,7,6,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,1,2,1,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,2,2,2,3,2,2,3,3,3,3,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,3,4,4,4,4,5,5,5,5,6,7,9,9,9,12,12,13,11,13,14,15,14,16,17,17,18,17,20,21,20,22,23,23,23,24,22,21,22,21,21,22,21,23,22,22,22,25,23,26,24,25,25,26,26,26,26,25,25,26,25,26,26,26,26,26,26,26,26,26,25,25,25,25,25,25,26,25,25,26,24,24,24,24,23,22,21,19,19,17,16,15,14,11,10,8,7,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,6,7,8,8,7,8,8,8,8,9,8,8,7,7,7,7,7,8,8,8,9,8,8,8,8,7,7,7,7,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,3,3,3,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,4,3,3,4,3,3,4,4,3,4,3,4,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,4,4,5,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,4,4,3,3,4,4,5,6,7,8,9,9,9,10,11,12,14,15,16,18,20,19,18,18,19,19,22,19,21,21,22,24,23,23,23,24,22,24,23,23,25,23,22,24,22,23,23,23,24,23,23,21,23,23,23,21,23,22],[29,28,28,29,28,29,28,27,28,27,27,27,26,26,26,26,25,26,26,26,26,26,26,26,26,26,26,26,27,25,25,26,26,27,25,26,26,26,26,26,27,26,25,26,25,25,24,23,24,23,22,21,22,20,19,20,19,18,18,18,14,13,10,8,6,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,1,2,2,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,2,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,2,2,2,3,3,3,3,3,2,3,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,1,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,3,4,4,4,4,4,4,5,4,4,4,3,4,4,4,4,5,5,5,6,6,7,9,10,10,12,13,14,13,15,16,17,15,17,18,19,19,19,21,23,21,23,24,24,24,25,23,23,25,22,23,24,23,24,24,24,24,26,26,27,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,26,26,26,26,27,26,27,26,25,26,25,24,24,23,22,21,20,19,18,17,15,12,11,9,7,6,5,5,5,5,5,4,5,5,5,5,5,6,6,6,6,7,6,6,7,7,7,8,8,8,8,8,7,8,7,7,7,6,7,8,8,8,8,8,8,7,7,7,7,7,6,6,6,6,5,5,5,5,5,4,4,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,2,2,3,3,2,2,3,2,2,3,3,2,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,4,3,4,4,3,3,4,3,3,4,4,3,4,3,4,4,3,3,4,3,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,4,5,5,4,5,5,4,4,5,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,5,5,6,7,8,10,10,9,11,12,14,16,16,17,19,19,19,18,19,20,19,22,20,22,22,22,25,24,25,23,25,23,24,24,24,25,23,23,24,23,23,24,24,23,24,23,22,24,24,23,22,23,24],[28,28,28,29,28,29,28,28,28,28,27,28,27,26,26,26,26,26,27,26,26,26,26,26,26,27,26,26,28,25,26,26,26,27,27,27,26,27,27,27,27,27,25,26,25,25,24,23,23,23,22,20,22,20,19,19,19,18,17,17,14,12,10,7,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,1,2,2,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,2,3,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,2,2,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,3,3,4,4,3,3,3,3,4,3,3,4,4,5,5,6,6,9,9,10,12,12,14,12,14,16,16,15,16,18,18,18,19,21,21,21,22,23,24,23,24,23,23,24,22,21,22,23,23,23,22,23,24,24,26,24,25,25,25,26,25,25,25,25,25,25,25,25,26,26,26,26,27,27,26,26,26,25,26,26,25,26,26,25,26,23,24,24,23,23,22,20,19,19,18,16,15,14,12,10,8,7,6,5,4,4,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,8,7,8,8,7,7,7,7,6,7,7,7,7,8,7,7,7,7,6,6,6,6,5,6,5,5,5,5,4,4,4,4,3,3,3,4,3,3,3,4,4,3,4,4,4,4,5,5,5,6,5,5,5,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,2,2,2,2,2,2,3,3,2,2,2,3,3,2,2,3,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,8,10,10,9,11,12,13,16,17,17,19,20,18,17,19,20,19,22,19,23,22,21,26,23,23,23,24,22,24,24,23,24,23,23,23,21,22,25,23,23,24,23,22,23,24,22,21,22,23],[28,28,28,29,28,29,28,27,29,28,27,28,27,27,27,27,26,27,27,27,27,28,27,27,27,27,26,27,28,26,26,27,27,27,26,27,27,28,28,27,27,27,26,26,26,25,24,23,24,22,23,22,22,21,20,21,19,19,17,17,14,12,10,7,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,2,2,2,2,2,2,2,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,3,3,2,2,3,2,2,3,3,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,5,5,5,7,9,9,10,12,13,14,13,14,15,15,15,17,18,18,19,19,21,22,21,23,24,24,23,23,22,21,23,22,20,22,22,23,22,22,22,24,24,26,23,25,24,25,26,25,24,24,24,24,25,26,25,25,26,26,26,26,26,26,26,26,26,26,26,25,26,25,26,26,24,24,24,24,22,21,20,19,18,17,16,15,14,12,10,9,7,6,5,5,5,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,9,8,8,7,7,7,7,7,7,8,8,9,8,8,7,8,7,6,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,3,4,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,8,10,10,9,10,12,13,15,17,17,18,20,20,18,18,20,20,22,21,23,21,22,23,25,24,24,25,23,24,23,24,25,22,23,25,22,22,24,24,24,24,24,23,24,24,23,21,24,25],[28,28,28,28,28,29,28,27,28,27,26,27,26,26,26,27,25,26,27,26,26,27,26,25,26,26,26,26,26,25,25,26,26,26,25,26,26,26,26,26,26,25,25,25,25,24,23,22,22,21,21,21,21,19,19,19,18,18,17,17,13,12,10,7,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,2,2,1,1,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,3,2,3,3,2,2,3,3,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,3,3,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,2,2,3,2,2,3,3,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,3,3,4,4,3,3,3,3,4,3,3,4,4,5,5,5,7,9,9,10,12,13,14,12,14,15,16,15,16,17,18,19,18,20,21,20,21,22,23,23,23,21,21,22,22,21,22,22,22,22,23,22,23,24,26,24,24,25,25,26,25,25,25,26,26,25,25,25,25,25,26,26,27,26,26,26,26,24,25,25,25,25,25,25,25,24,24,23,24,23,21,19,18,18,16,16,15,14,11,10,8,7,6,5,5,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,7,8,7,8,8,7,7,7,6,6,6,6,7,7,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,3,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,5,4,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,3,2,2,2,2,2,3,3,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,4,4,5,4,5,5,5,5,4,5,4,5,5,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,8,9,9,9,10,12,13,15,16,16,18,20,18,17,18,19,19,22,20,22,22,21,25,23,24,23,25,22,24,23,23,25,22,23,24,23,22,23,24,23,23,23,22,23,23,23,21,24,24],[28,28,28,29,28,28,28,28,28,27,27,28,26,26,26,26,26,26,26,26,26,27,26,26,27,27,26,27,27,25,25,26,26,27,26,26,25,26,26,26,26,26,25,25,25,25,23,22,23,22,21,21,21,20,18,20,19,18,17,17,14,12,9,7,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,2,2,2,2,2,1,1,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,3,3,3,2,3,2,2,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,3,3,3,3,2,2,2,1,1,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,3,3,4,4,3,3,3,3,4,3,3,4,4,5,5,6,7,8,9,10,12,13,14,13,14,15,16,15,16,17,18,19,18,20,22,21,22,22,23,24,24,22,22,23,22,22,22,22,23,22,23,23,24,24,25,23,24,25,25,25,24,25,25,25,25,25,25,25,25,25,25,25,27,25,26,26,26,25,25,26,25,25,26,25,26,23,25,24,24,24,21,20,19,18,17,16,15,14,11,10,8,7,6,5,4,4,5,4,4,5,4,5,5,5,5,6,6,6,6,6,6,6,7,7,8,8,7,8,8,7,7,7,7,7,6,7,7,7,8,8,7,7,7,7,6,6,6,6,5,6,5,5,5,5,4,4,4,3,3,3,3,4,3,3,3,4,4,3,4,4,4,4,5,5,5,6,6,5,5,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,5,4,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,2,2,2,2,2,2,3,3,2,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,8,9,10,9,10,12,13,15,16,17,18,20,18,16,18,19,19,21,20,22,22,21,25,23,23,22,23,22,24,24,23,24,23,23,22,23,22,23,22,23,23,22,21,22,24,22,21,23,22],[28,28,28,29,28,29,28,28,28,28,27,27,27,26,26,26,26,27,27,27,26,27,27,26,27,27,27,27,28,26,26,27,27,28,27,27,26,28,27,27,27,27,26,27,26,25,25,23,24,23,22,21,22,21,19,20,20,18,17,17,14,12,9,7,6,5,4,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,1,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,3,3,2,2,3,2,2,2,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,3,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,4,4,5,5,6,9,9,10,12,12,14,13,13,16,16,15,16,17,18,18,18,21,22,21,22,23,24,23,24,23,21,23,21,21,22,23,23,22,22,23,23,24,26,24,25,25,25,26,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,25,26,25,26,26,25,26,25,25,26,24,24,24,23,23,22,20,20,19,17,17,15,13,11,9,8,6,6,5,4,4,4,4,3,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,7,6,6,6,6,6,7,6,7,7,6,7,6,7,6,5,6,5,5,5,5,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,4,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,7,9,8,8,9,12,12,14,15,16,19,20,18,16,18,19,18,21,18,22,21,21,25,23,23,22,24,22,24,23,23,24,22,23,23,20,21,24,24,22,24,22,21,24,24,21,20,23,23],[28,27,28,28,27,28,28,27,28,27,27,26,26,25,25,26,25,26,26,26,26,26,26,26,26,26,26,27,27,25,25,26,26,27,26,27,27,26,26,26,27,26,25,25,25,25,23,22,22,22,21,20,21,19,19,19,18,18,17,17,14,12,10,7,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,2,2,3,2,2,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,3,3,3,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,3,3,4,4,3,3,3,4,4,3,3,4,4,5,5,6,7,9,10,10,13,14,14,13,14,16,15,15,16,17,17,18,18,21,21,20,22,22,23,23,23,23,21,22,20,21,22,22,23,22,22,22,24,24,25,24,25,25,25,25,25,24,24,25,24,25,24,25,25,25,25,25,27,25,26,25,25,25,25,26,25,26,25,25,26,24,23,23,24,21,21,19,17,17,15,15,14,13,11,10,8,7,6,5,4,4,5,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,7,7,8,8,7,8,8,7,7,7,6,6,6,6,7,7,8,7,7,8,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,2,2,2,2,2,2,2,3,2,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,3,3,3,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,4,5,4,5,5,5,5,5,5,4,5,5,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,8,9,9,9,10,11,12,14,16,16,17,19,18,17,17,18,19,21,19,21,20,21,24,22,22,22,23,22,22,22,22,24,21,22,23,21,22,23,22,22,22,23,21,22,23,22,20,22,23],[28,27,28,28,27,28,27,27,28,27,26,26,26,26,25,26,24,26,25,25,26,26,25,26,26,26,25,26,26,24,25,25,25,26,25,25,25,26,26,25,25,25,25,25,24,24,23,22,22,21,21,21,21,19,18,19,18,18,17,16,13,12,10,7,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,3,3,2,2,2,2,1,1,2,1,1,1,1,1,1,1,2,1,2,2,2,2,3,3,3,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,4,3,3,4,4,5,5,6,7,9,10,10,12,13,14,13,15,15,16,15,16,17,17,17,18,20,21,19,21,21,22,23,22,21,20,21,21,21,22,21,23,22,22,21,24,24,25,22,24,25,24,24,24,24,24,25,25,25,25,25,25,24,25,24,25,24,25,25,25,24,24,24,24,24,24,24,25,23,23,23,23,23,20,19,18,17,16,15,14,13,10,9,8,6,6,5,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,7,8,8,8,8,7,7,6,6,6,6,6,7,7,8,8,7,7,7,7,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,3,3,3,4,3,3,4,4,3,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,5,4,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,7,9,9,9,10,12,13,15,16,16,19,20,17,17,18,18,18,21,19,21,21,21,25,23,24,22,24,22,23,24,24,25,22,23,24,23,22,24,23,23,23,22,22,23,24,23,21,23,23],[28,27,28,28,27,28,28,27,28,27,26,27,26,26,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,25,25,26,26,27,26,26,25,26,26,26,26,26,25,25,25,25,24,22,23,22,22,21,22,20,19,21,20,19,18,18,16,13,10,8,6,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,3,3,2,2,2,2,2,2,2,2,1,1,2,1,1,2,1,1,2,2,2,3,3,3,3,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,4,3,3,3,3,3,3,3,3,4,4,5,5,6,7,10,10,11,13,14,15,14,15,17,17,16,18,19,20,19,20,22,22,22,22,23,23,23,24,22,21,23,21,22,22,22,23,22,22,23,23,24,26,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,25,26,25,25,25,25,25,24,26,25,24,25,23,23,23,23,23,21,20,19,18,17,16,15,13,11,10,8,7,6,5,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,7,7,8,7,7,7,7,6,6,7,7,7,8,7,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,5,5,5,6,5,5,5,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,3,3,4,3,3,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,8,9,9,10,10,12,12,14,15,15,18,19,17,16,17,19,18,21,19,20,20,20,24,22,22,21,23,21,23,22,22,23,21,22,23,20,21,22,23,21,23,22,20,22,23,20,20,22,22],[27,27,28,28,28,28,28,28,28,27,27,26,27,26,27,26,27,27,26,27,27,27,27,27,27,27,28,27,28,27,26,27,28,28,27,28,27,28,28,28,28,27,26,27,26,26,24,24,25,23,22,21,22,20,20,21,20,19,18,20,16,14,11,8,8,6,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,3,4,4,4,4,4,4,5,4,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,3,3,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,4,4,5,4,4,4,4,4,4,4,4,5,5,5,6,7,8,12,12,12,14,15,16,15,16,18,18,18,20,21,20,21,21,23,23,23,24,25,25,24,24,24,23,24,22,23,23,24,25,23,24,24,25,26,26,25,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,26,26,26,26,27,26,26,26,25,24,24,24,24,23,19,20,20,17,16,15,14,12,11,9,8,7,6,5,5,5,5,5,5,5,6,6,6,7,7,6,7,8,7,7,8,8,8,9,9,9,9,9,9,9,8,8,7,8,8,8,8,9,9,9,9,8,9,8,7,7,7,7,7,6,6,6,6,5,5,5,5,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,6,6,7,7,7,6,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,6,6,5,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,4,3,3,3,3,3,3,4,4,3,4,3,4,4,3,3,4,4,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,2,3,3,3,3,4,4,4,5,5,5,4,4,5,5,5,4,4,4,4,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,4,5,4,4,5,5,4,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,4,4,3,4,4,4,4,5,5,4,5,5,5,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,5,5,5,4,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,5,6,7,8,9,11,10,10,11,13,13,15,16,18,20,21,19,17,19,20,19,22,19,21,21,22,24,24,25,24,24,24,25,23,24,25,23,23,25,23,23,24,24,23,24,24,22,24,25,22,20,24,24],[28,28,28,28,28,28,28,28,28,27,26,26,27,26,26,27,26,27,27,27,27,27,27,27,27,27,27,28,27,26,26,27,27,28,27,28,27,27,28,27,27,27,26,26,26,26,25,23,24,23,23,22,23,21,20,21,20,20,18,19,16,14,11,9,8,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,2,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,4,4,4,4,5,4,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,2,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,4,5,5,4,4,4,5,5,4,4,5,5,6,7,8,9,12,13,12,14,15,17,15,16,18,17,17,19,20,18,20,20,22,22,22,23,24,25,24,25,24,23,24,22,22,22,23,24,23,24,24,25,25,28,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,26,26,26,25,26,26,26,26,26,26,27,24,25,24,25,23,23,21,19,20,17,16,16,14,12,10,10,8,7,6,6,5,6,6,6,5,5,6,6,6,7,6,6,7,8,7,7,8,9,8,9,10,10,9,10,9,9,8,8,7,8,8,8,9,10,10,9,9,8,8,8,7,7,7,7,7,7,6,6,6,6,5,5,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,7,6,7,7,6,6,5,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,4,4,5,5,6,6,5,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,3,2,3,3,3,3,4,4,4,4,5,5,4,4,5,5,5,4,4,4,4,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,4,4,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,6,6,8,8,10,10,10,11,11,13,14,16,17,17,20,20,19,18,19,19,20,22,20,21,21,22,24,24,24,23,24,23,25,24,23,26,22,24,25,23,22,24,23,24,24,23,22,23,25,23,21,24,26],[29,28,28,29,28,29,28,28,29,27,27,27,27,26,26,27,26,27,27,27,27,27,27,27,28,27,27,27,27,26,27,27,27,28,27,27,27,27,28,27,27,27,26,26,27,26,25,24,24,24,23,22,23,22,21,22,20,21,19,19,16,15,12,9,8,7,6,5,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,3,3,3,3,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,2,2,3,3,2,3,3,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,3,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,5,5,5,5,5,6,7,8,9,10,12,13,13,15,16,17,16,18,20,19,18,19,20,20,20,22,23,23,22,24,24,25,25,25,23,23,23,23,23,23,24,24,24,25,24,25,26,27,25,26,26,26,26,27,26,26,27,26,26,26,26,27,26,27,26,27,26,27,26,26,25,26,26,26,26,26,26,27,24,24,23,24,23,21,22,19,19,18,16,17,15,13,12,10,8,8,7,6,6,6,7,6,6,6,7,7,7,8,8,7,8,9,8,8,9,10,10,10,10,10,10,11,10,10,9,9,9,9,9,9,10,11,10,10,10,10,10,8,8,8,8,8,8,7,7,7,6,6,6,6,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,7,8,7,7,7,6,5,5,4,4,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,6,6,7,7,6,5,5,4,4,4,4,3,3,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,5,5,5,4,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,3,3,3,4,4,4,5,5,5,5,6,5,5,6,6,6,5,5,5,4,4,3,3,3,3,4,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,6,6,6,5,5,6,5,5,5,5,5,5,4,4,4,4,5,5,4,5,5,5,5,5,6,5,5,6,6,7,7,6,7,8,7,7,7,7,7,6,6,6,7,6,6,6,7,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,8,8,10,11,11,12,12,14,14,17,17,18,20,21,20,18,19,20,20,23,20,22,22,21,24,24,24,24,25,24,25,25,24,26,24,24,25,23,23,24,25,23,25,23,23,24,25,24,22,25,24],[28,29,28,29,29,29,29,29,29,28,28,28,28,27,28,27,28,28,28,29,28,28,28,28,28,28,28,28,29,28,27,28,29,29,28,29,28,28,29,28,29,28,28,28,27,27,26,25,26,26,23,23,25,22,23,24,22,22,21,22,19,16,14,12,10,8,7,6,5,5,4,4,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,4,5,5,4,4,5,4,4,5,5,5,4,5,5,5,5,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,3,4,4,4,4,4,4,4,4,5,6,5,5,5,5,5,4,4,4,4,4,4,3,3,4,3,4,3,3,4,4,5,5,5,5,5,4,4,4,4,4,3,3,3,2,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,6,6,7,6,7,7,7,7,7,8,7,9,8,7,6,6,6,6,5,5,4,5,5,4,3,4,4,3,2,3,3,1,1,3,2,1,0,1,1,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,5,6,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,3,4,5,5,5,5,6,6,6,6,7,7,7,6,6,7,6,5,5,5,6,6,6,6,6,7,8,9,10,12,14,14,16,16,18,18,19,19,22,22,21,23,24,22,23,24,25,24,25,26,26,27,26,26,27,26,26,22,24,26,26,25,25,26,26,27,27,27,27,27,28,28,27,28,28,28,28,29,28,28,29,28,29,28,28,28,29,28,28,28,27,28,28,28,28,27,27,27,26,26,26,25,25,24,23,22,22,20,18,18,15,14,13,11,10,10,7,6,7,7,8,7,8,9,9,9,9,10,10,10,10,11,10,11,12,12,12,12,13,13,13,13,11,12,11,10,11,11,11,12,11,13,13,11,12,12,12,11,10,10,10,10,9,10,9,8,8,7,8,6,7,6,6,6,8,7,7,8,8,7,8,8,9,8,8,9,10,9,10,10,9,9,8,8,7,6,5,5,4,4,4,5,5,5,6,5,6,6,5,5,5,5,6,6,5,5,6,5,5,5,6,6,5,7,6,6,6,6,7,7,8,8,8,9,9,8,7,6,6,6,6,5,5,6,6,6,7,8,7,8,8,9,8,8,7,7,6,6,6,6,5,6,6,5,5,5,5,5,5,5,4,4,4,4,3,4,5,4,3,4,5,4,4,5,5,5,5,5,6,7,5,5,6,6,5,5,7,6,5,7,7,7,6,6,7,7,6,6,7,6,6,6,7,7,7,6,7,7,6,5,6,6,6,5,6,6,5,5,6,5,4,4,5,5,5,5,5,6,6,6,7,7,8,8,9,7,7,8,7,7,6,6,6,6,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,6,5,5,6,7,6,7,8,8,8,8,8,8,8,8,8,8,8,7,8,8,8,7,7,7,8,7,7,7,6,6,5,5,5,5,6,5,5,6,7,6,7,8,7,7,8,8,8,8,8,9,10,9,9,9,9,9,8,8,8,8,8,8,8,8,9,7,6,7,6,7,9,9,8,9,9,9,9,9,9,9,9,10,11,9,9,8,11,10,9,9,8,9,8,8,8,8,8,8,8,8,7,8,7,7,7,7,6,6,7,8,9,10,10,12,13,14,14,13,16,16,18,19,19,22,23,21,19,22,23,21,24,22,23,24,25,26,26,27,24,26,25,26,26,25,27,25,26,27,23,24,26,26,24,26,24,24,25,26,24,23,25,26],[28,28,28,28,28,28,28,29,28,28,28,27,28,27,27,27,28,28,28,29,28,28,29,29,28,28,29,28,28,28,27,28,28,29,28,28,28,28,29,28,29,28,28,28,28,27,25,26,26,25,24,24,25,23,24,24,23,22,22,22,20,18,16,14,13,10,9,8,7,5,5,4,4,4,4,4,4,3,4,5,4,4,5,4,4,5,6,6,7,6,6,7,6,5,6,7,6,6,7,7,6,7,7,7,7,7,7,7,7,7,8,7,6,6,6,7,6,6,6,6,7,6,6,7,6,6,7,7,6,6,6,7,6,6,7,7,7,7,6,6,7,7,6,6,5,5,6,6,5,6,5,5,4,5,5,5,6,6,5,6,6,5,4,4,4,4,4,4,5,3,4,4,3,4,4,4,4,4,5,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,8,8,8,8,9,8,8,9,10,9,10,9,8,8,7,7,7,7,6,6,5,5,5,5,4,5,4,3,3,3,3,2,2,2,2,1,0,1,2,3,4,2,4,4,4,3,3,4,4,3,3,4,3,3,4,4,4,4,5,6,5,6,6,6,5,5,4,4,4,4,4,5,5,6,6,6,6,6,7,7,7,6,7,6,6,6,5,5,6,4,5,5,4,4,4,3,3,3,3,3,2,3,4,4,4,4,4,4,4,5,5,5,6,6,7,7,8,8,8,8,8,9,9,8,8,9,8,7,7,6,7,8,7,7,8,8,10,10,11,13,15,15,16,18,19,19,19,20,21,21,21,22,23,23,24,25,25,26,27,27,28,27,26,27,26,24,26,24,24,26,25,26,24,26,26,28,27,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,26,27,27,27,26,26,25,25,23,22,19,21,18,17,18,15,15,14,13,12,12,9,8,9,9,10,9,10,10,11,10,11,12,12,11,12,13,12,12,13,13,14,14,14,15,14,14,13,13,12,12,12,13,13,14,13,14,15,13,14,14,13,12,11,12,11,12,11,11,10,10,11,10,10,9,10,8,8,8,10,10,8,9,10,11,9,11,11,10,10,11,11,11,11,11,11,11,10,9,9,8,7,6,6,5,5,6,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,6,6,7,6,7,7,7,7,7,7,7,8,8,9,10,10,10,10,8,8,7,7,8,8,6,7,7,8,8,8,9,8,9,9,10,9,9,9,9,8,8,8,7,6,8,7,6,6,6,6,6,5,6,5,5,5,6,4,4,5,5,4,6,6,6,6,6,7,7,7,7,8,7,7,6,8,7,7,7,8,7,7,8,7,8,8,8,8,8,7,8,8,7,7,8,8,8,8,8,9,8,7,7,7,7,7,6,6,6,6,6,6,6,4,5,6,6,6,5,6,7,8,8,8,9,9,9,10,9,8,9,9,8,7,8,7,7,7,6,5,5,6,6,5,6,6,6,6,6,7,6,7,7,7,7,8,8,8,9,9,9,9,9,10,10,8,9,9,10,9,9,10,10,9,8,8,9,8,8,8,8,7,8,7,7,6,7,8,7,7,8,8,8,8,9,9,10,9,10,10,10,9,10,11,10,11,10,10,10,10,10,10,9,10,10,9,9,10,9,8,8,9,9,11,10,10,10,10,11,10,11,10,10,11,12,11,10,11,10,12,10,10,10,10,10,10,9,10,9,9,10,9,9,8,9,9,8,8,9,9,7,8,10,10,12,12,14,15,15,15,16,17,18,20,20,21,23,24,24,21,23,23,22,25,23,25,25,25,26,26,27,26,28,26,28,27,27,27,26,27,28,25,26,27,27,26,26,25,25,26,27,25,24,26,26],[29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,28,28,28,28,29,29,28,28,29,28,28,29,28,29,28,28,29,29,29,28,29,28,28,29,29,29,28,28,28,27,27,26,26,26,25,24,24,24,23,23,24,23,22,21,22,20,18,16,14,13,12,10,9,9,7,8,7,6,5,4,5,5,5,5,5,4,4,6,5,5,8,7,8,8,9,9,8,9,8,9,8,9,9,8,9,9,9,9,10,10,9,9,10,9,10,10,9,9,9,9,9,9,8,6,8,9,7,8,9,10,8,9,9,10,9,9,9,9,8,9,10,9,9,9,9,9,9,8,10,9,9,10,10,9,9,8,6,6,6,8,8,10,10,7,8,7,7,5,6,5,5,4,5,5,4,4,5,5,4,5,5,7,5,7,6,7,5,7,8,7,7,8,9,8,8,8,8,7,8,8,10,10,10,9,11,10,10,11,12,11,12,11,9,9,8,9,8,8,8,8,7,7,8,8,7,6,7,7,5,5,4,4,3,3,2,2,1,0,1,3,4,2,4,5,5,4,3,6,5,3,5,6,5,4,6,6,6,6,7,8,7,8,8,8,7,6,6,6,7,7,6,7,7,7,7,7,7,8,7,8,9,9,8,8,8,7,7,6,6,5,7,6,5,5,6,5,4,5,5,4,3,5,5,4,5,5,6,5,5,6,7,6,7,8,8,8,9,9,9,10,11,11,10,10,10,11,10,9,8,7,10,10,9,10,11,10,11,12,13,14,16,16,17,19,19,20,20,21,23,22,22,24,24,23,24,25,26,26,25,27,27,28,26,27,26,26,27,25,25,26,26,27,26,26,27,28,28,29,27,29,28,28,28,29,28,28,28,28,28,28,28,28,28,27,27,28,28,28,28,28,27,27,28,27,28,27,27,27,26,26,26,25,25,24,23,22,23,21,17,21,17,17,16,15,13,13,12,11,11,10,11,11,11,11,12,11,13,13,12,13,14,14,13,14,14,16,15,15,16,16,16,16,14,14,13,14,13,14,15,14,15,16,16,14,16,16,15,14,13,13,13,13,13,12,12,12,13,11,11,11,11,10,9,9,10,11,10,10,11,12,10,11,11,11,11,12,12,12,12,12,12,12,10,10,10,9,8,8,7,7,7,7,7,7,7,8,8,8,8,8,7,8,8,7,8,8,8,7,8,8,7,9,8,8,9,9,8,9,10,9,10,12,12,12,11,10,9,9,9,9,8,8,9,9,10,10,10,11,10,12,11,12,11,10,10,10,10,9,9,11,8,8,8,8,8,7,7,7,7,7,6,5,7,7,5,6,7,7,5,7,7,7,6,7,7,7,8,9,10,9,8,8,9,8,8,9,8,8,8,9,9,8,8,9,9,9,8,9,9,9,9,9,9,10,9,10,10,9,9,9,10,8,9,8,9,9,9,9,8,7,6,7,8,8,9,9,9,8,9,10,10,11,11,11,11,11,10,10,11,11,9,9,9,8,8,7,7,6,7,8,6,7,8,8,7,7,8,8,8,9,9,8,9,9,9,11,10,10,10,10,11,11,10,11,10,11,10,9,10,11,10,10,10,10,10,10,10,9,9,9,9,9,9,8,9,9,9,9,10,10,9,10,11,10,11,11,11,11,10,11,13,12,13,11,11,12,11,11,11,11,11,11,11,11,11,11,10,10,12,10,12,12,12,12,12,13,11,12,12,12,13,13,14,12,12,11,13,12,11,11,11,11,11,10,11,10,10,10,9,10,9,10,11,9,9,10,10,9,9,11,12,14,13,15,16,15,16,16,18,18,19,20,20,24,25,23,22,24,24,23,26,23,24,26,25,27,27,27,27,27,26,28,28,27,28,26,27,28,26,27,27,27,27,28,26,26,27,28,26,25,27,27],[29,29,29,29,29,29,29,29,29,28,28,28,29,27,28,28,28,29,28,29,29,29,29,29,29,29,29,29,29,29,27,29,29,30,28,29,28,28,29,28,29,28,28,28,28,28,26,26,27,25,25,25,25,24,23,25,23,22,22,23,21,19,18,16,14,14,13,11,11,9,9,8,7,7,5,6,5,4,6,7,6,6,8,8,7,8,10,11,10,10,10,11,11,9,11,11,11,9,11,11,11,11,11,12,11,12,11,11,11,11,12,11,10,9,9,9,9,9,9,9,9,8,8,10,10,9,11,10,11,11,11,11,11,10,11,11,12,11,11,11,11,11,11,11,11,12,10,9,9,8,8,8,8,7,8,8,9,8,8,9,8,7,6,7,7,6,6,6,8,5,7,7,7,5,7,7,7,7,8,8,8,7,8,9,9,9,9,10,9,10,10,10,10,10,11,12,13,12,12,13,12,12,13,14,13,14,13,11,12,11,11,11,10,11,10,10,11,9,9,8,9,8,8,6,6,5,5,4,5,4,3,2,1,0,1,5,3,5,6,6,5,4,5,5,4,5,6,4,4,6,6,5,6,8,8,9,9,8,8,8,8,7,7,9,8,9,9,9,10,9,10,10,11,11,11,12,11,10,11,11,10,11,9,9,7,9,8,6,6,7,7,5,5,6,5,4,5,6,6,7,8,8,7,7,9,8,7,10,10,10,10,13,12,11,12,12,13,13,13,13,13,13,11,10,8,11,13,11,10,13,13,13,13,13,14,18,19,18,18,20,21,21,21,23,22,21,24,24,23,25,25,26,26,26,27,27,27,27,28,26,25,25,24,25,26,25,26,25,26,27,28,28,28,27,28,27,28,28,28,28,27,28,28,28,28,28,28,28,28,27,28,28,27,28,27,27,28,27,26,28,26,26,27,26,26,27,26,25,23,23,21,22,19,18,20,17,18,17,16,15,14,13,13,13,14,13,13,13,14,15,13,15,15,17,15,16,17,16,15,16,18,17,19,19,20,19,19,17,18,16,15,16,16,17,17,16,18,20,17,19,18,16,15,15,16,15,15,15,15,14,14,16,14,13,13,13,11,11,11,13,13,12,13,13,13,13,14,14,13,14,15,15,15,16,14,15,15,13,12,11,10,10,9,8,7,8,9,9,8,9,9,10,10,11,11,9,11,10,10,10,10,11,10,9,10,11,11,10,11,11,11,10,12,12,10,12,12,13,13,12,11,11,11,11,11,11,12,11,11,12,12,12,13,13,13,13,14,13,12,12,13,12,11,12,12,11,11,11,10,11,10,10,9,10,10,8,7,9,9,6,7,9,9,6,8,10,10,8,9,10,10,9,11,11,11,11,10,11,11,10,11,12,11,11,12,13,11,12,12,12,12,10,11,11,12,11,12,11,12,13,11,12,12,11,11,11,11,11,10,10,10,10,10,10,8,7,8,9,10,8,9,9,10,12,11,11,13,13,12,13,11,12,12,12,12,10,10,11,10,11,10,8,8,10,11,7,9,10,11,9,10,11,11,10,10,11,11,11,12,13,12,12,14,13,13,13,14,13,13,14,14,13,13,12,13,13,12,12,12,12,11,12,12,11,12,12,12,12,11,12,11,10,11,12,12,12,12,14,13,14,13,14,13,13,13,15,14,14,14,14,13,13,14,14,12,13,14,13,13,13,13,13,12,14,13,14,14,13,14,14,14,13,14,14,13,14,14,16,13,15,14,15,15,13,14,14,14,13,14,14,13,13,14,13,12,13,14,12,12,12,12,12,11,11,12,13,15,14,16,17,18,18,19,20,22,22,24,22,26,26,25,25,26,25,25,26,26,25,27,26,28,28,28,27,28,27,28,28,28,28,28,28,28,27,27,28,28,28,28,27,26,28,28,27,26,28,27],[29,29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,30,29,29,29,29,29,29,29,28,28,29,28,28,27,27,27,26,26,26,26,25,26,26,24,25,23,24,21,20,18,18,16,15,14,11,11,11,9,9,8,9,7,7,6,6,8,8,7,8,9,9,9,11,11,11,12,12,12,12,13,12,13,12,13,13,13,13,13,14,14,14,13,14,13,14,13,13,13,13,14,13,10,13,13,10,9,11,13,11,12,13,13,13,13,13,14,13,13,13,15,13,13,15,14,14,14,14,13,13,13,15,13,14,14,12,12,13,12,9,10,10,11,11,14,14,9,11,10,10,9,9,10,7,7,9,8,6,7,9,7,7,9,10,9,8,12,13,12,11,11,12,11,12,12,13,13,12,13,13,13,14,13,15,15,13,15,15,16,15,16,17,17,17,16,15,14,13,13,13,12,14,12,12,12,13,12,11,12,12,11,10,8,7,8,5,7,5,5,3,2,1,0,2,2,4,5,6,4,4,7,6,5,7,9,8,8,10,11,9,11,10,12,10,11,11,12,11,12,10,11,11,11,11,12,12,13,12,13,13,13,13,14,14,14,13,14,13,13,12,10,11,11,11,10,9,9,9,10,7,9,10,7,7,9,9,9,9,9,9,9,9,10,11,11,12,13,13,13,15,14,14,14,15,15,16,14,14,15,15,11,12,9,11,13,12,12,13,14,14,15,15,18,20,20,19,22,23,23,21,24,26,24,23,26,27,24,26,26,28,27,27,28,28,28,28,29,28,27,28,26,27,27,27,27,26,28,28,29,29,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,28,28,29,29,29,29,29,29,28,29,28,29,28,27,28,26,27,26,26,25,24,24,22,23,21,19,22,17,18,19,16,17,16,15,14,16,15,15,15,14,15,16,15,16,17,18,17,18,19,19,19,18,20,21,21,21,21,22,22,19,19,18,18,18,18,18,19,18,21,22,19,22,21,18,18,19,19,17,18,19,16,16,17,17,16,15,14,15,13,13,13,14,14,16,15,17,16,16,18,17,16,17,18,17,17,16,16,15,16,16,14,15,13,12,13,11,11,11,12,12,11,12,13,13,13,12,13,12,12,12,12,13,12,13,12,12,12,12,12,11,13,13,12,12,13,13,12,16,14,16,16,15,13,13,13,12,13,12,12,11,14,13,15,16,16,14,17,16,17,15,15,15,15,13,13,14,14,12,13,12,11,12,12,11,11,11,11,10,10,12,11,10,10,11,10,10,11,11,10,11,12,12,11,12,13,13,13,13,12,12,13,13,12,14,13,12,13,14,13,13,12,13,13,12,12,13,13,13,13,13,13,15,12,14,14,12,11,13,12,13,12,11,12,12,12,12,11,10,9,10,12,12,11,12,13,13,14,14,14,15,15,16,13,13,14,14,13,12,11,12,11,11,10,9,9,10,11,9,10,12,11,10,12,13,11,12,12,13,13,12,13,14,15,13,15,14,14,15,16,15,14,16,17,16,17,13,16,16,13,13,15,14,13,14,14,13,15,11,12,12,12,14,12,14,12,14,14,13,14,15,14,15,16,15,15,15,16,18,17,17,16,17,17,15,16,16,15,16,16,15,15,16,15,14,14,15,15,14,15,16,16,16,17,15,17,16,17,17,18,20,17,18,16,18,16,15,16,17,18,15,16,17,15,16,16,16,14,15,17,14,14,15,15,14,14,14,16,15,17,17,19,19,19,19,20,20,22,23,22,22,25,26,25,25,26,25,26,27,27,26,27,26,28,28,28,28,28,27,29,29,28,29,28,28,28,28,28,28,28,28,28,28,27,28,28,27,26,27,27],[29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,28,28,29,28,28,29,28,29,29,28,29,29,29,29,28,28,29,29,29,28,29,29,29,29,28,29,28,28,29,29,28,27,27,27,24,25,26,25,24,25,25,23,23,23,23,21,19,18,16,14,15,13,11,11,10,9,9,8,7,7,8,7,7,9,9,8,9,10,11,11,12,13,14,13,15,15,14,15,14,14,13,13,11,14,14,12,13,14,13,11,13,12,11,10,12,13,10,11,10,9,10,9,8,7,7,9,8,6,9,11,8,9,11,11,10,11,13,13,13,13,13,14,14,14,13,13,14,14,12,14,15,12,12,12,12,10,10,11,9,10,11,14,11,11,10,11,11,8,9,9,8,6,8,8,6,6,7,7,5,6,7,6,6,7,9,8,9,9,12,11,11,12,14,13,13,13,14,14,14,14,15,16,15,15,16,16,16,17,16,17,16,16,16,15,13,14,15,13,14,13,13,14,13,12,12,12,10,10,10,9,8,8,7,6,4,5,4,4,3,1,0,1,2,4,5,3,4,6,6,5,7,7,6,7,8,9,9,11,10,10,9,11,11,11,11,11,10,12,12,13,13,13,14,14,14,14,15,14,14,14,14,14,15,15,15,14,14,13,13,12,13,13,11,10,11,11,8,9,10,7,7,8,9,8,7,8,8,8,9,9,10,10,10,10,10,12,13,12,13,13,13,14,12,11,12,12,12,11,11,9,10,12,11,11,11,13,14,14,14,15,17,18,18,20,21,21,21,22,24,22,22,24,25,23,25,25,26,25,26,27,26,27,27,27,26,25,25,26,25,26,26,26,27,27,26,28,27,28,28,28,28,29,28,29,28,28,29,28,28,29,28,29,28,28,28,29,28,28,28,27,27,27,28,27,27,27,26,27,25,25,25,25,23,21,21,19,20,19,16,19,17,17,17,16,15,14,13,13,13,13,14,14,15,16,17,16,16,17,18,17,18,19,18,18,18,19,19,18,21,21,21,21,19,19,18,18,17,18,18,18,18,19,21,19,20,18,17,17,17,16,17,17,15,15,17,15,15,14,14,14,14,14,13,14,14,14,15,16,16,15,16,17,16,16,16,17,16,16,16,16,16,15,15,14,15,12,12,12,10,10,13,13,13,12,13,13,15,13,13,14,13,14,13,14,13,14,15,14,13,14,15,14,13,14,15,14,14,14,15,15,15,15,15,16,15,14,16,16,15,15,14,14,14,15,15,15,16,15,15,17,17,17,16,15,16,16,15,15,16,15,14,15,14,13,14,13,13,12,14,13,12,12,13,12,10,11,12,11,10,12,12,11,13,13,12,12,13,14,14,15,14,14,14,14,14,14,16,15,13,15,15,16,15,14,16,16,14,14,15,15,14,15,15,15,16,14,14,14,14,12,13,13,13,13,12,13,12,12,13,12,12,10,13,12,12,11,12,13,14,14,14,15,14,16,15,14,14,14,14,13,11,12,11,11,12,11,10,11,12,11,10,12,12,12,12,12,13,12,13,14,13,14,14,14,15,15,15,17,16,16,16,17,17,16,17,17,18,17,17,18,17,16,15,16,15,14,14,14,13,13,12,11,12,12,13,13,13,13,14,15,15,15,15,16,17,17,17,18,17,17,17,17,18,17,18,17,17,17,15,16,17,15,15,16,16,13,15,14,15,15,16,16,16,15,16,17,16,17,17,17,18,18,18,18,18,17,18,17,18,17,17,18,17,16,18,17,17,16,17,16,16,17,15,16,15,15,14,14,14,15,15,16,16,17,18,18,18,18,19,21,21,23,22,25,25,24,25,25,24,25,25,26,25,27,26,27,26,27,27,27,26,27,28,27,28,27,27,27,28,27,27,27,27,27,27,26,26,27,26,25,27,27],[29,30,29,29,29,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,30,29,29,29,29,29,29,29,29,28,29,29,28,28,27,27,26,26,26,26,25,25,25,24,24,22,22,21,19,17,14,13,12,11,9,10,9,7,8,6,6,5,6,5,5,6,6,5,6,7,7,7,8,10,10,9,11,10,9,11,8,9,9,9,8,8,9,9,9,8,9,8,9,8,8,8,9,9,8,8,6,7,7,6,6,6,5,6,6,5,7,7,6,6,7,8,6,8,9,9,8,9,9,9,10,9,9,10,9,8,9,9,10,8,6,7,8,6,5,6,6,6,7,9,7,6,7,7,6,5,5,5,5,4,5,5,3,4,5,5,4,4,5,5,4,5,5,5,5,6,7,7,7,8,10,9,9,9,11,11,10,11,11,11,11,11,11,12,12,12,11,12,11,12,11,11,11,10,10,11,10,9,10,10,9,9,8,8,6,7,6,6,6,5,6,4,4,5,3,3,2,2,1,0,1,2,2,2,3,4,4,3,5,5,5,5,6,7,6,7,7,7,7,8,8,8,8,7,7,7,8,9,8,10,10,11,10,10,10,11,10,11,11,11,11,10,10,11,12,9,9,8,10,9,7,7,8,6,6,6,6,6,7,5,6,6,7,6,7,7,7,8,8,7,9,9,9,8,10,11,10,10,12,12,11,11,11,11,11,10,11,8,9,11,11,9,9,10,11,12,12,13,16,17,17,20,20,21,21,22,24,22,21,23,24,25,25,26,27,27,26,28,27,28,28,28,27,26,26,26,25,27,26,27,26,27,27,28,28,29,29,29,28,29,29,29,29,28,29,28,28,28,28,28,28,28,28,29,28,28,28,28,27,28,28,28,28,27,28,28,26,26,26,26,26,24,24,21,22,20,18,20,17,17,16,15,14,13,11,11,11,12,11,13,13,13,14,13,14,14,14,13,14,16,14,14,14,16,16,16,17,18,17,17,16,16,15,15,15,16,15,16,15,16,17,16,16,15,14,15,15,13,13,14,13,13,14,13,13,12,12,13,12,11,11,11,12,11,12,12,12,12,12,12,11,12,12,12,13,13,13,13,13,13,12,11,11,10,9,8,7,7,7,9,8,8,10,10,11,11,9,10,10,10,10,10,11,9,10,10,11,9,10,11,10,10,11,11,9,10,11,11,11,12,12,12,12,11,11,11,11,10,11,10,11,11,10,11,11,10,11,11,11,12,11,10,11,11,10,10,11,10,11,10,9,9,11,9,10,9,10,10,8,8,9,9,8,8,9,8,8,9,9,8,8,10,10,9,9,10,11,10,11,12,10,10,12,10,11,10,10,11,11,11,11,10,10,11,10,10,11,10,10,10,10,12,12,10,10,11,10,10,9,10,9,9,9,10,8,8,9,8,7,7,8,8,8,7,8,9,9,10,9,10,10,11,11,11,11,11,11,11,10,9,9,9,10,9,8,8,9,9,8,9,9,9,9,9,9,10,10,9,10,11,10,11,11,12,12,11,11,11,12,11,11,12,11,11,12,11,11,12,11,12,11,11,12,11,10,11,10,10,10,9,9,10,10,10,11,11,11,11,11,11,11,12,12,12,12,12,12,11,13,12,13,13,13,12,12,12,12,12,12,11,11,12,12,11,11,11,12,11,12,12,12,13,11,13,12,12,13,12,13,13,14,12,12,12,12,12,13,12,12,12,12,11,12,12,12,11,11,12,11,12,12,11,11,11,11,11,11,12,12,14,14,16,15,16,17,17,17,19,20,22,21,25,25,24,23,24,24,24,25,25,24,26,25,26,27,27,27,27,27,28,27,27,29,27,28,28,28,27,28,28,28,28,27,26,27,28,26,25,27,26],[29,29,29,29,29,29,28,28,29,27,27,28,28,28,27,28,27,28,27,27,28,28,28,28,28,28,27,28,28,27,27,28,28,28,27,28,28,28,28,28,28,27,27,27,27,26,25,25,26,24,24,24,24,23,22,23,21,22,20,20,18,17,14,13,11,11,10,9,8,8,7,7,6,6,5,5,5,4,5,5,5,5,6,6,6,7,8,8,8,9,8,8,8,7,8,8,6,6,8,8,6,7,8,7,6,8,8,6,6,8,8,6,6,6,5,5,5,5,4,5,6,5,6,7,6,5,6,7,6,6,7,7,8,9,8,9,9,9,8,9,8,8,8,7,8,8,6,6,6,6,5,5,5,5,5,5,6,6,5,6,6,5,4,4,4,4,4,4,4,4,3,5,4,5,4,5,5,5,5,5,5,6,6,7,7,7,9,8,8,9,9,8,9,9,9,10,10,9,9,10,10,10,11,11,11,11,11,10,10,9,9,9,9,9,8,8,7,8,8,7,7,6,6,5,5,5,5,4,4,4,3,4,4,3,3,2,1,0,1,3,2,2,2,2,3,3,4,6,4,4,4,5,6,7,7,6,7,8,8,7,7,7,7,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,7,7,8,7,6,7,7,7,6,6,7,5,5,5,6,6,6,7,7,5,7,7,7,6,8,7,7,9,9,8,8,9,10,10,10,9,10,10,10,9,9,8,9,9,10,8,9,10,11,11,12,12,14,15,15,17,18,17,17,19,20,19,19,20,20,20,22,22,24,24,23,25,25,26,26,26,25,24,24,24,25,25,25,26,25,26,25,27,27,28,26,27,26,27,27,28,27,27,27,27,27,27,27,27,27,27,27,28,27,27,27,26,27,27,27,26,27,26,26,26,24,24,25,24,23,21,21,20,20,18,16,18,16,15,14,13,12,11,11,10,11,10,11,11,11,13,12,12,13,12,13,13,13,14,13,13,14,14,15,15,17,17,17,16,15,15,15,13,13,13,13,14,14,15,16,15,16,15,13,14,12,12,13,12,12,11,12,11,11,10,10,11,10,11,10,11,11,10,10,11,10,11,11,12,11,11,12,11,11,12,12,12,11,10,10,9,9,8,7,7,6,7,8,9,8,7,9,9,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,11,11,11,12,11,10,10,9,10,9,9,8,9,10,9,10,11,10,10,11,11,11,10,10,10,10,9,9,9,9,9,9,8,8,8,8,8,8,8,9,8,8,8,9,7,7,8,9,7,8,8,8,7,9,9,9,8,9,10,9,9,10,9,9,9,10,10,9,9,10,10,10,9,10,11,10,9,10,10,10,10,10,10,10,10,10,10,9,9,9,9,8,8,8,7,8,7,7,7,6,6,5,6,7,6,6,6,8,8,9,9,9,10,11,11,10,9,10,9,9,8,9,9,8,8,8,7,7,8,8,8,8,8,9,8,9,9,9,9,9,9,10,10,10,10,10,10,11,11,11,12,12,12,12,12,12,12,12,12,12,11,11,11,11,10,11,10,10,10,9,9,9,9,9,9,10,9,10,10,10,11,11,10,12,11,12,12,12,12,12,12,13,13,12,12,12,12,12,11,12,12,11,11,12,11,9,10,11,11,11,12,11,11,11,12,13,11,12,12,12,13,13,14,12,13,11,14,13,12,12,12,12,12,11,11,11,11,11,11,11,11,11,10,10,10,9,9,9,9,10,10,12,12,14,15,16,14,15,16,19,18,20,21,23,23,23,23,24,23,22,24,25,23,25,25,25,26,27,25,26,25,26,27,26,27,26,26,27,27,26,26,27,26,27,27,26,27,27,25,25,27,26],[28,28,28,28,28,29,28,28,28,27,26,26,26,27,26,27,26,26,27,25,27,28,27,26,28,27,26,27,27,26,26,27,27,28,27,27,26,27,27,27,27,27,26,27,27,26,26,24,25,24,24,23,23,24,23,22,21,21,20,19,17,16,14,12,11,10,8,8,7,7,6,7,6,5,5,5,5,4,5,6,5,5,6,6,5,6,7,7,7,7,7,7,7,6,6,7,6,5,6,6,6,6,6,6,6,5,6,6,5,6,5,5,5,5,5,4,5,4,4,4,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,6,6,6,6,6,6,6,5,6,6,4,4,5,4,5,5,6,5,5,5,5,5,4,4,5,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,6,6,6,6,7,6,7,7,9,9,8,8,9,10,9,9,10,10,10,9,9,8,7,7,8,6,7,6,6,5,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,1,1,0,1,1,1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,5,6,5,5,4,4,5,5,5,5,6,6,6,6,7,7,7,8,8,8,8,7,7,7,6,7,6,5,5,5,5,5,4,5,5,5,4,5,4,4,4,4,5,5,5,5,5,5,6,6,5,6,7,7,7,7,7,7,7,8,9,9,8,9,8,8,7,8,7,8,8,8,8,8,9,10,11,10,12,14,14,14,18,18,18,17,18,20,18,18,20,21,20,21,22,22,23,22,24,25,25,25,25,24,23,24,24,23,24,24,24,25,23,24,26,26,27,26,27,27,27,26,28,27,27,27,27,27,27,28,28,27,28,26,28,27,27,27,26,27,27,26,27,28,27,26,26,25,26,24,24,24,21,22,20,20,19,16,18,16,15,14,12,11,10,11,9,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,14,14,15,15,15,15,12,13,12,12,12,11,12,12,13,14,15,13,15,14,12,12,11,11,11,11,11,11,10,9,10,9,9,9,9,9,7,8,9,8,8,9,9,8,8,9,9,9,9,9,10,10,10,10,9,9,8,7,7,6,5,5,5,4,5,5,5,5,7,6,6,6,7,7,7,6,7,7,7,7,8,7,7,7,8,7,7,8,8,8,8,8,8,8,9,10,10,10,10,8,8,8,8,8,8,7,7,8,8,8,8,9,9,10,10,10,9,9,9,9,8,9,8,9,8,8,9,7,7,7,7,7,7,7,7,6,6,7,6,6,6,6,5,6,7,6,6,7,7,6,6,7,7,8,7,8,8,8,8,8,8,7,8,8,8,8,8,8,8,8,8,8,8,8,8,9,8,9,9,9,9,9,9,8,9,8,8,8,7,7,6,6,7,6,6,5,6,7,6,5,6,7,7,8,9,9,9,10,10,9,9,10,9,9,8,8,8,8,8,7,7,6,7,7,7,7,8,7,7,7,8,7,8,8,8,7,8,8,9,8,8,8,8,8,9,9,9,9,9,10,10,9,9,9,10,9,9,9,9,9,9,9,8,8,8,7,7,7,8,8,8,9,9,8,9,9,9,10,9,9,10,10,10,10,11,11,11,10,10,11,11,10,10,10,10,9,10,10,10,8,9,9,9,9,10,10,10,10,10,11,10,11,10,11,11,11,12,10,11,10,12,10,10,10,10,9,9,9,9,9,9,9,9,8,8,8,8,8,8,8,7,8,7,9,10,10,11,12,14,13,13,14,14,16,17,18,19,20,20,19,21,21,20,21,23,22,23,24,24,25,25,25,24,25,24,26,26,25,26,25,25,26,26,24,25,25,24,25,24,24,25,25,23,24,24,23],[28,28,28,28,28,28,28,27,28,27,26,26,26,26,26,26,25,27,26,26,27,27,26,27,27,27,26,27,27,26,27,27,27,28,27,27,27,27,27,27,27,26,26,27,26,26,25,24,25,24,23,22,23,23,21,22,21,20,19,20,17,16,14,12,11,9,9,8,7,6,7,6,5,4,4,5,5,4,5,5,4,4,5,5,4,5,5,6,6,6,6,6,5,5,6,5,5,5,5,6,5,5,5,5,5,5,5,4,5,5,6,5,5,4,4,4,4,4,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,6,6,5,6,5,5,5,4,4,5,4,4,4,4,3,3,4,4,4,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,2,3,3,2,2,3,2,2,3,3,3,3,4,4,3,3,4,4,4,5,5,5,5,6,6,7,7,7,7,8,8,7,8,8,8,8,8,7,7,6,7,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,2,1,0,1,1,1,1,1,2,2,2,2,3,3,3,4,4,4,4,5,5,5,4,4,3,4,4,4,4,4,5,5,5,5,5,5,6,7,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,5,5,5,5,6,5,5,6,6,6,6,6,6,7,7,8,8,7,7,8,8,8,8,7,6,8,8,8,8,8,9,9,10,10,11,13,14,14,17,16,18,16,17,18,18,18,19,20,20,21,20,22,23,22,24,25,25,24,25,24,24,24,24,24,24,24,25,24,24,25,26,26,27,25,26,27,27,27,26,26,27,27,27,27,27,27,27,27,27,26,27,27,27,26,27,26,27,26,26,27,26,26,26,24,25,25,24,23,22,22,20,20,19,17,17,15,14,14,12,10,10,9,8,9,8,8,10,9,10,10,10,10,10,10,10,11,11,11,11,12,12,12,13,14,14,14,14,11,12,11,11,10,11,11,11,12,12,14,12,14,12,12,12,10,10,10,10,10,9,10,9,9,9,8,9,8,8,7,8,8,8,8,8,8,8,8,9,8,8,9,9,8,9,9,9,8,9,9,7,7,6,5,5,4,4,5,5,4,4,6,5,5,5,6,6,6,6,6,6,6,6,6,5,5,6,6,6,6,7,6,6,6,7,8,7,8,9,9,9,8,8,6,7,6,7,6,6,6,7,7,7,8,8,8,9,9,8,8,8,8,8,7,7,7,7,6,6,7,6,6,6,6,5,5,6,5,5,5,6,5,5,5,5,5,5,6,5,4,5,6,6,5,6,7,6,6,7,7,6,6,7,7,6,6,7,7,7,7,7,7,7,7,7,8,7,7,8,8,8,8,8,8,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,6,6,5,6,6,6,7,7,8,8,9,9,9,8,8,9,8,8,8,8,8,7,7,6,6,5,6,7,6,5,7,7,6,6,7,6,6,7,7,7,7,7,8,8,8,8,8,7,8,9,9,9,9,9,9,9,8,9,9,8,9,9,9,9,9,8,8,8,8,7,7,7,8,7,7,8,8,8,8,8,8,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,9,9,10,10,8,9,9,9,8,9,9,9,9,9,10,9,10,10,10,10,11,11,10,10,10,11,10,9,9,9,9,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,6,8,9,10,10,11,12,12,12,12,14,15,15,16,17,20,19,18,19,21,18,18,20,20,20,23,21,23,23,24,22,24,23,25,25,25,26,24,25,25,24,23,25,24,23,25,24,23,25,25,22,22,24,24],[29,29,29,29,29,29,29,29,29,28,28,28,28,27,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,28,27,28,29,29,28,29,28,28,29,28,29,28,28,28,28,28,26,26,27,24,24,25,26,23,23,25,23,22,20,20,18,17,13,10,9,8,7,6,6,5,5,4,4,3,3,3,3,3,3,4,3,4,4,3,3,4,4,5,5,4,4,5,4,4,4,5,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,3,3,3,3,2,3,3,2,2,2,2,1,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,5,6,6,6,6,6,7,7,7,7,7,7,7,6,6,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,2,3,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,3,3,4,4,4,4,4,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,3,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,6,5,7,6,6,6,5,7,6,6,6,6,7,7,8,9,9,11,13,13,15,17,17,17,19,20,19,19,21,22,22,23,24,25,25,24,27,27,27,27,27,25,25,25,26,24,24,26,26,25,24,26,27,28,28,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,27,28,28,28,26,28,27,27,27,25,26,26,26,25,24,23,21,21,18,17,17,15,14,12,11,9,9,8,7,7,7,7,6,7,7,8,8,8,8,9,9,9,10,10,10,11,12,11,12,13,13,13,12,11,12,10,9,10,9,10,11,11,12,13,12,11,11,10,10,10,9,9,9,9,8,8,8,7,7,7,7,6,5,5,5,6,6,5,6,6,6,6,7,7,7,8,7,8,8,8,8,8,7,7,6,6,4,5,4,3,3,3,4,4,3,4,4,4,4,4,5,4,4,4,4,4,4,5,4,4,4,4,4,4,5,5,5,5,6,6,6,7,8,8,8,7,6,6,5,5,5,5,4,5,5,6,6,6,6,7,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,4,5,5,5,5,5,5,5,5,5,6,5,5,6,5,5,5,6,6,6,6,6,6,5,5,6,5,5,5,4,5,4,5,5,4,4,4,4,5,4,4,4,5,5,6,6,6,7,7,7,6,7,7,7,7,6,6,6,6,5,5,5,4,5,5,4,4,5,4,4,4,5,4,4,5,5,4,5,6,5,6,6,6,6,6,6,7,7,6,7,7,6,7,6,7,7,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,6,5,6,6,6,7,6,7,8,7,7,8,8,9,8,8,8,8,8,8,7,7,8,7,7,7,7,6,6,6,6,6,8,7,7,7,7,8,8,8,8,8,8,9,9,8,8,8,9,8,7,7,7,7,6,7,7,6,6,6,6,5,6,6,5,5,6,5,5,5,6,7,8,10,10,12,12,12,12,13,14,15,16,18,18,21,20,20,20,21,20,20,22,22,21,24,23,24,24,26,25,25,25,26,26,25,27,26,25,25,25,26,26,26,25,25,26,24,26,26,23,24,25,23],[29,29,28,29,29,29,29,29,29,28,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,29,28,28,27,28,28,28,28,28,27,28,28,27,25,25,26,25,25,25,25,25,23,24,21,22,20,20,18,16,13,10,9,8,7,6,5,5,5,4,4,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,5,5,6,6,6,6,7,6,6,7,7,7,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,2,2,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,5,4,4,4,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,4,5,5,5,6,6,5,5,7,6,5,6,5,5,7,7,6,6,7,8,8,9,10,12,13,13,16,17,18,17,18,20,19,18,20,21,21,23,22,25,25,24,26,26,26,26,27,25,24,24,24,23,24,24,25,24,24,25,26,26,27,25,27,27,27,27,28,27,27,27,27,27,27,27,27,27,27,27,28,28,28,27,28,27,27,28,27,28,27,27,28,25,26,26,26,24,23,22,20,21,19,15,18,13,13,12,11,9,8,8,7,7,7,7,7,7,7,7,7,8,8,8,8,9,10,9,9,9,10,10,10,11,11,11,12,11,11,9,9,9,9,9,10,10,11,12,10,11,10,10,9,9,9,9,9,8,8,8,7,7,7,6,6,6,5,5,6,6,5,5,6,6,5,6,6,6,6,7,7,7,7,8,7,7,6,6,5,5,4,4,3,3,3,3,3,3,3,4,4,4,5,4,4,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,7,8,8,8,7,6,6,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,5,6,6,6,7,7,7,6,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,6,6,7,6,6,7,6,6,6,6,6,6,6,5,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,7,8,7,7,7,7,7,7,8,6,7,7,7,6,8,7,7,8,8,9,7,8,8,8,8,8,9,8,8,7,8,8,8,7,7,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,7,7,9,9,10,11,11,11,11,13,14,16,16,17,20,20,19,18,20,20,19,22,20,21,22,23,24,24,25,24,26,24,25,25,25,26,24,25,26,23,24,25,25,24,26,24,24,25,26,23,23,24,24],[27,27,27,27,27,27,27,27,27,26,26,25,26,26,25,27,25,26,26,25,26,27,26,26,27,26,25,27,26,25,26,26,26,27,26,26,26,26,26,26,26,26,25,26,25,25,25,23,23,23,23,22,21,23,20,20,19,19,19,17,15,15,12,10,9,8,7,6,6,5,4,5,4,3,3,4,3,3,3,4,3,3,4,4,3,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,6,7,7,7,7,7,6,5,5,5,5,4,4,4,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,2,2,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,4,3,3,2,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,5,4,4,4,4,4,3,3,4,3,3,3,3,3,2,3,3,2,2,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,6,6,5,6,5,6,6,6,6,6,7,7,8,8,10,12,12,12,14,15,17,14,16,18,16,16,17,18,19,18,19,21,21,21,23,23,24,23,23,22,21,22,22,20,22,22,23,23,23,23,24,24,24,24,25,25,25,25,26,26,25,25,25,26,26,26,26,26,26,26,26,26,25,25,25,25,26,25,25,26,25,25,25,24,24,24,24,23,21,22,18,18,18,15,16,13,13,12,10,8,8,7,7,7,6,7,7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,11,11,11,11,9,10,9,9,9,8,9,9,9,10,11,10,10,10,9,9,8,8,9,8,8,7,7,7,7,6,6,6,6,6,5,6,6,5,5,6,6,5,6,6,6,6,6,7,7,8,7,7,7,6,6,5,5,4,4,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,6,6,6,7,8,8,8,7,6,5,5,5,5,5,4,5,5,6,6,6,7,7,7,7,7,7,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,6,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,5,4,4,4,5,5,6,6,6,7,7,7,6,7,7,7,7,6,6,6,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,7,6,6,6,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,7,7,7,7,7,8,7,7,7,8,7,8,8,7,8,7,8,7,7,7,7,6,6,6,6,6,6,6,5,6,5,5,6,5,5,5,4,5,5,6,7,8,8,10,11,11,11,12,12,14,15,15,16,18,17,17,18,18,17,18,20,19,20,20,20,23,22,23,23,25,22,23,23,24,24,22,23,24,22,22,23,24,23,24,22,22,22,24,20,20,22,22],[29,29,28,28,29,29,28,28,28,27,27,26,27,27,26,27,26,27,27,26,28,27,27,28,27,27,27,28,28,27,27,27,27,28,27,28,27,28,28,28,27,27,27,27,26,26,26,24,26,24,24,23,25,23,22,23,22,21,20,21,17,15,13,10,9,8,6,6,5,4,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,3,3,3,3,4,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,5,5,5,5,5,6,6,6,6,6,6,6,5,5,4,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,3,3,4,4,3,3,2,2,2,2,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,6,6,6,5,5,6,6,5,6,6,6,7,8,8,9,11,12,12,14,16,16,15,16,18,19,19,21,22,21,22,21,24,25,22,26,27,26,25,26,25,25,24,24,23,24,23,25,25,24,25,27,26,27,26,25,26,27,26,27,26,27,27,27,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,27,26,27,26,26,26,25,24,23,23,20,20,19,17,17,15,14,12,10,9,8,8,7,6,7,7,7,7,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,11,11,10,11,10,9,8,8,9,9,9,9,10,10,11,10,10,9,9,9,8,8,8,8,8,8,8,7,7,7,6,6,6,5,5,5,6,6,5,5,6,6,5,6,6,6,6,7,7,7,7,7,7,7,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,6,5,6,7,7,8,6,6,5,4,4,4,5,4,4,4,5,5,5,6,5,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,4,4,3,3,3,4,3,3,4,3,3,3,4,3,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,4,5,5,4,5,6,5,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,4,4,4,5,5,5,6,6,6,7,6,6,6,6,7,6,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,8,8,8,8,8,8,7,7,7,7,7,6,7,7,7,6,6,6,7,6,7,7,6,7,6,7,7,7,7,7,7,8,8,7,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,6,7,8,8,10,10,11,10,11,13,13,15,16,17,19,18,17,18,19,17,18,21,20,20,22,21,23,24,25,23,24,23,25,24,25,25,24,25,24,23,23,24,25,24,25,23,23,25,25,22,21,24,24],[29,29,29,29,29,29,29,28,29,28,28,27,28,28,28,27,27,28,27,28,28,27,28,28,28,28,28,28,28,27,27,28,28,29,28,28,27,28,28,28,28,28,27,27,27,27,26,25,25,25,24,24,25,23,23,24,22,22,20,21,17,16,13,10,8,7,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,6,5,6,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,3,4,4,3,3,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,4,4,5,5,4,5,4,5,5,5,5,5,6,6,7,7,9,11,11,12,14,16,17,16,18,20,19,18,21,22,22,22,24,24,24,24,25,26,26,26,26,24,25,25,23,23,24,24,25,24,25,24,26,25,27,25,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,27,28,26,27,28,27,27,28,27,28,25,26,27,26,26,25,23,21,22,19,17,17,15,13,12,10,8,8,6,6,5,5,6,5,5,5,6,6,6,7,7,7,8,9,8,8,9,9,9,9,10,10,10,10,9,10,8,8,8,8,9,9,9,10,10,9,9,9,9,8,8,8,8,7,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,4,5,4,4,5,5,5,6,6,6,6,7,7,6,6,5,4,4,3,3,3,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,3,3,4,3,3,3,4,4,3,4,4,4,4,5,5,5,6,7,7,7,6,5,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,5,5,5,5,4,5,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,6,6,6,5,6,5,5,5,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,6,6,6,6,6,6,7,7,6,7,7,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,6,6,7,6,7,7,7,7,8,7,7,7,6,7,7,6,6,6,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,3,4,5,6,8,8,10,11,11,11,12,14,14,16,17,18,20,20,19,18,21,21,20,23,21,23,24,22,25,24,26,25,25,24,26,25,25,26,25,25,25,23,24,26,26,24,26,25,25,25,26,24,23,25,24],[29,28,28,28,28,28,29,28,28,27,27,27,27,26,26,27,27,27,27,27,28,27,27,28,28,27,27,28,27,27,26,27,27,28,27,27,27,27,27,27,27,26,26,27,26,26,26,25,25,24,24,23,23,23,22,23,21,21,19,19,17,16,12,10,9,7,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,4,4,5,5,5,5,6,5,5,6,6,6,6,6,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,3,4,4,3,3,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,4,5,5,5,5,4,6,5,5,5,5,5,5,5,5,6,6,7,7,8,9,11,12,12,15,15,17,15,17,18,18,17,19,19,20,21,21,22,23,23,24,24,25,25,26,25,22,24,23,22,23,24,24,23,24,25,26,25,27,26,27,26,27,26,27,26,26,26,26,27,26,26,27,27,27,27,27,27,27,26,26,27,27,27,26,27,26,26,27,26,25,26,24,24,22,21,19,20,18,15,17,14,12,11,10,8,8,6,6,6,6,6,5,6,6,7,7,7,7,7,7,8,9,8,8,9,10,9,9,9,10,10,11,10,9,8,8,8,9,8,9,9,10,10,9,9,9,8,8,8,8,8,8,7,7,7,6,7,6,6,5,5,5,5,4,5,5,4,5,5,4,4,5,5,5,6,6,6,6,6,6,6,6,5,4,4,3,3,3,2,2,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,7,7,7,6,6,5,5,4,5,5,4,4,5,5,5,6,6,6,6,6,6,6,5,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,4,4,4,5,5,5,6,6,6,6,7,6,6,7,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,4,4,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,6,7,7,8,7,6,7,6,7,6,6,6,6,6,6,6,6,5,6,6,5,7,7,7,7,7,7,6,7,7,7,7,7,8,7,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,5,6,7,7,9,10,11,10,11,12,12,15,16,17,18,19,17,17,18,19,18,20,19,20,23,22,24,24,24,23,25,23,24,25,24,25,23,24,24,22,23,24,24,24,24,23,23,23,25,22,21,23,23],[28,27,27,27,27,27,28,27,27,26,26,25,25,25,25,26,25,25,26,25,26,26,25,26,26,26,25,26,26,24,26,26,26,26,26,26,25,26,26,26,25,26,25,25,25,24,24,23,23,22,22,23,21,22,20,20,19,18,17,17,14,14,11,9,8,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,4,4,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,5,4,5,6,5,6,5,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,3,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,4,5,5,5,5,5,4,5,5,5,5,5,6,6,8,7,9,11,12,11,13,14,15,14,15,16,15,15,16,17,18,18,18,20,21,20,22,23,23,23,22,23,21,22,22,21,22,21,23,22,22,22,25,24,25,24,25,25,25,25,25,24,24,25,25,25,25,25,25,26,26,25,26,25,26,25,25,25,26,25,25,26,25,25,25,24,24,24,23,23,21,21,19,18,17,15,15,13,12,10,9,8,7,7,6,6,6,6,6,6,6,6,6,7,7,7,7,8,8,7,8,8,8,8,9,10,9,10,9,8,8,7,7,7,7,8,8,8,9,9,9,9,8,8,8,7,7,8,7,7,7,7,6,6,6,5,5,5,5,4,4,5,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,5,5,4,4,3,3,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,6,6,7,7,5,5,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,5,5,6,5,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,6,6,6,5,5,6,5,5,5,4,4,4,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,6,7,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,5,6,7,7,9,10,10,10,10,12,13,14,17,14,19,17,16,17,18,16,17,19,18,19,21,20,22,21,23,21,23,22,23,23,23,24,22,22,23,20,21,23,23,22,23,22,21,21,23,21,20,22,22],[28,29,29,29,28,29,28,28,29,27,28,27,27,27,27,27,26,27,26,26,26,26,26,26,26,26,27,26,27,26,26,26,27,27,26,27,26,27,27,27,27,26,25,26,26,26,24,24,24,23,22,23,23,21,20,22,20,19,18,18,16,14,12,9,8,6,5,4,4,4,3,3,3,2,2,2,3,2,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,2,1,2,2,2,2,3,3,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,3,3,3,3,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,4,4,4,5,4,4,5,5,5,6,6,7,8,10,11,11,13,15,16,14,16,18,17,17,19,19,20,21,21,22,24,23,24,25,25,24,25,23,23,24,23,22,23,23,24,24,24,24,25,25,26,25,26,26,26,27,26,26,27,27,26,26,26,26,27,27,27,27,27,27,28,27,27,25,26,27,26,27,27,26,26,24,24,25,24,23,22,21,20,20,18,17,16,14,13,11,9,7,7,6,5,5,5,5,4,5,4,5,6,6,6,6,6,7,7,7,7,8,8,8,8,9,8,9,9,8,8,7,7,7,7,8,8,8,8,9,8,8,8,8,7,7,7,7,6,6,6,6,6,5,5,5,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,6,6,6,6,5,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,5,6,6,6,5,4,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,5,6,7,7,9,10,11,10,11,14,14,17,17,17,20,21,19,18,18,20,20,22,21,22,24,22,25,24,25,24,25,23,25,25,24,25,24,25,24,23,24,25,25,24,25,24,24,24,25,24,22,25,25],[29,29,29,29,29,29,29,29,29,28,28,27,28,27,28,27,28,28,28,28,28,27,28,28,28,28,28,28,29,28,27,28,28,29,28,28,28,28,28,28,28,28,27,27,27,27,25,25,25,25,24,24,25,23,22,23,21,21,20,21,17,15,13,10,8,7,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,4,3,4,4,4,4,5,5,4,4,3,3,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,2,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,5,4,5,5,5,5,5,6,6,7,7,8,10,11,12,14,15,16,16,16,19,17,17,20,21,20,21,22,24,24,23,25,25,26,25,25,23,24,24,23,24,24,23,25,24,24,24,26,26,28,24,26,27,27,27,27,27,27,27,27,27,27,27,27,28,27,27,28,28,28,27,27,26,27,28,26,28,27,26,28,25,26,25,25,24,24,23,22,21,18,16,16,15,13,12,10,8,7,6,6,5,5,6,5,6,5,5,6,6,7,7,7,8,8,8,8,8,9,9,9,9,9,9,10,9,9,8,7,8,8,8,9,9,9,9,9,9,9,8,8,7,7,7,7,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,6,5,5,5,4,4,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,7,7,7,6,5,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,4,3,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,6,7,6,6,7,6,6,6,6,6,6,6,6,6,5,5,5,5,5,6,6,6,6,6,7,6,7,7,6,6,7,7,6,6,6,7,6,6,6,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,5,6,7,7,9,10,11,10,11,14,14,16,17,18,20,21,20,18,19,20,19,22,20,22,23,22,25,24,25,25,25,24,25,24,25,25,24,24,25,21,23,24,24,23,24,22,23,24,25,22,21,24,24],[28,28,27,28,27,28,28,28,27,27,26,26,26,25,26,26,26,26,26,26,27,27,27,26,26,27,26,26,27,25,25,26,26,27,26,26,26,27,27,26,27,26,25,26,26,25,25,24,24,23,23,22,22,22,21,20,21,19,19,17,15,14,11,9,9,7,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,2,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,5,5,4,5,5,5,6,6,6,7,6,5,5,4,5,4,4,4,4,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,2,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,4,5,5,4,4,4,5,5,5,5,5,6,7,7,8,9,11,11,12,14,15,16,14,15,17,16,16,18,18,19,18,20,21,22,22,23,23,24,23,24,24,21,23,22,21,23,23,23,22,23,23,25,24,26,25,26,26,26,26,27,26,26,26,26,26,26,26,26,26,27,26,27,26,26,26,26,26,26,26,26,26,26,26,26,25,25,24,23,23,21,21,18,18,17,14,16,13,12,11,9,8,7,7,6,6,6,6,5,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,9,9,8,8,8,8,8,8,9,9,9,9,9,8,8,8,8,7,7,7,7,7,7,6,6,5,6,5,5,5,4,4,5,4,4,5,5,4,4,5,5,4,5,6,5,6,6,6,6,5,5,4,4,3,3,3,2,3,2,3,2,2,3,2,2,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,6,5,6,7,7,7,6,5,5,5,4,5,5,4,4,5,5,5,6,6,6,6,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,4,4,4,4,4,5,5,6,6,6,7,7,7,6,6,7,7,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,4,4,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,6,7,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,5,6,5,5,6,6,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,4,6,7,8,9,10,11,10,10,11,14,15,16,16,18,19,16,17,19,19,18,20,19,20,21,21,23,23,22,22,24,23,24,23,24,23,22,23,24,22,22,22,23,24,23,22,21,22,24,22,20,22,22],[27,27,27,27,27,27,27,27,27,26,25,25,26,25,25,25,25,26,26,26,27,26,26,27,26,26,26,26,26,25,26,26,26,27,26,27,26,27,27,27,27,26,25,26,26,26,25,24,24,24,22,22,23,22,20,21,21,19,19,18,16,14,13,10,9,8,7,6,6,6,5,5,4,3,3,4,4,3,4,4,4,3,4,3,4,4,4,5,4,4,4,5,4,5,5,4,4,5,4,4,4,5,5,4,5,5,5,4,5,5,6,5,5,4,4,5,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,4,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,5,5,5,5,5,5,6,6,6,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,2,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,5,4,4,4,5,5,5,5,5,6,6,5,5,5,5,6,6,6,6,7,7,8,8,9,11,12,12,14,15,16,15,16,18,16,17,19,20,20,20,20,22,23,22,24,24,26,25,25,23,24,25,23,22,23,24,24,23,23,23,27,26,26,25,26,26,27,27,27,26,26,26,26,26,26,27,27,26,27,27,27,26,27,26,27,25,27,26,26,27,27,26,26,24,25,25,25,23,22,22,21,20,18,17,17,15,13,12,11,8,8,8,7,7,6,7,6,6,6,7,7,7,7,8,8,8,9,8,8,9,9,9,9,10,9,10,9,9,8,8,8,8,8,8,9,9,9,10,9,10,9,9,9,8,7,8,8,7,7,8,7,7,6,6,6,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,7,7,6,6,6,5,4,4,3,3,3,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,5,4,5,4,5,5,5,6,7,7,6,6,5,4,4,4,5,4,4,5,5,5,5,5,6,6,6,7,7,6,6,6,6,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,5,4,4,4,4,4,4,4,4,4,5,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,6,7,7,6,6,6,6,5,6,5,5,4,5,5,4,4,5,4,4,4,5,4,4,5,5,4,5,5,5,5,6,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,7,6,7,6,7,8,7,8,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,7,6,7,7,6,7,7,6,7,7,7,7,7,7,7,7,7,6,7,6,6,6,5,5,6,5,5,5,5,5,4,5,4,4,4,4,3,4,4,5,7,8,8,10,11,11,11,10,13,14,16,17,17,19,18,18,18,20,19,18,20,19,20,21,20,23,23,23,22,23,23,23,24,24,26,23,24,23,22,22,23,24,24,24,22,22,22,23,22,21,22,23],[28,28,29,29,28,29,28,28,28,27,28,27,27,27,27,27,27,27,26,27,27,26,26,27,26,26,27,26,27,26,25,27,27,28,26,27,26,27,27,26,27,27,25,26,26,26,25,24,24,24,22,23,23,21,20,22,21,20,19,20,17,15,12,10,8,8,6,5,5,4,4,4,4,3,3,3,3,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,6,6,5,4,4,4,5,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,2,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,5,5,4,5,5,5,5,5,6,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,2,3,3,3,3,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,5,5,5,5,5,6,5,5,5,5,5,5,5,5,6,6,7,7,8,9,11,12,12,13,15,16,16,17,19,19,19,20,21,21,20,23,23,24,24,24,25,25,24,25,24,24,25,22,22,24,24,25,23,24,25,25,25,27,25,26,27,27,27,26,26,27,27,27,27,27,27,27,27,27,27,27,28,28,27,27,26,26,27,27,27,27,26,27,24,24,25,24,23,23,21,21,21,18,18,17,15,14,12,11,9,8,7,6,6,6,6,5,6,5,6,6,7,7,8,7,8,9,8,8,9,9,9,9,10,10,10,10,9,9,9,8,9,9,8,9,10,10,11,10,9,9,9,9,8,8,8,8,8,7,7,7,6,6,6,5,5,4,5,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,7,7,7,6,6,4,5,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,6,7,7,7,6,5,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,4,4,4,4,4,4,4,4,4,5,5,5,4,5,5,4,4,5,5,5,4,4,4,4,5,4,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,7,7,6,6,6,6,6,6,5,5,5,4,4,3,4,4,3,3,4,4,3,3,4,3,4,4,4,3,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,4,4,5,5,4,4,5,4,4,5,5,5,5,6,6,6,6,6,7,7,7,6,7,7,6,6,6,6,6,6,6,6,6,6,5,5,5,5,6,7,7,6,6,6,7,7,7,7,7,7,7,7,7,6,7,6,6,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,5,7,8,8,10,12,11,11,12,14,15,17,18,18,21,21,19,19,20,21,19,22,21,21,23,22,25,24,25,24,25,24,25,25,25,25,24,25,25,23,24,25,24,25,25,24,23,24,26,23,23,25,25],[29,28,28,29,28,28,29,28,28,28,27,28,28,27,27,27,27,28,27,28,28,27,28,28,27,28,28,27,28,27,27,28,28,28,27,28,27,27,28,27,28,27,27,27,27,27,26,25,26,25,24,25,25,23,23,24,22,22,21,21,18,16,14,12,10,10,9,8,7,7,6,6,6,5,4,5,5,4,5,6,4,4,5,5,4,5,6,6,6,6,6,6,6,5,6,6,5,6,6,6,5,6,6,6,6,7,6,6,6,7,8,6,6,6,6,6,5,5,5,5,5,5,4,5,5,4,5,5,5,4,5,6,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,4,5,5,5,6,6,6,6,6,6,6,5,5,4,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,5,4,5,5,6,6,7,7,7,7,7,8,8,7,8,8,7,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,2,3,3,3,3,3,4,4,4,5,4,4,4,3,4,4,4,3,2,3,2,1,1,1,1,1,0,1,2,3,4,4,3,2,2,3,3,2,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,2,2,2,2,3,3,4,5,5,4,4,6,5,5,6,5,6,5,6,6,6,6,7,7,7,7,6,8,7,7,7,7,7,8,8,8,8,8,10,9,10,11,12,14,14,16,17,18,17,19,20,19,19,21,22,21,22,24,25,25,24,26,25,27,26,27,25,24,26,24,22,25,24,25,24,24,24,27,26,27,26,26,26,27,27,28,27,27,27,26,27,27,27,27,27,27,27,28,28,28,27,28,27,27,28,28,28,27,27,27,25,25,26,25,23,23,22,21,21,19,18,18,15,14,13,12,10,10,9,9,9,9,9,9,9,9,9,10,9,10,10,10,11,12,11,10,11,12,12,11,12,13,13,13,11,11,11,10,10,11,10,11,11,13,13,11,13,12,12,11,11,10,11,11,10,10,9,9,9,9,8,8,7,6,6,6,7,6,5,6,7,6,6,7,7,6,6,7,7,8,8,8,8,7,6,5,5,4,5,3,3,3,3,3,2,3,3,3,3,4,3,4,4,4,5,5,4,5,5,6,5,5,5,6,6,6,7,7,6,7,7,8,8,9,9,9,8,7,7,6,7,7,6,6,6,6,7,7,7,8,7,8,9,9,9,7,8,8,7,7,8,7,7,7,7,6,6,6,6,6,6,6,5,4,5,4,5,4,4,5,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,6,7,7,7,7,7,7,7,8,7,7,8,7,7,7,8,8,7,7,7,7,6,6,7,6,5,5,6,6,6,6,6,7,7,8,8,8,9,10,10,8,8,9,9,8,8,7,8,7,7,7,7,6,7,6,6,6,7,6,6,6,7,6,6,7,7,6,7,7,7,7,7,7,8,7,8,8,8,8,8,8,8,7,8,8,8,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,8,8,7,8,9,8,8,8,9,8,9,9,9,9,10,10,9,10,10,10,10,9,9,9,10,9,9,10,8,8,9,9,9,9,9,9,10,9,9,9,10,10,9,9,9,10,9,9,9,10,8,8,8,8,8,7,6,7,7,6,6,6,6,5,5,5,5,5,5,4,4,5,6,8,9,9,11,11,12,12,11,14,16,17,17,19,20,19,19,20,21,21,18,23,20,22,23,22,24,25,25,24,24,24,25,25,24,25,25,25,25,23,24,25,25,24,25,24,23,25,26,23,23,24,23],[27,27,26,27,27,27,27,27,26,26,26,26,26,25,25,26,26,26,26,27,27,27,27,27,27,26,27,27,27,26,26,27,27,28,26,27,26,26,27,26,27,27,26,26,27,26,25,24,25,24,24,23,23,23,22,22,22,21,21,20,18,17,15,13,12,11,10,10,9,9,7,7,6,5,5,6,6,5,6,7,7,6,7,7,6,7,8,8,8,8,8,8,9,8,8,8,7,8,8,8,8,8,9,8,8,8,8,8,8,9,9,8,8,8,7,8,7,7,7,7,7,7,6,6,7,6,6,7,7,6,6,7,6,6,6,6,6,7,7,7,6,8,7,7,7,8,8,7,7,7,7,6,7,7,7,8,8,8,7,8,8,7,7,7,8,6,6,7,6,5,6,6,5,5,6,5,5,5,5,5,4,5,4,4,4,5,4,5,5,4,5,6,5,5,6,7,7,8,7,8,8,8,8,9,9,9,9,8,8,7,8,8,7,8,7,6,6,6,6,5,6,6,5,5,5,4,4,4,4,3,3,4,4,5,6,6,5,4,5,5,5,4,4,4,3,3,3,3,3,2,2,2,1,0,1,2,3,4,3,3,2,2,3,3,3,4,4,5,5,5,5,5,7,7,7,7,6,7,7,7,7,7,6,6,6,5,5,5,4,4,4,4,3,3,3,3,2,4,3,4,4,5,5,5,6,5,6,7,7,7,6,6,7,7,7,8,8,8,7,7,8,8,8,8,7,8,9,9,9,9,9,10,11,11,12,13,14,14,16,15,18,16,17,19,19,19,19,20,21,20,22,23,23,23,25,24,26,25,25,25,23,25,23,23,24,24,24,23,24,24,27,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,26,27,27,27,27,26,26,27,27,26,26,27,26,26,27,25,24,25,24,23,22,22,20,20,19,17,18,15,15,13,12,11,10,10,10,10,9,9,9,10,10,10,11,10,11,11,10,11,12,12,11,12,13,13,13,13,13,14,13,11,11,11,11,11,11,11,12,12,12,14,13,14,13,12,12,11,11,11,11,11,11,10,10,10,9,9,9,9,8,7,8,9,7,8,9,9,8,8,9,8,7,9,9,8,9,8,8,9,8,7,7,6,5,5,4,4,3,5,5,3,4,5,4,3,4,5,4,4,6,6,6,5,7,7,7,6,8,8,8,8,7,9,8,8,8,8,8,9,10,10,10,9,8,8,8,8,8,8,6,7,8,9,9,9,10,10,10,10,10,10,9,10,9,9,9,9,9,8,9,9,9,9,9,8,7,7,8,6,6,7,6,5,5,6,6,5,6,6,5,5,6,6,7,6,7,7,7,7,6,7,6,6,8,8,7,8,9,8,8,8,7,9,8,9,9,9,8,9,9,8,9,8,9,9,9,9,9,9,9,8,9,8,8,8,9,9,9,8,7,8,8,9,9,9,10,9,9,10,10,10,11,10,10,10,10,10,10,10,9,9,9,9,8,8,7,8,7,7,7,7,8,6,8,7,7,7,9,8,7,9,9,9,10,9,9,9,9,10,9,9,9,9,9,10,9,9,10,9,9,9,10,9,9,9,9,9,9,9,8,8,8,8,8,8,9,8,9,9,9,9,10,9,10,10,10,10,10,11,10,11,10,11,11,10,11,10,10,10,10,10,10,10,10,9,9,10,9,10,10,10,10,10,11,10,10,10,9,11,10,10,10,10,10,11,10,9,10,10,10,10,8,9,10,9,8,8,8,7,7,7,6,6,6,6,5,6,8,8,10,10,11,12,13,12,13,14,16,16,18,17,21,19,18,20,21,20,19,21,19,20,22,21,24,25,23,23,23,25,24,25,25,25,24,24,25,23,22,24,25,24,25,23,23,24,24,23,20,24,24],[29,29,29,29,29,29,30,29,29,29,29,28,29,28,29,28,29,29,28,29,29,28,29,29,28,29,29,29,29,29,28,29,29,29,29,29,28,29,29,29,29,29,28,28,28,28,27,27,28,26,26,27,26,26,25,26,25,24,23,22,21,19,18,16,14,14,14,13,12,12,11,10,9,9,8,10,9,8,9,10,10,9,10,11,9,10,10,10,10,10,10,10,10,11,10,10,10,10,10,10,11,10,9,9,11,10,10,10,10,11,13,11,11,10,10,11,10,9,9,9,8,10,10,9,9,10,9,8,9,7,8,8,7,8,7,8,7,8,7,8,8,8,8,9,10,10,9,11,10,10,10,11,11,11,10,12,11,10,11,12,12,11,10,10,11,9,9,11,9,9,10,10,8,9,9,7,6,7,6,6,6,6,5,5,5,5,5,5,6,5,6,7,5,7,7,9,9,11,10,10,10,10,10,11,11,13,11,10,10,10,9,10,8,9,9,7,9,10,7,7,8,7,7,7,8,6,6,6,7,6,5,8,7,8,8,8,8,8,7,8,7,7,7,6,6,4,4,4,3,3,3,2,1,1,0,1,3,4,3,3,2,3,3,3,4,6,7,8,6,7,7,7,9,10,10,10,9,8,9,9,7,10,8,9,9,7,7,7,6,5,7,6,5,4,5,5,3,4,5,7,7,7,6,6,7,7,7,7,8,8,8,8,7,9,9,9,10,10,9,10,11,11,10,11,9,11,12,12,13,13,13,13,14,14,15,16,18,17,19,19,20,20,21,23,22,22,23,24,24,24,25,27,27,26,27,28,28,27,28,27,26,27,26,26,27,26,27,27,26,27,28,27,28,28,28,28,28,28,28,28,28,29,29,28,28,29,28,29,28,28,29,28,28,28,28,28,28,28,28,29,28,28,28,27,28,27,27,26,26,26,24,24,21,22,22,19,19,17,16,15,14,13,13,12,12,13,10,12,11,12,13,13,13,14,13,14,15,14,14,14,15,16,15,16,15,16,16,14,14,14,13,14,14,14,15,14,15,15,16,16,16,15,14,15,14,14,13,14,14,13,12,13,12,11,11,11,13,9,8,10,8,10,9,10,9,8,10,9,9,10,10,10,11,11,11,11,10,8,8,7,6,6,5,4,4,5,5,4,4,6,5,5,6,7,7,6,7,7,7,7,7,9,7,7,10,10,11,11,10,11,12,10,11,10,10,11,11,12,12,11,10,11,10,10,10,10,9,10,10,11,11,11,11,12,13,14,13,13,12,12,12,12,12,12,12,12,10,11,11,10,11,10,11,10,10,11,10,9,10,9,7,8,9,7,7,8,7,7,7,8,7,7,9,9,9,7,8,9,8,8,9,9,10,9,10,10,10,10,10,10,10,11,11,10,11,12,11,10,11,11,11,12,12,12,12,12,12,12,11,11,11,12,12,11,12,12,12,11,12,12,11,12,12,11,12,12,12,13,13,13,12,12,13,12,11,13,12,12,12,12,12,12,10,10,11,10,9,11,11,9,10,10,10,10,11,11,10,10,10,12,12,11,11,11,11,11,11,11,11,12,12,11,12,11,12,12,11,11,12,12,11,11,12,12,12,12,11,10,11,11,11,11,11,11,11,11,11,12,11,12,12,12,12,12,12,12,13,12,12,13,13,12,12,13,13,12,13,13,12,13,12,13,12,13,12,12,13,13,13,13,13,12,13,12,12,13,13,14,12,13,11,13,13,11,11,11,11,11,10,11,10,9,10,9,10,8,8,9,8,8,8,6,8,7,9,10,12,11,14,14,14,15,14,17,19,18,19,20,20,22,19,22,22,22,19,24,23,22,24,25,25,26,26,25,24,25,26,26,26,27,25,25,27,26,25,24,25,26,26,25,25,25,26,26,24,26,26],[28,28,28,28,29,29,29,28,28,28,28,27,28,27,28,27,28,29,28,29,29,28,29,29,29,29,29,28,29,29,28,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,28,27,29,27,26,26,27,26,26,27,26,25,25,25,23,21,20,19,18,18,17,15,16,14,15,14,13,12,12,13,13,12,13,13,12,12,13,12,11,12,14,14,14,13,14,13,12,14,13,13,12,13,13,12,12,14,13,11,13,13,13,11,15,15,16,16,15,15,15,16,15,15,12,12,13,12,9,10,11,11,9,10,11,9,9,9,10,8,10,9,10,9,10,10,10,9,10,10,11,10,10,11,11,12,11,12,12,13,13,15,15,16,16,16,16,15,15,16,14,14,14,14,11,11,12,11,11,12,13,10,9,9,11,9,11,8,7,8,11,7,5,9,10,7,8,10,9,9,10,11,11,10,12,13,14,12,14,15,15,16,14,15,13,13,13,12,12,11,11,12,11,12,11,11,10,10,9,11,11,10,10,11,11,10,9,12,11,10,12,13,12,11,10,10,12,11,10,11,9,10,8,9,8,7,4,4,4,3,1,0,2,4,4,4,3,6,7,6,7,9,8,8,9,10,10,11,12,11,12,13,12,11,12,11,12,12,11,10,11,10,10,10,9,10,10,10,9,9,10,9,7,8,10,12,10,11,11,9,11,11,9,11,12,11,11,12,12,12,11,14,13,15,14,14,15,15,14,13,14,16,16,14,16,16,16,18,15,16,18,18,20,19,20,21,23,22,23,24,24,24,25,26,26,27,27,27,28,27,28,28,28,28,28,28,27,28,27,27,28,27,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,30,29,29,30,30,30,29,29,29,29,29,29,30,29,29,29,28,28,28,28,27,27,26,24,25,23,23,23,21,21,20,19,18,18,17,16,15,16,16,14,16,15,16,16,17,18,17,15,17,18,17,16,17,19,17,18,19,19,19,18,16,17,15,15,17,16,16,17,18,19,19,19,19,19,18,17,18,17,17,18,18,16,16,16,16,16,15,14,15,14,13,12,13,13,12,12,13,13,12,13,13,13,13,14,13,13,14,13,13,13,12,12,11,8,8,8,7,6,8,6,5,6,7,6,6,7,8,8,8,9,11,10,9,10,12,11,11,14,14,14,14,14,14,14,14,13,14,14,15,15,15,15,16,15,15,14,15,15,13,13,14,15,15,18,16,16,17,18,19,19,19,17,16,18,17,16,17,16,16,16,14,15,14,14,13,13,13,13,13,11,12,11,11,9,10,10,11,9,10,9,10,8,10,11,7,10,11,11,8,10,11,10,9,12,12,12,12,12,13,12,13,14,14,15,14,15,14,15,15,14,14,17,16,14,16,17,15,14,16,16,16,14,15,16,15,17,15,15,14,16,15,16,16,17,17,17,16,17,18,17,18,18,17,17,15,18,17,15,17,17,16,17,15,16,16,14,13,13,15,13,14,14,13,13,13,13,14,14,13,13,14,14,13,14,14,15,14,14,15,16,15,14,16,15,15,15,14,17,16,15,14,17,17,14,15,16,14,17,14,15,14,13,16,14,14,15,16,14,14,16,16,15,16,16,16,17,16,16,16,16,16,17,16,16,17,16,18,17,17,16,17,16,17,16,15,15,15,16,15,16,16,15,16,16,16,16,17,15,17,16,17,16,17,14,16,16,15,15,15,15,14,14,14,14,13,13,12,12,12,12,12,10,12,12,8,8,11,11,12,13,14,15,16,15,17,16,18,20,20,21,21,24,21,21,22,24,23,22,24,23,24,26,23,26,26,26,25,25,25,26,27,27,27,26,27,28,25,25,27,27,26,27,26,26,27,27,25,24,26,26],[28,28,28,28,29,28,29,28,28,27,28,27,28,27,28,27,29,29,27,29,29,28,28,29,28,29,29,28,29,29,28,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,28,28,29,28,26,27,27,27,26,27,26,25,25,25,23,21,20,20,19,19,18,16,16,15,15,15,13,12,14,14,13,12,14,13,14,13,14,13,10,13,15,14,15,13,14,14,12,14,14,14,12,15,15,11,13,15,15,11,14,15,15,12,14,16,16,16,15,16,15,15,14,14,13,13,14,12,11,12,12,10,9,11,10,9,9,10,8,9,11,10,10,9,11,10,9,9,11,11,11,10,10,11,11,13,11,11,13,13,13,15,15,15,15,16,15,15,14,14,15,14,14,14,13,11,12,12,11,10,11,10,10,10,9,9,11,8,7,8,9,5,6,9,5,5,10,10,11,10,9,12,11,11,12,13,13,13,13,15,15,16,15,13,13,12,12,11,12,10,12,11,11,11,9,11,12,11,10,9,12,12,10,12,11,10,10,11,11,11,12,12,11,12,12,11,12,10,11,9,10,10,9,8,8,7,6,6,5,4,3,2,0,1,2,3,4,5,7,7,6,9,9,10,10,10,11,11,12,13,14,12,13,11,11,11,9,11,11,11,11,9,9,10,9,8,10,11,9,8,9,9,7,8,10,11,12,11,11,11,12,12,12,12,12,12,12,14,13,13,13,15,15,16,14,14,16,16,15,15,14,16,18,16,16,18,18,18,20,19,19,20,22,20,21,23,24,23,23,25,24,25,26,27,27,27,27,27,28,28,28,28,29,28,29,29,28,29,28,27,28,27,28,28,27,28,29,28,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,28,29,28,28,27,26,26,25,26,24,23,23,21,21,21,19,18,19,19,18,20,19,20,17,19,17,17,18,19,20,20,18,19,20,19,18,19,21,19,20,21,20,21,20,18,17,16,17,17,19,19,19,20,20,21,21,22,21,21,20,20,19,19,20,19,19,20,18,18,19,17,17,17,15,15,14,16,15,14,16,16,14,15,16,15,16,15,15,16,16,15,14,15,14,13,15,12,11,11,8,7,7,8,9,7,7,8,8,7,8,8,8,10,11,11,12,10,13,13,12,12,14,13,14,13,15,14,14,15,14,16,15,15,16,16,17,17,15,14,15,14,13,12,11,14,14,15,16,17,17,17,18,19,19,19,18,18,18,17,15,18,17,16,15,15,14,15,15,14,13,13,14,13,12,13,12,12,11,12,12,11,10,12,10,11,10,12,12,11,12,14,14,11,13,14,12,13,14,15,13,13,15,15,12,14,14,16,15,14,15,15,15,14,15,16,17,17,16,18,18,16,16,18,17,17,15,15,17,16,17,15,15,15,15,15,16,16,15,16,17,16,17,18,17,18,19,18,18,16,18,17,16,16,18,16,17,17,15,15,14,14,14,14,13,15,15,13,14,15,13,14,15,15,13,15,17,15,17,16,17,16,15,18,18,16,17,19,18,17,17,16,20,19,17,16,19,18,15,19,18,16,18,17,17,14,14,19,16,14,17,19,16,16,19,17,17,18,19,18,19,18,19,19,19,21,19,19,19,19,18,20,20,20,18,20,20,20,18,18,18,17,19,18,18,18,17,17,19,18,18,20,18,19,18,19,18,18,17,20,17,16,16,17,16,16,15,16,15,15,15,15,13,13,16,14,12,13,13,11,8,11,10,12,14,14,16,16,17,17,16,19,20,20,21,21,24,22,21,23,24,21,22,24,23,23,26,23,26,26,26,26,26,26,27,27,27,28,27,28,28,26,26,27,28,26,27,26,26,27,27,25,24,25,26],[29,29,28,28,29,28,29,29,28,28,28,28,28,27,28,28,28,29,27,29,29,28,28,29,28,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,29,29,28,28,29,28,28,27,28,27,27,27,27,27,25,27,26,25,23,24,23,21,20,19,19,18,18,17,16,16,15,15,14,15,14,14,13,13,14,14,16,14,14,14,12,13,14,14,14,13,14,14,13,14,14,13,12,12,13,12,12,13,14,11,13,14,13,12,13,15,17,15,14,15,14,15,14,13,13,12,12,12,12,11,11,12,11,10,11,8,10,10,9,11,11,11,10,8,10,10,9,9,11,10,9,11,11,9,11,12,11,10,13,13,13,14,15,14,16,17,16,14,14,14,15,14,13,14,13,13,12,13,11,12,12,10,9,11,9,9,8,9,6,7,8,5,6,7,8,5,8,8,9,8,8,11,11,10,10,11,12,11,11,14,15,16,14,11,12,12,13,11,10,10,10,9,9,9,8,9,10,11,8,10,10,10,9,11,10,10,11,11,12,12,12,13,12,11,11,10,10,10,11,10,9,11,9,7,7,7,6,5,6,4,3,2,1,0,1,3,4,5,7,6,5,8,9,10,9,8,10,9,11,11,12,11,11,10,9,10,11,9,9,11,10,9,10,10,9,8,10,9,9,9,9,9,9,9,12,12,13,12,14,13,14,13,13,14,14,14,14,15,15,14,14,16,17,17,16,15,16,16,16,15,14,16,18,16,17,18,18,17,17,18,19,20,21,21,21,22,22,22,24,24,23,25,25,25,26,26,26,27,27,26,27,27,28,28,28,28,27,27,27,27,27,27,28,28,27,28,29,28,29,29,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,28,28,29,28,28,28,27,27,26,27,25,25,24,22,23,21,21,22,20,19,19,18,17,19,18,18,17,19,16,18,18,18,19,19,19,19,20,19,19,18,20,21,21,22,20,21,20,19,19,18,18,18,18,18,19,20,19,21,21,21,21,21,19,20,19,18,19,19,19,20,18,18,18,17,17,18,16,17,14,16,17,15,16,16,15,14,16,15,14,16,16,15,14,16,15,15,14,12,12,11,9,10,9,8,8,9,9,6,7,8,8,6,8,8,8,10,9,10,11,11,11,11,10,10,13,11,11,14,14,13,14,14,13,15,14,15,15,16,16,15,13,11,14,13,13,11,11,13,14,14,15,15,15,15,18,18,18,17,16,16,17,15,16,16,16,16,15,15,15,14,15,14,14,13,14,15,11,11,14,12,10,12,15,11,9,13,13,10,10,14,13,10,13,15,13,10,15,14,12,11,14,15,11,13,14,14,12,15,15,16,16,14,16,15,16,16,16,17,17,17,15,17,18,15,16,17,17,16,15,15,16,15,17,15,15,16,15,15,16,15,14,16,16,15,16,17,16,16,18,16,16,15,16,16,15,16,17,16,17,17,16,17,15,15,16,16,15,16,16,14,15,16,16,16,15,16,16,15,16,16,17,17,18,17,16,18,18,17,16,18,17,17,18,15,19,18,16,16,20,18,16,18,19,17,18,16,17,14,15,19,17,14,17,19,17,16,19,19,17,17,19,19,18,17,19,19,18,18,19,18,19,19,18,19,19,19,18,19,19,20,19,18,18,18,19,18,18,19,17,18,18,18,18,18,18,18,18,19,17,19,16,19,18,16,18,17,17,16,18,17,17,14,15,15,13,12,13,13,10,12,13,9,10,11,11,12,13,13,17,16,18,18,17,18,20,20,23,22,25,24,21,22,25,24,22,25,22,23,26,25,26,27,27,26,27,27,27,27,27,28,27,27,28,26,26,28,28,27,28,27,27,27,27,25,24,26,26],[29,28,28,28,28,28,29,28,28,28,27,28,28,27,27,27,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,29,29,28,28,28,29,28,28,28,28,28,28,27,27,27,27,27,27,27,25,26,26,25,23,23,22,21,19,17,17,16,15,16,15,14,14,13,13,11,10,13,12,13,12,13,13,13,14,14,11,14,13,13,14,14,13,12,14,15,13,13,13,13,13,12,15,14,13,11,15,14,13,13,14,16,16,16,14,16,15,15,14,14,15,13,13,15,12,11,12,13,11,11,13,10,10,11,9,8,10,9,9,9,9,10,10,11,11,11,11,12,12,12,12,13,15,12,15,15,14,14,15,15,16,16,16,14,14,14,16,14,13,16,15,14,14,15,11,12,14,12,9,11,12,9,8,7,8,7,7,7,5,6,7,6,7,8,7,7,8,8,10,10,8,10,10,11,11,11,12,13,12,12,11,12,11,11,11,12,9,9,11,11,10,9,10,11,7,9,11,10,7,9,10,9,8,11,10,11,12,13,11,11,10,9,11,10,10,9,8,8,8,6,6,7,6,5,5,4,3,3,2,1,0,1,3,4,6,5,5,5,6,7,6,7,8,8,10,9,9,10,9,9,11,11,9,11,10,10,10,8,8,10,8,6,8,9,7,6,8,7,7,7,9,9,10,11,11,9,11,11,10,12,11,10,10,11,12,11,11,14,14,14,13,13,13,14,13,12,11,14,15,13,15,16,14,16,15,15,17,18,19,18,19,20,20,21,21,23,22,24,24,25,25,25,25,26,27,26,27,28,27,28,28,28,27,27,27,26,27,26,28,27,28,27,28,28,29,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,28,29,29,29,28,28,29,28,28,28,28,26,26,26,24,24,23,22,23,21,19,20,18,18,17,15,15,16,16,15,13,15,12,15,14,14,17,16,15,17,19,17,17,17,19,18,19,20,19,19,19,17,17,15,15,16,16,17,17,17,18,20,19,20,19,18,18,18,17,16,17,18,16,16,17,16,15,15,13,14,12,12,10,12,12,11,11,12,10,10,11,12,10,11,13,12,11,13,13,13,12,12,11,9,8,8,8,6,7,6,7,5,5,7,7,5,5,8,7,7,7,8,8,7,8,9,8,7,10,11,11,11,12,12,11,11,12,11,11,13,13,14,13,12,11,11,12,11,12,12,11,13,13,14,13,14,13,14,16,16,14,15,15,14,15,15,14,14,15,14,13,12,13,13,13,13,13,11,12,13,9,9,10,9,8,9,10,10,7,9,9,9,8,9,10,9,10,10,10,9,10,10,9,9,9,10,10,9,11,11,10,12,10,12,12,12,13,13,13,13,13,12,13,14,13,14,15,14,14,16,15,16,14,13,15,14,15,15,14,16,15,15,16,15,15,15,15,15,14,15,15,15,15,15,15,15,15,14,14,14,15,15,15,15,15,15,12,13,14,13,11,13,13,11,12,13,12,10,13,12,11,10,12,14,14,13,13,14,12,13,13,13,14,14,14,13,15,12,15,13,13,13,17,15,13,15,15,14,15,14,14,12,14,16,14,11,13,16,13,13,15,16,13,14,16,15,15,15,15,16,16,16,16,17,16,15,16,17,16,16,15,16,16,16,16,16,15,14,15,14,16,16,14,15,16,15,16,14,15,16,15,17,14,16,13,16,15,13,14,14,13,12,13,12,11,10,10,10,10,10,9,9,9,9,9,8,9,7,10,11,12,13,16,15,15,18,16,19,21,21,23,22,25,24,20,22,25,23,22,25,23,23,27,25,26,27,27,27,27,27,27,28,27,27,27,27,28,25,26,26,28,27,27,26,26,27,27,25,25,26,27],[28,28,28,28,28,28,28,28,27,27,27,25,28,26,27,26,28,28,27,28,28,27,28,28,28,28,28,28,28,28,27,28,28,28,28,29,28,28,28,27,28,28,27,27,27,27,26,26,26,25,23,24,25,23,22,24,23,21,21,21,19,17,15,13,12,11,10,9,9,9,8,8,7,7,6,7,6,6,7,7,6,7,7,7,6,8,8,8,8,8,8,9,8,9,9,9,8,9,9,9,9,9,9,9,9,10,9,9,9,10,11,10,9,9,9,10,9,9,9,9,9,8,7,8,8,7,7,8,8,7,7,8,7,8,7,8,7,8,7,8,7,8,8,8,8,8,8,7,8,8,8,7,8,8,9,9,9,9,9,10,9,8,8,9,9,8,7,9,7,7,7,7,6,6,8,6,5,6,6,6,6,5,5,5,5,5,5,5,5,5,6,6,5,5,6,6,8,7,7,8,8,8,8,9,9,10,9,8,8,8,8,8,7,7,7,6,6,7,6,5,5,6,5,4,5,5,4,5,5,4,5,6,7,6,7,8,7,7,7,7,6,6,6,5,5,5,4,4,3,4,3,2,3,3,2,3,3,3,1,0,1,1,2,2,3,3,3,4,4,5,4,5,5,5,5,6,5,5,6,6,6,5,5,5,5,4,5,5,4,4,4,4,3,4,4,4,3,4,5,5,5,6,6,6,7,7,7,8,7,7,7,8,8,8,8,9,9,9,9,9,10,9,9,9,8,9,9,9,9,10,10,11,11,11,13,13,15,14,15,16,17,17,18,20,20,19,22,22,23,23,24,25,26,25,26,26,27,26,26,26,25,26,24,24,24,24,25,25,25,25,27,27,28,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,27,28,28,28,28,27,27,27,28,27,27,28,27,27,28,26,27,26,26,24,24,23,22,22,20,19,19,17,16,14,14,12,12,10,10,10,10,10,10,10,10,11,11,10,11,11,11,11,13,12,11,12,14,13,13,14,14,14,13,12,13,11,12,12,12,12,13,13,14,14,13,15,14,13,13,13,12,11,12,12,11,11,10,11,10,10,10,10,8,9,7,8,9,9,8,9,9,8,8,9,8,9,9,9,10,10,10,10,9,9,8,7,7,6,6,5,4,5,6,4,3,4,5,4,4,5,4,4,5,6,6,4,6,6,5,6,6,6,6,7,7,7,8,7,7,8,8,9,9,10,9,9,8,7,7,7,8,7,6,8,9,9,10,9,9,10,11,11,10,11,10,10,9,9,10,9,8,9,9,7,8,8,8,7,7,6,7,6,5,5,6,5,4,6,5,5,6,7,6,6,6,6,7,6,8,7,8,7,6,6,6,6,6,7,6,7,7,7,7,7,7,8,8,7,8,8,9,8,8,8,9,9,8,9,9,9,8,9,9,9,8,8,9,9,9,9,9,9,8,9,9,10,9,10,10,9,10,11,10,11,11,11,10,10,11,10,10,10,10,10,9,9,8,9,7,7,7,8,7,7,7,6,7,7,7,7,8,7,7,7,8,9,9,9,9,9,8,9,10,8,9,9,10,9,9,10,10,9,8,9,9,9,9,9,10,9,10,8,9,8,7,9,8,9,8,9,9,9,9,10,9,9,10,10,11,9,10,11,11,10,10,10,11,9,11,11,9,10,10,10,10,11,10,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,12,10,10,10,11,9,9,10,9,9,8,8,9,8,7,8,8,7,7,7,8,6,7,8,6,6,6,8,9,10,11,12,12,13,13,13,15,17,17,20,20,22,21,19,20,23,22,19,22,20,21,24,23,24,25,25,25,25,25,26,26,26,26,26,25,26,25,26,25,25,26,26,25,24,26,26,24,23,26,26],[28,28,28,28,28,28,28,28,28,27,27,27,27,26,27,27,27,28,27,27,27,27,28,28,27,27,28,27,28,27,26,28,28,28,27,28,27,28,28,27,28,27,27,27,27,27,25,25,25,24,23,23,24,23,22,23,22,21,21,20,18,16,14,11,9,9,7,6,6,6,5,5,5,4,4,4,5,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,7,6,5,5,5,6,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,4,4,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,3,4,5,5,5,4,5,5,5,5,5,5,6,5,5,5,4,4,4,3,3,3,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,4,5,5,5,5,4,5,4,4,4,4,4,3,3,3,3,2,3,2,2,3,2,2,3,3,2,1,1,0,1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,2,4,4,4,4,4,4,5,5,4,5,5,5,4,5,6,5,5,6,6,7,6,6,7,6,6,6,6,7,7,7,7,7,8,8,8,8,10,11,13,13,14,16,17,16,17,20,18,18,21,21,21,22,23,25,24,23,26,25,26,25,26,24,24,25,23,23,24,23,25,24,24,25,26,25,27,26,27,27,27,26,27,27,27,27,27,27,27,28,27,28,27,27,28,27,27,27,27,27,27,28,26,28,27,26,27,25,26,25,25,24,24,23,21,22,18,18,18,16,15,13,11,10,9,8,7,7,7,7,6,7,7,7,7,7,8,8,8,8,10,9,9,9,10,10,10,11,11,11,12,10,11,9,9,9,9,9,10,10,12,11,10,12,11,10,9,9,9,9,9,8,8,8,7,7,7,7,7,6,6,6,5,6,5,5,5,6,5,5,5,6,5,5,6,6,7,7,7,7,7,6,5,5,4,4,3,3,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,2,3,4,3,3,4,4,3,4,4,4,4,4,5,5,5,6,7,7,7,6,5,5,4,4,4,4,4,4,5,5,5,6,6,6,7,8,7,7,6,6,6,5,5,5,5,4,5,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,5,5,5,5,5,6,5,5,6,6,6,5,6,5,5,5,5,5,5,5,5,4,4,4,5,5,5,5,6,6,6,7,7,6,8,8,8,7,6,7,7,7,7,6,7,6,6,5,5,4,5,5,5,4,5,5,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,5,6,6,6,6,6,6,6,6,6,7,6,5,6,6,6,6,6,6,6,6,6,6,5,5,6,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,7,8,8,7,7,7,7,7,7,7,6,6,7,7,7,7,7,7,7,7,7,8,8,8,7,8,8,7,8,7,7,7,6,6,6,6,5,5,5,5,4,4,5,5,4,4,4,3,4,4,3,3,4,6,7,8,9,10,11,10,11,12,14,15,17,18,18,21,20,19,19,21,21,18,22,19,21,22,21,23,23,24,23,24,23,24,24,24,24,23,23,25,22,23,24,23,23,25,24,22,24,24,23,22,24,24],[28,28,28,28,28,28,28,27,28,27,27,26,26,26,26,25,26,26,26,26,26,26,26,26,26,25,26,26,26,25,25,26,26,27,25,26,25,26,26,25,26,25,25,25,25,24,23,22,23,22,22,22,22,20,19,21,19,18,17,17,15,13,11,8,7,6,5,4,4,4,3,3,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,2,2,2,3,3,2,2,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,7,10,10,10,12,13,14,12,14,16,16,16,18,18,18,19,19,20,22,20,22,21,23,22,23,22,21,23,22,21,22,22,23,23,22,22,25,24,26,24,25,25,25,25,25,25,25,25,25,25,26,26,25,26,26,25,26,25,26,25,26,26,26,26,25,25,25,25,26,24,23,24,23,22,22,20,19,19,17,16,16,14,12,11,9,7,6,6,5,5,5,5,4,5,4,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,8,7,7,6,6,6,6,7,7,8,8,8,8,8,8,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,5,5,5,5,5,4,4,3,3,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,3,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,5,5,5,5,4,4,4,3,3,3,2,2,3,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,4,3,3,4,4,3,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,4,4,4,4,4,5,5,5,5,5,5,4,5,5,4,4,5,4,4,5,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,4,6,7,7,9,10,10,11,11,13,14,17,18,17,20,19,19,19,20,20,18,21,20,21,22,21,24,24,24,23,24,23,24,24,24,25,24,23,25,24,23,24,24,25,23,24,23,23,25,23,22,24,25],[28,28,28,28,28,28,28,28,28,27,27,26,27,25,26,25,26,27,26,26,26,26,26,26,25,26,26,26,26,26,25,26,26,27,25,26,25,26,26,25,26,26,25,26,25,25,24,22,24,22,22,22,22,20,19,20,19,18,18,18,15,14,11,8,7,6,5,4,4,3,3,3,3,2,2,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,3,3,4,3,4,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,2,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,1,1,2,2,2,2,3,3,2,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,1,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,4,4,4,4,4,4,5,5,5,6,6,7,9,10,10,12,13,15,14,15,16,17,15,17,18,18,18,19,21,21,21,22,22,23,23,23,22,21,23,20,22,22,21,24,22,23,23,24,25,26,24,25,26,26,26,26,26,26,26,26,26,26,26,26,26,25,25,26,26,26,26,26,24,25,26,25,25,25,24,26,24,23,24,23,23,22,21,21,20,18,17,16,15,12,11,8,7,7,5,5,5,5,5,4,5,4,5,5,5,5,5,6,6,7,6,6,7,7,7,8,8,8,8,8,8,8,7,7,7,7,7,7,7,8,8,7,8,8,7,7,7,7,6,6,6,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,5,5,5,5,5,5,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,4,5,5,5,4,3,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,4,5,5,5,4,4,5,5,5,5,4,4,4,3,3,3,2,3,3,3,2,2,2,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,4,4,3,3,4,4,3,4,4,3,4,3,4,3,3,3,3,3,3,4,3,3,4,4,3,3,4,4,4,4,5,5,6,5,5,5,5,5,5,5,4,4,5,4,4,5,4,4,4,4,4,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,4,6,7,7,9,9,10,11,11,15,14,17,18,19,20,20,18,18,20,20,19,22,20,22,22,21,24,23,23,22,23,22,24,23,22,24,24,23,23,23,24,24,23,23,23,23,22,24,24,22,23,24,24],[29,28,28,28,29,28,28,28,27,27,27,25,27,25,26,26,27,27,26,26,27,26,26,27,26,27,27,27,27,26,26,27,27,27,26,27,26,26,26,26,26,26,25,26,25,25,24,23,24,23,21,21,21,20,18,20,19,18,17,17,14,13,10,8,7,6,4,4,4,4,3,3,2,2,2,2,3,2,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,3,4,3,2,2,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,4,4,4,4,4,4,5,6,6,7,9,9,9,12,13,14,12,13,15,15,15,16,17,17,18,18,21,21,20,22,22,23,23,23,22,21,23,21,22,22,22,24,22,23,22,25,25,27,25,25,25,26,26,26,26,26,26,26,26,26,27,26,26,26,26,26,27,26,26,26,25,25,26,27,26,25,25,27,24,24,24,24,22,22,21,20,20,18,17,17,15,12,10,8,7,6,5,5,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,8,7,7,6,6,6,6,6,7,7,7,7,7,7,7,7,6,5,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,5,5,5,5,4,5,5,5,4,4,4,4,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,4,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,2,2,3,4,6,6,7,8,9,9,10,10,13,14,16,16,17,19,21,18,18,19,21,18,23,18,22,21,22,24,23,23,22,23,22,24,23,23,24,22,23,23,22,23,22,22,23,22,24,22,23,24,23,22,23,24],[28,28,27,27,27,27,27,27,27,26,26,24,25,24,25,25,25,26,25,26,26,25,26,26,26,26,26,26,26,25,25,26,26,27,25,26,26,26,26,25,26,25,24,25,24,24,23,22,23,22,21,20,21,20,18,19,18,17,17,16,13,12,10,7,6,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,1,2,2,3,3,3,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,3,4,2,2,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,4,4,3,4,4,3,3,3,4,4,3,4,4,4,5,5,6,8,9,10,10,12,12,13,11,13,14,14,14,15,16,16,16,16,19,20,19,20,21,22,22,22,22,21,22,20,21,22,21,22,21,21,21,25,24,26,24,24,24,25,24,24,25,25,25,25,25,24,25,25,26,25,25,26,25,25,25,25,25,25,25,25,24,25,24,25,24,24,24,24,22,21,21,19,19,17,16,15,14,11,11,8,6,6,5,5,4,5,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,7,7,7,6,7,6,6,6,5,6,6,6,7,6,7,7,7,7,6,7,6,6,6,6,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,1,1,2,2,1,1,2,2,1,2,2,2,2,2,3,3,3,3,4,5,5,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,3,2,2,2,3,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,5,5,5,4,4,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,4,5,6,6,8,8,9,10,10,14,13,17,17,17,19,19,19,17,18,19,18,21,19,19,21,21,22,23,23,22,23,22,24,22,22,24,23,22,23,22,22,22,21,22,22,23,21,22,23,22,21,23,23],[28,27,28,28,27,28,27,27,27,26,26,25,25,25,25,24,25,26,25,25,26,25,25,25,25,26,25,26,26,25,24,25,25,26,25,25,25,26,25,25,26,25,24,25,24,24,22,22,22,22,20,20,20,18,18,19,18,16,17,16,13,11,9,7,6,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,2,2,3,3,2,2,3,3,2,2,2,2,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,2,3,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,4,4,5,5,5,6,8,8,9,10,12,13,11,13,15,14,14,16,17,17,17,18,19,20,20,20,21,22,23,23,22,21,24,21,21,22,22,22,22,23,22,25,23,26,24,25,25,25,25,24,25,25,25,25,25,25,26,26,26,25,25,26,25,26,26,25,25,25,25,25,25,25,25,25,23,23,23,23,22,21,19,19,18,16,15,15,13,11,9,7,6,5,5,4,3,4,4,3,4,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,6,6,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,2,3,4,5,5,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,3,3,3,3,4,4,3,4,4,4,4,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,3,2,2,3,3,2,3,2,3,3,2,3,3,3,2,3,3,3,3,2,3,2,2,2,2,2,2,3,2,2,3,3,3,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,6,6,8,9,10,10,10,13,14,16,18,18,19,20,18,18,19,19,18,21,21,21,22,21,24,24,23,23,23,24,24,23,23,24,23,23,25,24,23,24,23,24,22,23,23,22,24,24,22,24,24],[29,28,28,29,28,28,28,28,28,27,27,26,27,26,26,25,26,27,25,25,26,25,26,26,25,26,26,26,27,26,25,26,26,26,25,26,25,25,25,25,25,25,24,24,24,24,22,21,22,21,20,20,20,19,17,19,17,16,15,15,13,11,9,6,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,1,2,2,3,3,3,2,3,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,3,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,4,4,4,4,4,6,7,8,9,11,12,13,11,12,14,14,13,15,16,16,16,16,19,20,18,20,20,21,21,22,21,21,22,20,20,21,21,22,21,21,22,24,23,26,23,24,24,24,25,24,25,25,25,25,25,24,24,24,25,25,25,26,25,26,25,25,24,25,25,24,25,25,23,25,22,22,23,23,23,22,19,20,19,17,15,15,13,11,9,8,6,5,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,6,6,5,5,5,5,5,6,5,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,3,4,5,5,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,3,2,2,2,2,2,3,3,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,4,4,3,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,3,2,2,3,3,2,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,6,6,8,9,9,10,10,13,13,16,16,17,20,21,18,18,18,20,18,21,19,22,21,21,24,24,23,22,23,22,24,23,22,24,23,23,24,21,22,24,21,23,22,24,22,23,24,22,22,23,23],[28,27,27,27,27,27,27,27,26,26,25,24,26,25,25,25,25,26,24,26,26,24,25,26,25,26,25,26,26,25,25,26,26,27,25,26,25,26,26,26,26,25,24,25,25,24,23,21,22,21,20,19,20,18,17,18,18,15,16,15,13,11,9,7,6,6,4,4,4,3,3,3,3,2,2,2,3,3,3,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,4,3,4,4,4,3,3,4,4,4,4,4,4,5,5,5,6,9,9,9,11,11,12,11,11,13,13,13,14,14,15,15,16,18,19,18,20,21,21,20,22,21,20,21,20,19,20,21,22,20,20,21,23,22,24,23,24,24,24,24,25,24,24,25,24,24,24,24,24,24,25,25,25,26,25,25,25,24,24,24,24,25,24,25,25,23,23,23,22,21,21,19,19,18,16,15,15,12,11,10,8,7,6,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,6,6,5,6,6,6,6,6,7,7,6,7,7,6,6,5,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,3,4,5,5,6,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,5,5,4,4,4,4,4,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,4,5,7,7,9,9,10,10,10,14,14,16,16,15,17,18,17,17,18,20,17,20,18,20,20,20,22,25,21,21,23,22,22,22,22,23,20,20,23,21,21,20,21,23,22,22,21,22,24,22,20,23,23],[28,28,28,28,28,28,27,27,27,27,26,25,26,24,25,24,25,26,25,26,26,25,26,26,25,26,26,26,26,25,25,26,27,27,26,27,26,26,26,26,26,25,26,26,25,24,24,23,23,22,21,21,21,19,17,19,18,17,16,15,13,12,9,7,6,5,4,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,4,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,4,4,3,3,3,4,4,3,4,4,4,5,5,5,7,8,9,9,11,12,13,11,13,14,14,14,16,17,17,17,18,20,20,20,22,21,23,23,23,23,21,23,22,21,22,22,22,22,22,21,25,24,26,24,25,25,25,26,25,25,25,25,25,25,26,26,26,26,26,26,27,25,26,25,26,25,25,25,26,25,26,26,26,24,24,24,24,23,22,21,20,20,18,17,16,15,11,10,8,6,6,5,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,6,6,6,7,7,7,7,7,6,6,6,5,5,5,6,6,6,7,7,6,7,6,7,6,5,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,4,4,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,3,5,5,5,4,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,3,2,2,2,2,2,3,3,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,3,4,4,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,4,5,6,6,8,9,9,10,11,13,14,15,17,17,19,20,19,17,18,19,19,21,20,21,22,21,24,25,24,23,23,23,25,23,24,25,24,23,25,23,24,24,24,25,23,24,23,23,24,24,22,24,25],[29,28,28,28,28,28,28,28,27,27,27,26,27,25,26,25,26,27,25,26,26,24,26,26,25,26,26,25,26,26,24,26,26,26,26,26,26,26,26,26,26,26,26,25,25,24,23,22,23,22,21,20,20,19,18,18,17,16,16,16,13,11,9,7,6,5,4,4,4,3,3,3,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,2,2,3,3,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,6,8,9,9,11,13,12,11,12,13,14,13,15,16,15,16,17,18,20,19,20,21,22,22,22,21,21,22,20,21,21,21,22,21,22,22,24,23,26,23,24,24,25,25,24,25,25,25,25,25,24,25,25,25,25,25,26,25,26,25,25,24,24,25,24,24,25,24,25,22,22,23,23,22,21,19,19,19,17,15,15,14,11,10,8,7,6,5,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,6,7,7,7,7,7,8,7,7,6,6,6,6,6,7,6,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,2,1,2,2,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,5,5,5,4,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,2,2,3,2,3,2,3,3,3,3,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,5,5,4,4,5,4,4,4,4,3,4,4,4,3,4,4,4,3,4,4,4,4,5,4,4,4,4,5,5,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,4,5,7,6,8,9,10,11,11,14,15,17,17,18,20,21,19,18,20,20,20,22,20,23,22,22,25,24,24,24,24,23,26,24,24,26,24,24,25,23,25,25,24,25,25,24,23,25,25,24,23,26,25],[28,28,28,28,28,27,28,28,26,26,26,24,27,24,26,24,26,27,24,27,26,25,27,26,25,27,27,26,27,26,25,26,27,27,26,27,26,27,26,26,26,26,26,25,25,24,23,21,22,21,20,20,20,19,17,18,17,16,15,15,13,11,9,7,6,6,5,4,4,4,3,3,3,2,3,3,3,3,3,3,2,2,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,3,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,1,1,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,5,4,4,5,5,5,6,6,8,8,9,9,11,11,12,11,12,13,13,13,14,15,15,15,16,17,19,18,20,21,22,21,22,21,20,22,20,20,21,21,22,21,22,22,25,24,26,24,25,25,25,25,26,25,25,25,25,25,25,25,25,26,25,26,26,26,26,25,26,25,26,26,25,25,25,24,26,24,24,24,24,24,22,21,20,20,19,17,16,15,11,11,8,7,6,5,5,5,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,7,7,7,7,7,6,7,7,7,7,7,7,7,7,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,4,4,4,3,4,4,3,4,4,4,4,4,5,5,5,6,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,1,1,2,2,2,2,2,3,3,3,4,6,6,6,4,3,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,4,4,5,4,4,5,5,4,4,4,4,4,3,3,3,2,2,3,2,2,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,5,5,4,5,5,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,6,7,7,9,9,10,10,10,13,14,16,14,16,18,19,17,18,18,20,18,23,19,20,21,19,23,24,21,22,24,22,24,24,23,23,22,22,26,22,22,22,22,24,23,24,22,23,25,24,23,24,24],[27,27,27,27,27,27,27,27,26,26,25,24,26,24,25,24,25,26,24,25,25,23,25,24,24,25,25,25,26,24,24,24,25,26,25,25,25,25,25,25,25,25,23,24,24,23,22,20,22,21,19,19,19,17,15,17,17,15,16,15,12,11,9,7,6,6,5,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,1,2,2,3,3,2,2,3,3,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,4,4,4,5,5,4,4,5,5,5,6,6,8,8,9,9,10,11,12,11,12,13,13,13,14,15,16,15,15,18,18,18,19,20,21,20,21,21,19,21,21,19,21,21,22,20,21,21,24,22,25,23,23,24,24,25,25,25,25,25,25,25,25,26,25,25,25,25,26,26,25,24,24,24,24,24,25,25,24,24,25,23,23,22,22,22,20,19,19,18,18,16,15,14,11,11,9,7,6,6,5,5,5,5,4,5,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,7,7,8,8,7,8,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,5,5,5,5,5,5,5,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,3,3,3,4,5,5,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,5,4,5,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,4,3,3,3,3,3,3,4,3,3,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,5,5,7,6,8,9,10,9,10,13,14,15,15,17,18,17,17,16,18,18,16,20,18,18,20,20,23,23,21,22,23,21,24,22,23,23,21,22,23,22,21,22,23,23,23,22,22,23,24,22,20,22,23],[28,28,27,28,27,27,28,27,27,27,26,25,26,25,26,25,26,26,24,26,25,23,25,25,24,25,26,25,26,25,23,25,26,26,25,26,25,26,26,26,26,26,25,25,25,25,24,22,23,22,21,21,20,18,17,18,17,16,16,16,13,12,9,7,6,5,5,4,4,3,3,3,3,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,3,3,3,3,2,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,3,3,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,5,5,5,5,6,7,8,9,9,12,13,13,11,13,14,14,14,16,16,16,16,18,19,20,20,21,22,24,22,23,23,21,23,21,21,22,22,22,22,23,22,25,24,26,24,24,25,25,25,24,25,25,25,25,25,25,25,25,26,26,26,27,26,26,26,26,25,25,26,25,25,26,24,26,23,23,24,23,22,22,20,20,20,18,16,16,14,12,11,8,7,6,5,5,4,5,5,4,5,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,8,7,7,6,6,6,6,7,7,7,8,8,7,7,7,7,6,6,6,6,5,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,6,6,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,3,3,4,5,5,5,4,2,1,1,1,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,5,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,7,6,8,10,10,10,10,13,14,16,17,17,20,21,19,18,19,20,19,22,19,22,21,22,24,24,23,23,24,23,24,23,24,24,23,23,25,22,23,24,25,25,24,23,23,24,25,24,22,23,24],[27,28,28,28,28,27,28,28,26,27,26,25,26,25,27,25,27,27,25,27,26,24,27,26,24,26,26,25,27,27,25,27,27,27,27,27,27,27,27,27,27,27,27,26,27,26,26,24,25,23,21,21,22,21,19,20,19,18,19,18,16,13,11,9,7,7,6,5,5,4,4,4,4,3,3,3,4,3,4,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,6,6,6,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,4,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,5,6,5,5,4,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,6,6,5,6,6,5,5,5,5,6,6,5,6,6,7,7,7,8,9,10,11,12,14,14,12,14,16,15,15,17,17,17,18,19,20,21,20,21,22,24,23,24,24,23,25,22,21,23,23,24,24,24,24,26,25,27,26,26,26,26,26,26,26,27,27,27,26,26,27,27,27,26,27,27,27,27,27,26,26,27,27,27,27,27,25,27,24,25,25,24,23,23,21,22,20,20,18,17,16,13,12,10,9,8,6,6,6,6,6,6,6,5,6,6,6,7,7,7,7,8,8,8,8,9,9,9,8,9,10,10,9,9,8,7,8,8,8,9,8,10,10,8,9,9,9,8,7,8,8,7,7,7,7,6,7,6,6,5,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,6,6,7,7,7,6,6,5,5,4,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,6,6,6,5,3,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,3,4,3,3,4,4,4,3,3,3,4,4,4,4,4,4,5,4,5,5,4,5,5,6,5,5,5,6,6,5,5,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,6,6,6,6,6,6,6,5,6,5,5,6,6,5,5,6,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,4,5,5,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,3,4,4,4,3,4,5,7,8,7,9,11,11,11,12,15,16,17,17,20,21,21,20,17,21,21,20,23,19,23,22,23,25,24,23,25,25,23,26,25,24,24,25,25,25,23,23,25,25,25,26,24,25,25,26,24,23,25,24],[28,28,28,28,28,27,28,28,26,26,26,24,27,24,26,25,26,27,25,27,26,25,26,26,25,26,27,25,27,26,25,27,27,28,27,27,26,27,27,27,27,26,26,26,26,26,24,22,23,23,20,19,21,19,17,18,18,17,18,16,15,12,11,9,8,8,7,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,5,4,4,5,5,4,5,5,5,6,6,6,5,6,6,6,6,7,7,8,7,6,6,6,7,7,7,7,6,7,6,5,6,5,5,5,5,5,5,5,5,4,4,4,5,4,4,4,4,4,4,5,5,4,4,5,5,4,5,5,4,5,5,5,5,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,4,3,3,4,3,3,3,4,4,3,3,3,4,4,3,3,4,3,4,3,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,5,5,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,3,4,4,4,4,4,5,4,3,3,3,3,3,3,2,2,2,2,1,1,2,1,1,0,1,3,2,2,2,2,3,2,3,3,2,2,3,3,2,3,3,4,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,6,6,6,7,6,7,6,6,7,7,7,6,5,6,7,6,6,7,7,7,7,8,9,10,10,11,12,13,14,12,13,14,15,14,15,16,17,17,18,20,21,21,22,22,23,22,23,22,21,23,21,21,22,22,23,21,22,24,24,24,26,24,25,25,25,26,26,26,25,25,25,26,26,26,26,26,26,26,27,26,27,25,26,25,25,26,25,26,26,25,26,24,25,25,23,23,22,22,22,20,19,17,17,15,13,12,11,10,8,8,7,7,7,7,6,7,6,7,7,7,7,8,8,8,8,8,9,9,9,10,9,9,9,10,10,9,9,9,8,8,8,8,9,9,10,11,9,10,10,9,8,9,9,8,8,8,8,7,7,7,7,7,6,7,6,6,5,6,6,5,5,6,6,6,6,6,6,6,7,7,8,8,8,7,7,7,6,6,5,5,4,4,4,4,4,4,3,3,4,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,4,4,5,5,7,6,6,5,4,2,2,2,3,3,3,4,4,4,4,5,5,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,4,4,5,5,4,4,4,5,5,5,5,4,5,5,5,5,5,5,6,6,6,7,7,6,6,7,7,6,6,7,7,6,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,5,5,4,4,5,4,4,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,4,5,5,5,5,6,5,6,6,6,7,6,7,6,6,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,7,7,7,6,7,7,7,7,7,7,6,6,5,6,6,5,5,5,5,5,4,5,5,4,5,5,5,4,5,5,4,5,5,5,4,5,7,7,9,9,10,11,13,12,13,14,15,16,16,17,20,19,19,18,19,20,19,24,19,21,21,19,24,23,22,23,25,23,24,26,25,23,24,24,25,24,22,23,24,25,25,23,24,23,25,24,23,25,26],[27,27,27,27,27,27,28,27,26,27,25,25,26,26,26,26,26,27,25,26,26,26,26,26,25,26,26,26,26,26,25,27,28,27,26,28,27,27,28,27,28,27,26,26,26,26,24,21,24,23,20,21,21,19,18,19,18,17,17,17,15,13,11,10,9,8,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,5,5,5,4,5,5,5,5,5,5,6,5,5,6,6,5,5,7,6,6,7,7,7,7,7,8,8,8,8,7,7,7,8,8,7,8,7,7,7,6,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,5,5,5,5,5,6,5,6,6,5,7,6,6,6,7,6,7,7,6,7,7,7,7,7,6,7,7,6,7,6,7,6,7,6,6,7,6,6,6,6,7,6,5,6,5,5,5,4,4,4,4,4,3,3,3,3,4,4,3,3,4,4,3,3,4,4,4,4,3,3,4,4,4,4,4,3,4,4,4,4,6,5,5,5,5,6,6,6,5,6,6,5,6,6,7,7,8,7,7,7,7,7,7,7,7,6,6,6,6,5,6,5,5,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,1,1,1,0,1,2,2,2,2,3,3,3,4,3,4,4,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,7,6,7,7,7,7,7,8,8,8,8,8,8,8,8,8,7,8,8,7,8,8,8,9,8,8,10,10,11,11,12,13,13,13,14,14,16,16,17,18,18,17,19,21,20,20,22,21,23,22,23,22,21,23,23,21,22,22,22,22,22,23,25,24,26,24,25,26,25,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,26,27,26,26,26,26,26,27,25,27,25,24,25,24,24,23,23,22,20,19,19,18,16,14,14,12,10,10,9,8,8,8,8,8,8,7,8,8,8,9,9,9,9,10,10,10,10,11,11,11,12,12,12,12,11,11,9,9,9,10,10,11,12,12,13,12,12,12,11,10,10,10,9,10,10,9,9,8,9,8,8,8,8,6,6,6,6,7,6,6,7,6,6,6,7,7,7,7,7,8,8,9,8,8,7,6,6,6,6,6,5,6,5,5,5,5,4,4,4,4,4,4,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,4,4,4,4,5,5,6,6,7,5,4,3,3,3,4,3,4,4,4,4,4,5,5,5,6,6,6,6,5,6,5,6,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,4,4,5,4,4,5,5,4,4,5,5,5,5,5,6,5,6,5,5,5,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,6,5,6,6,6,6,5,6,6,6,6,6,6,7,7,6,7,7,6,6,6,7,7,7,7,7,7,7,7,7,7,7,8,8,7,7,6,7,6,6,5,5,6,6,5,5,6,5,4,5,5,5,5,5,5,4,5,5,5,5,5,5,5,6,5,4,5,5,5,5,5,5,6,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,7,8,7,7,8,7,7,7,7,7,6,7,7,7,7,8,7,7,7,8,7,7,7,7,7,8,8,8,8,7,8,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,8,9,9,10,11,12,12,13,14,15,17,18,19,21,21,21,18,20,20,20,22,20,21,22,21,24,23,24,23,23,22,25,25,23,24,24,24,23,22,23,25,24,23,25,24,23,25,26,23,23,25,25],[28,28,28,28,28,28,29,28,26,26,26,24,26,25,26,26,26,27,24,27,26,25,26,26,25,26,27,26,27,27,26,27,27,28,26,27,27,27,27,26,27,26,26,26,26,26,25,23,24,23,21,22,22,20,19,21,20,18,19,19,17,14,13,11,9,9,9,7,8,7,7,7,7,6,6,7,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,6,5,5,5,6,5,5,6,6,6,6,7,6,6,7,7,8,8,8,7,6,7,8,7,8,7,7,7,7,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,5,5,4,5,6,5,6,6,6,6,6,6,7,6,7,7,7,7,7,7,7,7,6,6,6,6,7,6,6,6,6,6,5,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,3,4,4,3,3,4,4,4,4,3,4,4,4,3,3,4,3,3,4,4,4,5,4,5,5,5,5,6,6,5,5,6,6,6,7,7,8,8,7,7,7,7,6,7,7,6,6,6,6,6,6,6,5,5,5,4,5,4,5,5,5,4,4,4,4,4,4,3,4,3,3,3,2,2,2,2,2,1,0,1,2,2,2,4,3,5,4,4,4,5,5,4,5,5,5,5,5,5,5,6,5,6,5,6,7,6,7,7,7,7,7,8,7,8,8,8,8,8,8,8,8,8,8,8,8,8,7,8,9,8,8,9,9,9,9,9,10,11,12,12,12,13,13,14,15,15,17,16,18,19,20,19,21,22,23,22,24,24,24,25,24,24,22,24,24,24,24,24,25,24,23,24,26,26,28,26,26,26,26,27,27,26,27,26,27,26,27,27,27,26,26,27,28,27,27,26,26,27,27,28,27,27,26,26,27,27,26,27,26,25,25,24,24,22,22,21,20,18,16,15,13,12,10,9,9,9,8,9,8,8,8,8,8,9,9,9,9,10,11,10,9,10,12,11,11,12,12,12,12,11,11,10,9,10,11,10,11,12,13,13,13,12,12,11,11,11,10,10,10,10,10,9,9,9,9,8,9,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,9,9,8,8,8,7,7,7,6,5,5,5,6,5,4,4,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,6,7,7,5,4,3,3,3,4,3,3,4,4,5,4,5,5,6,6,6,6,7,5,5,6,6,5,5,6,5,5,5,6,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,6,5,5,5,5,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,6,5,5,6,5,6,6,6,6,6,6,6,7,6,6,6,6,6,6,7,6,7,7,7,6,8,7,7,7,7,8,7,7,7,8,7,8,7,7,7,7,6,7,5,5,6,6,5,5,6,5,5,5,6,5,5,6,6,5,6,6,7,6,6,5,5,6,6,5,5,6,5,5,6,6,7,6,6,6,6,6,6,7,6,6,7,7,7,6,6,7,7,6,7,7,7,6,7,7,6,6,7,7,7,7,7,8,8,8,8,8,7,8,8,8,7,8,8,8,8,9,8,8,8,8,8,8,8,8,8,8,9,8,8,8,7,7,8,8,7,7,6,7,7,6,6,6,6,5,6,6,6,5,5,6,6,5,6,6,5,5,6,6,5,6,7,8,10,9,11,12,13,12,13,15,16,17,17,17,21,21,20,20,22,20,19,23,20,21,24,22,24,26,24,24,25,23,24,25,26,25,24,24,26,24,25,26,26,25,25,24,25,25,26,26,24,26,27],[28,28,28,28,28,28,28,28,27,27,26,26,27,25,25,26,26,26,26,26,26,25,26,26,26,27,27,26,27,26,26,27,28,28,26,27,27,28,27,27,28,27,26,27,26,26,26,24,24,23,22,22,22,20,19,21,19,19,19,18,16,14,13,10,9,8,7,6,6,6,5,6,5,5,5,5,4,5,4,4,4,4,4,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,6,5,5,5,6,6,6,6,6,5,6,5,5,5,5,5,5,4,4,4,4,4,4,4,5,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,5,6,5,6,5,5,5,5,5,4,5,5,5,4,5,5,4,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,2,2,2,3,3,3,4,4,3,3,3,3,4,3,4,3,3,3,3,3,3,2,3,3,2,2,3,4,3,3,4,3,4,4,4,5,4,4,4,4,5,6,6,7,7,6,6,7,6,5,6,5,5,5,5,5,5,5,5,4,4,4,4,5,5,5,5,4,3,3,4,4,3,3,3,3,2,2,2,2,2,1,2,2,1,1,0,1,1,1,2,2,3,2,2,3,3,3,3,4,4,4,5,4,4,4,5,5,5,5,5,6,5,6,6,6,6,7,6,6,7,7,7,7,7,7,7,7,8,7,7,7,7,7,7,8,7,7,8,8,8,9,9,10,12,13,11,13,14,14,14,15,16,17,16,17,18,19,19,20,22,23,23,24,24,25,24,25,24,22,25,24,23,25,25,25,25,25,24,26,27,28,26,27,27,27,28,27,27,27,28,27,27,27,28,28,27,27,27,29,28,28,28,27,27,28,27,27,27,27,27,27,25,26,26,25,25,24,23,22,22,21,20,19,18,14,14,12,10,9,8,8,8,8,8,7,8,8,8,8,8,9,9,9,9,10,9,9,10,11,10,11,12,12,11,11,10,11,9,9,10,10,10,10,12,12,12,12,12,12,11,11,11,10,9,10,10,9,9,9,9,8,8,8,7,7,6,7,7,7,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,7,6,6,6,6,5,5,5,5,4,4,4,4,4,4,3,4,3,3,3,3,3,3,4,3,4,3,3,3,3,3,4,3,3,4,4,5,5,6,7,7,7,5,4,3,2,2,3,2,2,3,3,3,3,4,4,4,5,5,5,5,4,4,4,4,4,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,5,6,6,6,5,5,5,5,4,5,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,5,5,4,4,4,5,5,4,4,5,5,5,5,6,5,5,6,6,6,5,5,6,7,6,7,6,6,6,6,5,5,4,4,5,5,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,6,6,5,6,6,6,5,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,5,5,6,6,6,6,6,6,7,6,6,7,6,7,6,7,7,7,7,7,8,8,7,7,7,7,7,7,8,7,7,7,8,7,7,8,7,7,8,8,7,8,7,8,8,8,8,7,7,8,7,7,7,6,7,7,6,6,6,6,5,5,6,6,5,5,5,5,5,5,6,5,5,5,5,5,5,7,8,9,8,10,12,11,11,13,13,15,17,16,18,20,20,20,18,20,20,19,23,20,21,22,21,24,24,23,24,25,23,25,24,24,25,24,25,25,24,23,26,25,24,25,23,24,24,26,24,23,25,26],[29,28,28,29,28,28,28,28,28,27,27,26,28,27,27,26,27,28,26,27,28,25,27,27,26,27,27,26,27,27,26,27,28,28,27,28,27,28,28,27,28,26,26,26,26,25,24,22,24,21,20,20,21,19,17,19,18,17,16,16,13,12,10,9,8,7,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,5,5,5,6,5,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,5,4,3,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,4,5,4,4,4,5,5,4,4,5,4,4,5,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,3,3,3,2,3,3,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,6,6,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,5,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,2,1,1,0,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,6,6,7,6,7,7,7,7,7,7,8,9,10,11,10,12,13,13,12,13,14,14,15,16,16,17,17,17,19,21,20,22,22,23,23,24,22,21,23,23,21,22,22,22,23,22,23,24,24,26,24,25,26,25,26,26,26,26,26,26,26,26,26,27,27,27,26,27,26,27,26,26,25,26,26,26,26,26,25,26,24,24,25,24,24,22,22,21,20,20,18,18,16,13,13,11,10,8,8,7,7,7,7,7,7,8,7,8,7,7,8,8,8,9,8,9,9,10,10,10,10,10,10,10,10,10,9,9,9,9,9,10,10,11,11,11,11,10,10,9,10,9,8,9,9,8,8,8,8,7,7,7,7,7,6,7,6,6,7,6,6,6,6,6,6,6,6,7,7,7,8,8,8,7,7,6,6,5,5,5,5,4,5,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,6,7,6,4,3,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,6,6,6,5,5,5,4,4,4,4,4,4,4,4,5,4,4,5,5,5,4,5,5,5,5,6,5,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,6,6,6,6,6,6,7,7,6,6,7,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,7,7,6,6,6,5,6,5,5,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,6,7,8,8,10,11,10,11,12,13,14,16,17,18,20,19,20,18,20,19,18,22,19,20,22,21,24,23,23,24,24,22,25,24,23,25,24,24,24,22,24,25,24,23,25,25,24,25,25,23,23,24,25],[28,27,27,28,27,27,27,27,27,27,26,26,26,25,26,25,26,26,25,27,26,25,26,26,26,27,27,26,27,26,25,27,28,28,27,28,27,27,27,27,27,26,26,26,26,25,24,22,24,22,20,21,21,19,18,19,18,16,17,17,14,13,11,8,7,7,6,5,5,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,3,3,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,3,3,3,3,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,1,1,0,1,1,1,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,7,7,7,8,9,10,10,12,11,12,12,13,14,14,14,15,16,17,17,18,19,21,21,21,22,23,23,24,23,21,23,22,21,22,22,23,23,23,23,24,24,27,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,25,26,27,26,26,26,26,25,26,26,26,25,26,26,24,25,24,24,23,22,21,22,20,19,17,18,15,13,13,10,9,8,7,7,7,6,6,7,6,6,6,7,7,7,7,7,8,9,8,8,9,9,9,10,10,11,10,10,9,10,9,8,8,9,9,10,10,11,11,11,10,10,9,9,9,8,8,8,8,8,7,7,7,7,6,6,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,3,3,3,3,3,3,4,4,4,6,5,5,5,3,2,2,2,2,2,2,2,2,3,2,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,4,4,4,3,4,3,3,3,4,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,5,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,5,5,4,4,4,4,5,4,4,5,5,4,4,5,5,4,5,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,6,6,6,6,6,5,5,5,6,6,6,6,6,6,6,7,6,7,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,6,6,8,8,10,10,10,11,12,14,14,16,17,18,20,20,20,18,21,19,20,23,20,21,22,22,24,24,24,25,24,23,25,25,24,26,24,23,24,24,24,24,25,24,24,24,22,25,24,24,22,23,24],[29,29,29,29,29,29,29,28,28,28,27,27,27,27,27,27,27,27,26,26,26,26,26,26,26,27,26,26,27,25,25,26,26,26,26,26,26,26,26,26,26,26,25,25,25,25,23,23,23,22,21,21,21,19,18,19,18,17,16,16,14,12,10,7,6,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,3,3,3,4,3,3,2,2,2,2,2,1,2,2,1,1,1,1,1,1,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,4,4,5,5,4,4,5,5,5,6,6,7,9,9,10,11,13,13,12,13,15,15,14,16,18,18,17,19,20,20,21,22,22,24,23,23,23,21,25,23,22,23,24,23,23,24,23,26,25,27,25,25,26,26,26,26,26,26,26,26,27,26,26,27,27,27,27,27,27,26,27,26,25,26,25,26,26,26,25,25,23,24,23,24,23,22,20,20,19,18,17,16,15,12,11,9,8,7,6,6,5,6,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,9,8,8,8,7,7,7,8,8,8,8,9,8,8,8,8,7,8,7,7,7,7,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,7,7,6,6,6,4,4,4,4,3,3,3,3,3,3,2,3,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,6,6,6,4,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,3,3,4,3,3,4,4,3,4,3,4,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,4,4,3,4,4,4,3,3,4,3,3,4,5,6,7,7,9,11,10,10,12,13,14,17,16,17,20,20,20,19,19,21,20,23,20,24,23,23,25,25,25,24,24,23,25,24,23,26,24,24,24,23,23,25,25,24,25,24,23,24,25,24,23,24,25],[28,28,28,28,28,28,28,28,28,27,27,26,26,26,27,26,26,27,26,26,27,25,27,27,26,27,27,27,27,26,26,27,27,28,27,28,27,27,28,27,27,27,27,26,26,26,24,23,24,23,21,21,21,19,18,20,18,17,18,17,13,12,10,7,6,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,3,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,2,2,2,2,2,1,1,2,1,1,2,1,1,2,2,2,2,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,4,5,5,4,4,4,4,5,4,4,5,5,5,6,6,7,9,10,10,12,14,14,13,14,15,15,14,16,16,17,18,18,20,22,21,22,23,24,23,24,23,21,23,22,22,23,23,23,24,23,22,25,24,26,25,25,26,26,26,26,26,26,26,26,26,26,27,27,26,27,26,28,26,26,26,26,26,27,27,26,27,26,26,26,25,25,25,25,23,22,21,20,20,19,17,16,15,12,11,9,8,6,6,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,8,9,9,8,9,8,8,7,7,7,7,8,8,9,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,7,6,5,4,4,4,4,3,3,3,2,3,3,2,2,3,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,6,6,6,5,3,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,4,4,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,3,3,4,3,3,4,4,3,4,3,4,4,3,3,4,3,3,3,4,3,4,3,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,6,5,5,5,5,5,5,5,4,4,5,4,4,5,4,4,4,4,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,5,6,7,7,9,10,10,11,12,13,13,16,16,18,20,19,19,18,19,18,19,23,20,22,23,22,24,24,24,24,24,23,26,24,24,25,23,24,24,23,23,25,25,24,24,24,24,24,24,24,22,25,25],[29,29,29,29,29,29,29,28,28,28,28,27,28,26,27,25,27,27,26,27,26,25,28,27,25,27,28,26,28,27,26,28,28,28,27,28,27,28,28,28,28,27,27,27,26,26,24,24,24,23,21,22,22,20,19,21,20,18,18,18,15,12,10,7,6,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,3,3,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,3,3,3,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,4,4,4,3,3,3,3,2,3,3,2,2,3,2,2,2,3,3,3,3,4,3,3,2,2,2,2,2,1,2,2,2,1,2,2,1,2,2,2,2,2,1,1,1,1,0,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,4,4,5,5,4,4,3,4,4,4,4,5,4,5,5,5,7,9,9,10,11,14,13,13,14,16,16,15,17,18,18,18,19,21,22,22,22,22,23,24,24,22,22,23,23,22,23,22,23,24,24,22,25,25,26,24,25,26,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,26,26,26,26,25,26,26,25,26,25,25,26,24,25,25,24,24,23,21,21,20,19,18,17,16,13,12,10,8,7,6,5,4,5,5,4,5,5,5,6,5,6,7,6,7,8,7,7,8,8,8,8,9,9,9,9,8,9,8,8,8,7,8,8,8,9,9,8,8,9,9,8,7,7,7,7,7,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,7,7,6,6,6,4,4,4,3,3,3,3,2,3,2,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,5,7,7,7,5,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,3,3,4,4,3,4,4,3,3,3,4,4,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,5,6,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,4,5,5,6,6,5,5,5,5,6,6,6,5,6,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,5,6,8,7,9,11,11,11,12,14,15,17,17,18,21,20,20,18,20,21,20,23,21,24,24,23,26,24,24,24,24,23,26,25,23,25,25,24,24,23,23,25,24,24,25,24,23,25,25,24,22,24,24],[27,27,28,28,28,28,27,27,28,27,26,27,26,26,26,25,25,26,25,26,26,25,26,26,25,27,26,26,27,25,25,27,27,27,26,27,27,27,27,26,27,26,26,26,26,24,24,22,23,22,22,22,21,19,18,20,19,17,17,17,13,11,9,6,6,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,2,3,3,3,3,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,2,2,1,1,2,1,1,2,1,1,1,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,4,3,3,4,4,4,5,5,6,8,9,9,10,13,13,11,13,14,14,14,15,16,16,16,17,18,19,19,20,21,21,21,22,20,20,21,21,20,21,20,22,21,21,20,23,23,25,23,23,24,24,24,25,24,24,24,24,24,25,25,25,25,25,25,26,25,25,25,24,25,25,25,24,24,24,24,25,23,23,23,23,22,20,20,20,18,17,16,15,14,12,10,8,7,6,5,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,7,7,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,6,6,6,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,3,3,3,4,5,6,6,4,3,2,2,1,2,2,3,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,1,1,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,4,3,4,4,3,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,5,4,4,4,4,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,7,6,8,10,9,9,11,12,13,15,16,17,18,19,19,17,18,18,19,22,19,23,21,21,24,23,24,23,24,23,25,23,24,25,22,23,23,22,22,24,23,23,24,23,23,23,24,23,21,23,24],[28,28,28,28,28,28,28,27,28,27,26,26,26,26,27,25,25,27,26,26,26,26,26,26,26,27,25,26,26,25,25,26,26,27,26,27,26,27,27,26,27,26,25,27,25,25,23,22,23,22,22,22,21,19,19,19,18,16,17,17,13,11,9,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,3,3,4,4,3,3,3,3,4,3,3,4,4,4,5,5,6,7,9,9,11,13,13,12,13,15,15,15,17,17,17,18,18,19,21,20,20,22,22,22,23,21,21,23,22,22,22,22,23,23,21,21,24,24,27,25,25,25,26,26,26,26,25,26,26,26,26,26,26,27,27,27,27,26,26,26,26,25,26,25,25,26,25,25,25,24,25,24,24,24,22,19,21,20,17,17,15,14,11,10,8,6,5,5,4,4,4,4,4,4,4,5,5,4,5,5,5,5,6,5,6,6,7,6,7,7,7,7,7,7,6,6,6,6,6,6,6,7,7,7,6,7,7,6,6,6,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,3,3,4,5,6,6,4,3,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,4,4,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,7,9,9,8,9,11,12,14,15,16,18,19,18,16,18,19,18,22,19,21,21,22,25,24,24,24,24,24,24,23,24,25,22,23,24,22,20,24,24,22,23,23,24,22,24,23,20,24,25],[28,28,28,28,28,28,28,27,27,27,27,26,26,25,26,24,25,26,25,25,26,25,25,25,26,26,25,26,26,25,25,26,25,26,25,26,25,26,25,26,25,26,25,25,24,24,22,22,22,22,22,20,20,20,18,18,18,16,16,16,13,11,9,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,1,2,1,1,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,4,4,4,4,5,6,7,8,9,11,12,13,12,13,14,15,14,16,16,17,17,18,19,20,19,20,21,21,22,22,21,20,22,21,21,21,21,22,22,22,21,24,23,25,23,23,24,24,25,24,24,24,24,24,24,24,24,25,25,25,24,26,24,25,24,24,24,24,24,24,24,25,24,25,23,23,22,23,23,21,20,20,18,17,16,16,14,11,9,8,6,5,4,4,3,4,4,3,4,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,6,6,6,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,5,5,4,4,4,3,3,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,5,5,5,4,3,2,2,1,2,2,1,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,3,3,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,2,2,3,3,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,2,3,2,2,3,4,5,6,6,7,8,9,9,10,11,11,14,14,15,17,18,16,15,17,18,17,20,17,21,20,20,23,22,21,21,23,21,23,22,21,22,22,22,22,20,21,22,22,22,23,21,21,22,23,21,20,22,23],[28,28,28,28,28,28,28,28,27,27,27,27,27,25,26,25,26,27,26,27,27,25,26,27,25,26,27,26,27,26,25,26,27,27,27,27,26,27,27,27,26,26,26,26,25,25,24,23,24,23,22,22,22,20,18,20,19,17,17,17,13,11,8,6,5,4,3,3,3,2,2,2,2,1,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,1,1,2,2,3,3,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,5,6,8,9,9,10,12,14,12,13,15,15,14,16,16,17,16,18,19,20,20,20,21,22,23,23,22,21,23,21,21,22,22,23,22,22,22,24,23,26,23,24,25,24,25,25,24,24,24,24,25,24,25,25,25,25,25,26,25,26,25,26,25,25,25,25,24,25,24,26,24,24,23,23,22,21,20,20,18,17,16,15,13,11,9,7,6,5,4,3,3,4,4,3,4,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,6,6,6,5,5,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,4,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,3,3,3,6,6,6,4,3,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,2,2,2,1,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,2,2,3,3,2,3,2,3,3,2,2,3,2,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,3,2,2,3,4,5,5,5,7,9,9,9,10,12,12,15,17,17,18,19,18,16,17,18,19,21,20,23,21,22,25,24,22,22,24,23,24,23,22,23,22,22,23,21,22,23,22,23,23,22,22,23,24,21,21,23,23],[28,27,28,28,28,28,28,27,28,27,27,27,27,26,26,26,26,27,26,26,27,27,26,27,27,27,27,27,28,26,26,27,26,27,27,27,26,27,27,27,27,27,26,26,26,26,24,23,23,23,23,21,21,21,19,21,19,18,17,17,14,11,8,6,5,4,3,3,3,2,2,2,2,1,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,2,2,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,3,3,2,2,3,2,2,2,3,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,5,6,7,9,10,12,14,16,13,14,16,16,15,16,17,17,18,19,19,20,20,20,22,23,22,23,22,21,23,21,20,22,22,24,22,22,22,25,24,27,24,25,25,25,25,25,25,25,25,25,25,25,26,26,26,25,26,26,26,26,25,26,25,25,26,25,25,26,25,26,24,24,23,24,23,22,21,20,18,17,16,15,13,10,9,8,6,5,4,4,3,4,4,3,4,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,6,6,6,5,5,5,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,1,1,2,2,2,3,3,5,5,6,4,3,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,3,3,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,2,2,3,3,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,4,5,6,6,7,9,9,8,10,12,13,16,17,16,19,19,19,17,17,19,20,21,20,24,21,22,25,24,23,23,24,23,23,24,24,23,21,23,24,21,21,24,23,23,24,23,23,23,24,23,20,23,23],[28,28,28,28,27,28,28,27,27,26,27,26,26,25,26,25,25,26,25,26,26,25,26,26,26,26,26,26,26,25,25,26,26,27,25,26,26,26,25,26,26,25,25,25,24,24,23,22,22,22,21,21,21,19,17,19,19,16,17,16,13,11,8,6,5,4,4,3,3,2,2,2,2,1,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,1,2,2,3,3,3,2,3,2,2,2,3,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,2,2,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,8,9,10,12,13,14,13,14,15,15,15,16,16,17,17,17,18,20,19,19,21,22,22,22,22,20,23,21,20,22,22,23,22,22,22,25,23,26,24,25,25,25,25,25,25,25,25,25,25,25,25,26,25,25,25,26,25,26,25,25,25,24,25,25,24,25,24,24,24,23,22,24,22,20,19,19,18,16,15,15,13,11,9,7,6,5,4,4,3,4,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,2,2,2,2,1,1,2,2,1,1,2,1,1,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,2,2,2,2,3,3,4,4,5,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,6,8,9,8,9,11,12,14,16,16,17,19,16,16,16,18,18,20,18,22,20,20,23,23,22,21,23,22,22,23,22,22,21,22,24,22,21,23,22,24,23,22,22,22,24,23,20,22,24],[28,28,28,28,28,28,28,27,27,27,27,27,26,25,26,25,26,26,25,25,26,25,25,25,25,26,26,26,27,25,25,26,26,26,26,26,26,26,26,26,26,25,25,25,25,24,24,22,22,22,21,21,22,20,18,19,18,16,17,16,13,11,9,6,5,4,3,3,3,2,2,2,2,1,2,2,2,2,2,2,1,1,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,2,2,2,2,2,2,3,3,2,2,3,2,2,2,3,2,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,2,3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,6,7,8,9,11,13,15,12,13,16,16,15,16,17,18,18,18,20,21,20,20,22,22,22,22,21,21,22,20,20,22,21,22,22,22,22,23,23,26,23,24,24,24,25,24,24,24,24,24,24,25,25,25,25,25,25,26,25,26,25,25,25,24,25,24,24,25,24,25,23,23,23,23,22,21,19,19,18,17,16,15,13,11,9,7,6,5,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,6,5,5,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,3,3,5,5,5,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,4,4,3,3,3,3,2,2,2,1,2,2,1,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,3,4,3,3,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,6,7,9,9,9,10,12,13,15,16,16,18,19,16,16,17,19,18,20,19,22,20,21,25,24,23,23,24,21,23,23,23,23,22,22,22,21,21,22,21,22,22,22,20,21,23,21,20,22,24],[27,28,28,28,28,28,27,27,28,27,27,27,27,27,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,26,27,28,27,28,28,28,28,27,28,27,27,26,27,27,26,25,24,23,24,23,22,22,22,21,20,21,19,18,17,16,13,12,9,6,5,4,3,3,3,2,2,2,1,1,1,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,3,3,3,3,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,3,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,7,9,9,11,13,13,12,13,14,14,15,15,17,17,17,18,19,21,19,20,22,22,23,23,22,22,22,21,20,23,22,22,21,22,21,25,24,26,24,24,25,26,25,25,25,26,25,25,26,25,26,26,26,26,26,26,26,26,26,25,25,25,26,26,26,25,25,25,24,25,23,25,24,21,20,20,19,18,16,14,12,10,8,7,6,5,4,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,6,6,6,6,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,4,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,3,3,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,1,2,2,2,2,3,3,3,3,4,5,5,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,4,4,3,4,3,3,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,2,2,3,3,2,2,2,3,3,2,2,3,3,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,3,3,3,3,3,4,4,4,4,4,4,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,4,4,3,4,3,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,2,2,2,3,3,4,5,5,7,8,8,8,9,11,12,14,16,16,19,18,19,16,17,18,18,20,19,22,22,21,23,24,22,23,23,23,24,23,23,24,22,22,22,21,23,23,24,22,23,23,21,23,23,22,20,22,23],[27,27,28,28,28,28,27,27,28,27,25,26,26,26,26,26,26,26,26,26,26,26,26,26,27,26,26,26,26,25,25,26,26,27,25,27,26,26,27,26,26,25,25,26,24,24,24,22,23,22,22,22,22,20,19,20,19,18,17,17,14,12,9,6,5,5,4,3,3,3,2,2,2,1,1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,3,3,3,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,5,5,6,9,9,10,13,13,14,12,13,16,15,15,16,17,18,18,18,19,21,19,20,22,23,22,23,20,20,21,19,21,22,20,24,22,21,21,23,23,26,23,23,25,25,25,26,25,25,25,25,25,25,26,25,26,26,26,26,26,25,24,25,24,25,26,24,26,24,24,25,23,24,23,24,23,22,19,20,19,17,16,15,13,10,9,8,6,5,4,4,3,4,4,3,4,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,5,5,5,4,4,3,3,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,3,3,3,4,4,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,2,2,3,3,2,3,3,2,3,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,4,4,3,3,3,4,3,3,4,3,3,3,3,3,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,4,5,6,6,7,9,8,8,9,11,12,13,15,15,19,19,18,16,16,17,18,21,19,21,19,21,24,23,22,23,23,23,23,22,22,23,20,21,23,21,19,22,22,22,22,21,22,22,23,22,19,23,24],[28,28,28,28,27,28,27,27,27,26,27,26,26,26,26,26,26,27,26,26,27,26,26,26,27,26,26,27,26,26,25,26,26,27,25,26,25,26,26,26,26,25,25,25,25,24,23,22,22,22,21,21,21,20,18,21,19,17,18,18,15,12,10,7,6,5,4,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,3,3,2,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,3,4,4,5,5,5,6,8,10,10,12,13,15,13,15,16,16,16,17,17,18,18,18,20,21,20,21,22,22,23,23,22,20,22,21,21,22,21,24,22,22,22,25,24,26,24,24,25,26,26,25,25,25,25,25,25,25,25,25,25,26,25,26,25,26,25,25,24,24,25,24,25,25,25,25,24,23,23,24,23,21,20,19,18,16,16,15,13,11,9,8,6,5,4,4,3,4,4,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,7,6,6,6,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,4,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,4,4,4,4,4,3,3,2,2,2,2,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,3,4,4,3,3,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,3,3,3,3,4,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,4,5,6,6,7,9,9,9,10,12,12,15,16,15,17,18,16,16,17,18,17,21,18,20,20,21,24,24,23,21,23,22,22,22,22,23,21,21,23,20,21,22,22,23,23,22,21,21,23,21,19,22,23],[28,27,28,28,28,28,27,27,28,27,26,27,26,26,26,25,25,26,26,25,26,26,25,25,27,26,26,26,26,26,26,26,26,26,25,26,25,25,26,25,26,25,24,25,24,24,23,22,22,23,21,21,21,20,18,20,19,18,17,17,15,12,10,7,6,5,4,3,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,3,4,4,4,4,3,3,3,4,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,2,2,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,1,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,2,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,3,4,4,4,5,5,7,9,10,11,12,14,15,14,14,16,16,16,17,18,18,18,19,21,21,20,21,22,22,22,23,21,21,21,20,21,21,21,23,22,22,22,24,24,26,23,24,24,24,25,25,24,24,25,24,24,24,25,25,25,25,24,25,25,25,25,25,24,25,25,24,24,24,24,25,24,23,23,23,23,21,20,20,18,17,17,14,13,10,9,8,6,5,4,4,3,3,4,3,3,3,4,4,4,4,5,5,5,6,5,6,6,6,6,7,7,7,7,8,7,6,6,6,5,5,5,6,6,7,7,7,7,7,7,6,6,6,5,5,5,4,4,4,4,3,3,3,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,5,4,5,4,4,3,3,2,2,2,2,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,2,2,3,2,3,2,2,2,3,3,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,3,4,4,5,5,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,4,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,4,5,6,6,8,9,9,10,10,14,13,15,17,18,19,20,18,17,19,19,19,22,20,22,21,22,24,23,23,23,23,22,24,23,22,23,22,22,22,20,22,22,22,22,22,22,20,22,23,20,21,23,23],[28,28,28,28,28,28,28,28,28,27,26,26,27,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,26,26,27,28,28,27,27,27,27,27,27,27,27,26,27,26,26,24,24,25,24,22,22,22,20,20,21,20,19,18,19,16,13,10,8,6,5,4,4,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,3,3,3,3,2,2,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,4,4,3,4,4,4,4,5,6,8,9,11,11,13,15,15,15,15,16,17,17,18,17,18,19,20,21,22,21,22,23,23,23,23,22,22,23,21,21,23,22,24,21,23,23,26,25,27,25,25,26,26,26,25,25,26,26,26,26,25,26,26,26,25,26,26,26,26,26,26,26,25,26,26,26,26,26,26,24,24,24,24,23,22,20,20,19,17,15,14,12,11,10,8,7,6,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,8,7,7,6,6,6,6,6,7,7,8,7,7,7,7,7,7,6,6,6,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,4,4,3,3,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,5,5,5,4,3,3,2,2,3,2,2,2,3,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,4,4,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,4,3,4,4,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,3,4,4,4,5,4,5,5,4,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,8,9,9,9,10,12,13,15,16,17,19,19,19,17,17,19,19,21,19,23,21,21,24,24,22,23,23,23,24,23,23,24,22,23,24,21,21,23,22,23,23,21,22,22,24,22,20,23,23],[28,27,28,28,28,28,28,27,28,27,26,26,26,26,26,26,26,27,26,27,27,26,27,27,26,26,27,26,27,26,25,26,27,28,26,26,26,26,27,26,26,25,25,25,25,25,24,23,24,23,21,22,22,21,20,22,20,19,18,19,16,14,10,8,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,3,3,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,3,3,2,2,3,3,3,3,4,3,4,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,2,2,2,2,3,3,3,3,3,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,2,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,3,4,4,3,4,4,4,5,6,6,7,9,10,11,13,15,15,15,15,17,17,16,18,18,18,19,19,20,21,20,21,21,22,22,23,21,21,22,21,21,22,22,24,22,23,23,25,24,26,24,24,25,26,26,26,25,25,25,26,26,26,25,25,25,25,25,25,25,26,25,25,25,24,25,25,26,25,24,26,24,23,23,23,23,21,21,19,19,17,15,16,13,12,10,9,6,6,5,4,4,4,4,4,5,4,5,5,5,5,6,5,6,6,6,6,7,7,7,7,7,8,7,8,8,7,6,6,6,7,6,7,7,7,8,7,7,7,7,6,6,6,6,6,5,5,5,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,4,4,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,5,5,6,4,3,3,3,2,3,3,2,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,5,4,5,5,5,4,4,4,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,3,4,4,4,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,5,7,7,8,10,10,10,11,13,13,15,16,16,19,19,18,17,17,19,18,22,19,21,21,21,24,23,23,23,23,23,23,23,23,24,22,23,24,22,22,23,22,23,23,22,22,22,24,23,21,23,23],[28,28,28,28,28,28,28,28,28,27,26,26,27,26,26,26,26,27,26,27,27,27,27,27,27,27,27,27,27,26,26,27,27,27,26,26,26,26,27,27,27,26,26,26,26,26,25,24,24,24,22,22,23,22,20,22,20,20,20,19,17,14,12,9,8,7,5,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,3,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,4,3,4,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,5,6,7,6,8,10,12,12,14,14,15,15,16,17,18,17,19,19,19,20,20,21,22,21,22,23,24,24,24,23,22,23,22,21,23,22,24,22,23,23,25,25,27,25,25,26,26,26,26,26,26,26,26,26,25,26,26,26,26,26,27,26,26,26,26,26,25,25,25,25,25,25,26,25,24,24,24,22,22,21,19,19,18,16,16,14,12,11,9,7,7,5,5,4,5,5,4,5,4,4,4,5,5,5,6,6,6,6,6,7,8,7,7,8,8,8,8,8,7,7,7,6,7,7,7,7,8,8,8,7,7,7,7,6,6,6,6,6,5,5,5,5,4,4,4,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,4,3,3,3,2,2,2,1,1,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,5,5,6,6,5,4,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,4,5,5,5,5,5,4,4,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,5,4,4,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,6,7,7,9,10,10,10,10,13,13,16,17,17,19,17,17,17,18,19,19,22,20,20,20,20,23,23,23,21,22,22,23,23,22,25,22,22,24,22,23,22,23,23,22,21,21,22,24,21,20,22,21],[28,28,28,28,28,29,28,28,28,27,27,27,27,26,26,26,26,27,26,26,27,26,26,26,26,27,27,27,27,26,26,27,27,27,26,26,26,26,27,26,27,26,26,26,26,25,25,24,24,24,21,22,23,20,19,21,21,19,18,19,16,13,11,8,7,6,5,4,4,3,3,2,2,2,2,2,3,3,3,3,2,2,3,2,2,2,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,6,5,4,4,4,5,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,3,3,3,3,2,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,4,4,4,4,4,4,5,6,7,7,10,11,12,12,15,16,14,15,17,18,16,17,18,19,19,20,20,21,21,22,23,23,23,24,22,22,23,21,21,23,22,24,22,25,24,25,25,26,25,25,26,26,26,26,26,26,26,26,26,26,26,26,27,25,25,26,26,26,26,26,26,25,26,26,26,25,26,25,24,23,23,24,22,22,20,20,18,17,16,15,13,11,10,9,7,6,5,5,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,7,8,7,8,8,8,8,8,7,7,7,6,7,6,7,7,8,8,7,8,8,7,7,6,6,6,5,5,5,5,4,4,4,3,3,3,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,6,6,6,5,4,3,3,3,3,2,2,1,1,1,2,1,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,5,5,6,6,5,4,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,3,4,4,3,3,4,4,4,3,3,3,4,4,4,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,4,4,4,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,4,5,5,5,5,4,5,5,5,5,5,5,6,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,6,7,7,9,10,10,11,10,13,14,16,18,18,20,20,17,17,18,19,19,21,20,20,22,21,24,23,23,22,22,21,24,23,21,24,22,22,23,22,22,23,22,22,23,23,21,23,24,21,21,22,21],[27,28,28,28,28,28,28,28,28,27,26,26,27,26,26,27,26,27,26,27,27,27,27,28,27,27,27,27,27,27,26,27,28,28,27,28,27,27,27,27,28,27,26,27,26,26,25,24,25,24,23,24,23,21,20,22,20,19,19,18,16,14,11,9,8,6,5,4,4,3,3,3,2,2,3,3,3,3,3,3,4,3,3,3,3,4,4,4,5,5,5,5,5,4,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,6,6,5,5,6,6,5,5,5,5,5,4,5,5,4,4,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,4,5,5,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,3,3,3,4,3,3,4,4,3,4,4,4,4,5,5,5,6,5,6,6,6,6,6,6,6,7,6,5,5,5,5,4,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,2,3,2,2,3,3,4,4,4,4,3,2,2,2,2,3,3,3,4,4,3,3,3,4,4,4,5,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,4,5,5,6,8,10,11,12,13,15,16,14,16,18,18,16,19,19,18,20,21,22,22,23,23,23,25,25,25,23,21,24,22,21,23,23,24,23,23,24,26,25,27,26,26,27,27,27,28,27,26,27,26,26,27,27,27,27,26,26,27,26,27,26,26,26,26,26,26,26,25,25,26,24,24,23,24,22,21,20,19,19,18,15,14,12,11,10,9,7,6,5,4,4,5,5,4,5,5,5,6,6,7,7,7,7,8,7,8,8,9,9,9,10,11,10,11,9,8,8,7,7,8,8,7,9,9,10,9,9,9,8,8,8,7,7,7,7,6,6,6,5,5,5,4,4,3,3,4,4,4,3,4,5,4,4,5,5,4,5,6,6,7,6,6,7,6,5,4,4,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,3,4,4,4,4,4,5,5,6,7,7,7,6,5,5,4,5,5,5,4,5,5,5,6,6,6,6,7,6,6,6,5,6,5,5,5,5,5,4,5,4,4,4,4,3,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,4,4,4,4,4,5,4,5,5,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,6,6,6,6,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,4,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,6,7,6,6,5,6,6,5,6,5,5,6,5,4,5,5,4,4,4,4,4,5,5,5,5,5,5,5,6,7,6,6,7,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,5,4,3,4,4,3,3,4,5,6,7,7,8,9,10,10,10,12,13,14,16,17,19,19,18,17,19,19,17,21,19,20,21,22,24,25,23,23,22,24,24,24,23,24,21,22,23,22,22,24,23,23,24,22,22,22,24,22,19,22,20],[28,28,29,29,29,29,29,29,29,28,27,27,28,27,28,27,27,28,27,28,28,27,28,28,27,28,29,28,28,28,27,28,29,29,28,29,28,28,29,28,29,28,28,28,28,28,27,26,27,25,25,25,24,23,22,23,22,21,20,20,18,16,12,10,8,6,5,4,4,3,3,2,2,2,2,3,3,3,4,3,3,3,4,3,3,4,4,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,7,7,6,6,7,7,8,7,6,6,6,6,6,6,5,5,6,5,5,6,6,5,5,6,5,5,5,6,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,5,5,6,6,5,5,5,5,4,5,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,4,3,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,6,7,7,6,6,7,7,6,6,5,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,4,5,5,4,4,4,4,4,3,3,4,3,3,3,3,2,3,3,3,3,3,4,4,4,5,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,2,2,2,2,2,1,1,2,2,1,0,1,1,2,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4,3,3,4,4,3,3,3,4,4,3,4,4,5,5,6,6,8,10,12,12,14,16,17,17,16,18,18,17,19,20,19,20,22,23,23,23,24,24,25,25,25,25,23,25,24,21,24,23,24,24,24,24,26,25,26,26,27,27,28,28,28,27,27,27,27,27,27,28,27,28,27,28,27,28,28,28,27,26,27,28,27,28,27,26,26,24,25,24,24,23,23,20,19,20,17,15,15,13,11,10,9,7,7,5,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,7,8,8,9,10,9,10,10,10,11,9,8,8,7,7,7,7,8,8,10,10,9,9,9,7,8,7,7,6,6,6,5,5,5,4,4,4,4,3,3,3,3,4,3,3,4,4,4,4,5,5,5,6,6,6,7,7,7,8,7,6,5,4,4,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,3,4,4,4,4,4,5,4,4,5,5,6,6,7,7,7,7,6,5,5,5,5,5,5,4,5,5,6,6,6,7,7,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,2,3,2,2,3,3,2,3,3,2,2,3,3,3,3,3,3,4,4,3,3,3,4,3,4,5,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,6,7,6,6,6,7,6,5,5,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,6,6,6,6,5,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,6,6,6,6,6,5,5,5,5,4,5,5,4,4,5,4,4,5,5,4,4,5,4,4,4,5,6,7,8,8,10,11,11,10,11,13,15,16,17,19,21,20,20,19,20,21,20,23,21,23,23,23,25,24,24,24,24,24,25,25,24,25,24,24,25,22,24,25,25,24,25,23,25,23,26,24,21,24,23],[28,28,28,28,28,29,28,28,28,28,27,27,27,27,27,27,27,28,27,28,28,27,28,28,28,28,28,28,28,28,27,28,29,29,28,28,28,28,28,28,28,28,28,28,27,27,26,26,25,25,25,24,24,23,21,23,21,21,19,19,16,15,12,9,7,6,4,4,4,3,3,2,2,1,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,6,5,6,6,6,6,6,7,7,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,6,6,6,5,5,5,5,4,5,5,4,4,5,4,4,4,4,3,3,4,5,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,3,3,4,3,3,4,4,3,4,4,4,4,4,5,6,5,5,5,6,6,5,6,7,6,7,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,4,5,5,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,2,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,3,3,4,3,4,4,4,5,5,6,8,10,12,14,14,16,17,16,17,18,17,17,18,18,19,20,21,22,23,22,24,24,24,24,25,23,23,24,23,22,24,23,24,23,23,23,26,25,26,26,26,27,27,27,28,27,27,27,27,27,27,27,27,27,27,28,28,27,28,26,27,26,27,27,26,28,26,26,27,24,25,25,24,24,24,20,22,21,19,18,17,15,13,12,9,7,6,5,4,4,4,4,4,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,9,9,8,8,7,7,6,6,6,7,7,8,9,8,8,8,7,7,6,6,6,6,5,5,5,4,4,4,4,3,3,3,2,3,3,3,3,4,4,4,4,4,4,5,5,5,6,6,6,7,7,6,6,5,4,4,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,6,6,7,7,6,5,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,6,6,5,6,6,6,5,5,4,4,3,3,3,2,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,4,3,3,4,4,4,4,4,5,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,6,6,6,5,5,6,5,5,5,5,5,5,4,4,4,4,4,4,3,4,4,5,5,5,5,5,5,5,6,5,5,6,6,5,6,6,6,5,5,5,5,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,6,7,8,8,10,11,10,10,11,14,14,15,17,18,21,21,20,17,19,19,20,22,20,21,23,22,24,23,24,24,23,24,25,24,24,25,24,23,24,22,22,24,24,23,24,24,22,24,24,23,22,24,22],[28,28,28,28,28,29,28,28,28,27,27,26,27,27,27,27,27,28,27,28,27,27,27,28,27,28,27,27,28,27,26,28,28,28,27,28,27,27,28,28,28,27,26,27,27,26,25,25,25,25,23,24,23,22,21,22,20,20,19,18,16,14,11,9,7,6,5,4,4,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,7,7,7,7,6,6,5,6,6,6,6,6,6,5,5,5,5,6,5,5,5,6,5,5,5,6,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,5,5,5,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,5,4,4,4,5,5,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,6,7,6,5,5,5,5,5,4,5,5,4,4,4,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,4,4,5,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,4,4,5,5,5,5,4,3,4,3,3,4,3,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,3,4,3,4,3,4,4,4,4,4,5,6,6,9,10,12,13,14,16,16,16,16,18,17,17,19,19,19,20,20,20,22,22,23,23,24,22,24,23,22,24,22,21,23,22,24,22,24,24,25,25,26,25,26,26,27,26,26,26,27,27,27,27,27,27,27,26,26,26,26,26,27,26,26,25,25,26,25,26,25,24,25,24,24,24,24,23,22,20,20,20,18,16,17,14,13,11,8,7,6,5,5,4,4,4,3,4,4,4,5,5,5,6,6,6,6,7,7,8,8,8,8,9,9,8,9,8,8,7,7,6,6,7,7,7,8,9,7,8,7,7,7,6,6,6,6,5,5,5,4,4,4,4,3,3,3,2,3,3,3,3,4,4,3,4,4,4,4,5,5,5,6,6,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,4,3,4,3,3,3,4,3,3,4,4,4,4,4,4,5,6,7,7,6,5,4,4,4,4,4,5,4,5,5,6,6,6,6,7,6,6,6,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,5,6,6,6,5,5,4,4,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,6,7,8,8,9,11,11,10,11,13,13,14,16,16,19,19,18,17,19,19,19,22,21,21,21,21,23,23,23,22,23,22,23,24,23,25,22,23,23,21,22,23,23,23,23,21,23,23,24,22,21,23,22],[28,29,28,28,28,28,29,28,28,27,27,27,28,27,27,27,27,27,27,27,28,27,28,28,27,28,28,28,28,27,27,28,28,28,27,28,27,27,28,27,27,27,26,27,27,27,25,25,25,24,23,24,24,22,21,23,21,20,20,20,17,15,12,9,8,6,5,4,4,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,6,7,7,6,6,5,5,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,5,5,6,5,5,5,5,5,5,4,4,5,4,4,4,4,5,4,5,5,5,5,4,4,4,4,4,3,4,4,4,3,4,4,4,3,4,4,3,4,4,4,4,3,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,5,4,5,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,4,4,4,3,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,2,3,4,3,3,3,3,3,4,3,3,4,4,5,6,7,8,10,12,11,14,16,17,15,16,18,18,17,20,20,19,20,20,21,22,21,23,23,24,22,24,22,22,23,22,21,23,22,24,23,24,24,26,25,27,25,26,27,27,27,27,26,26,27,26,27,26,26,26,26,26,26,25,26,26,25,26,24,25,25,25,26,25,24,26,23,24,24,24,23,22,21,20,20,19,15,15,14,12,11,8,6,6,5,4,4,4,4,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,8,7,8,8,8,8,7,7,6,6,6,5,6,6,6,7,8,7,7,7,7,6,5,6,6,5,5,5,4,4,4,4,3,3,3,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,5,5,5,6,6,5,5,4,4,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,6,7,7,6,5,5,4,4,4,5,5,4,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,4,4,4,3,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,6,5,6,6,6,6,5,5,5,5,5,5,4,4,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,3,4,4,4,5,5,5,5,5,5,5,5,5,6,6,5,5,5,6,5,4,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,3,4,5,6,7,7,9,10,10,9,10,12,13,14,16,16,18,19,17,16,18,18,18,20,18,19,22,20,22,23,24,23,23,23,24,24,24,24,22,23,24,22,23,23,22,23,24,21,22,23,24,21,20,23,21],[29,28,28,29,29,29,28,28,29,27,27,28,27,27,27,27,27,27,27,27,27,26,27,27,27,26,28,28,27,28,27,27,28,29,27,28,28,28,28,28,28,27,27,27,27,26,25,24,25,25,24,24,23,22,20,22,20,19,19,19,16,14,11,9,7,6,5,4,4,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,6,5,5,4,5,5,5,5,5,5,4,4,5,5,4,5,5,5,4,5,5,4,5,6,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,3,4,4,4,4,5,5,4,5,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,3,3,3,4,4,4,3,3,4,3,3,4,4,4,4,4,4,4,4,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,5,5,6,8,10,12,11,13,15,16,15,15,17,18,16,19,19,19,19,21,21,23,22,22,23,24,23,24,22,22,24,22,21,23,24,23,23,23,25,25,25,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,26,26,27,26,27,26,25,26,25,24,24,24,24,22,21,21,20,18,16,15,14,12,11,8,6,5,4,4,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,7,6,7,7,7,8,7,6,6,5,5,5,5,6,5,7,7,6,6,6,5,5,5,5,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,4,4,4,5,5,5,5,5,5,4,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,5,5,6,7,7,6,5,4,4,4,4,5,4,4,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,6,5,6,6,5,5,5,4,4,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,7,8,9,9,9,10,12,13,14,16,17,20,20,18,17,18,19,19,21,20,20,21,21,24,22,23,22,23,22,25,23,23,22,22,22,23,20,22,24,22,22,23,23,21,23,24,21,21,23,21],[28,28,28,28,28,29,29,28,28,28,27,27,27,27,27,27,27,28,28,28,28,28,27,28,27,27,28,28,28,28,27,28,28,29,28,28,28,28,28,28,28,28,27,27,27,26,26,25,25,25,24,24,24,23,22,23,20,20,19,19,16,14,11,9,7,5,4,4,4,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,4,5,5,5,4,5,5,6,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,5,5,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,3,3,4,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,6,6,5,5,6,6,6,5,5,5,4,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,4,4,4,5,6,8,10,12,12,14,15,16,16,16,17,17,18,19,18,18,20,20,21,22,21,22,23,23,23,24,22,22,24,22,21,23,23,23,21,23,24,25,25,26,25,25,27,27,27,27,27,27,27,26,27,27,27,27,27,26,26,27,27,27,26,26,26,25,27,26,27,25,25,26,25,25,25,25,24,23,21,21,21,18,16,18,14,13,11,8,7,5,5,4,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,6,6,7,7,7,7,7,6,6,5,5,5,5,6,5,6,7,6,6,6,6,5,5,5,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,5,5,5,6,6,5,5,4,4,3,3,3,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,6,7,5,5,4,4,4,4,4,4,4,4,5,5,5,6,5,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,5,6,6,6,5,5,5,5,5,5,5,4,4,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,2,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,4,5,5,5,4,4,4,4,4,4,4,4,3,4,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,5,4,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,9,10,12,12,14,16,17,19,20,19,16,18,19,19,21,19,22,21,21,24,24,23,23,24,22,24,24,23,23,22,23,23,20,21,23,23,22,23,22,22,22,23,22,20,23,20],[28,28,28,27,27,28,28,27,28,27,26,26,26,26,26,27,26,26,27,26,27,27,26,27,27,27,27,27,27,26,27,27,27,28,27,27,26,27,27,27,27,27,26,27,26,25,25,24,24,23,23,23,23,22,21,22,20,20,19,18,15,13,11,9,7,6,4,4,4,3,3,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,6,6,6,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,4,4,4,5,5,5,5,5,5,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,4,4,5,5,6,6,5,6,6,6,6,6,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,5,5,6,7,10,11,10,13,14,15,13,14,16,16,15,17,17,17,19,19,20,20,20,22,21,22,21,21,21,19,21,20,19,21,20,22,21,22,23,24,24,25,24,25,24,25,25,26,25,25,25,25,25,25,25,25,25,25,25,25,25,26,24,24,24,25,24,24,26,23,23,25,24,23,23,23,23,21,21,20,19,18,15,17,14,14,12,7,6,5,4,4,3,3,3,3,3,4,3,4,4,4,5,5,5,5,6,6,6,6,7,6,7,7,8,8,7,6,6,5,5,5,5,6,6,6,7,6,7,7,6,6,5,5,5,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,3,3,3,4,4,4,5,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,3,3,4,4,4,5,6,7,7,6,5,4,4,4,4,4,4,4,5,5,6,6,6,6,7,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,5,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,6,5,4,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,3,4,5,6,7,7,8,9,9,9,9,11,11,13,14,14,18,18,17,16,17,18,17,20,18,19,21,21,22,23,23,22,22,22,23,23,22,24,21,23,23,21,21,22,22,23,23,20,20,23,23,20,19,22,20],[28,28,28,28,28,28,28,28,28,27,26,26,27,26,26,26,26,27,26,26,27,26,26,27,26,27,27,27,27,27,26,27,27,28,26,27,27,27,28,27,27,27,26,26,26,25,25,24,25,24,24,24,23,22,20,22,20,19,18,19,16,13,11,8,7,5,4,4,4,3,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,6,5,5,6,6,5,5,5,4,5,5,4,4,5,4,4,4,4,5,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,3,4,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,5,5,4,5,5,5,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,2,3,3,2,2,3,3,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,4,4,4,4,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,2,3,3,3,3,3,4,4,4,5,5,6,8,9,10,12,14,16,13,14,16,17,15,17,18,17,18,18,20,21,20,21,21,22,21,23,21,19,22,21,19,21,21,23,22,22,22,25,24,26,24,25,26,26,26,27,26,26,26,25,25,26,26,25,26,26,26,26,25,26,24,25,24,24,24,24,25,24,23,25,24,22,23,23,22,21,20,19,19,18,15,14,13,12,11,8,6,5,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,6,6,6,6,6,5,5,5,4,4,4,4,5,5,6,6,5,6,5,5,5,4,5,4,4,4,4,4,3,3,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,5,6,6,6,6,5,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,5,5,5,5,5,5,6,6,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,2,2,2,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,3,4,4,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,4,4,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,4,5,6,6,7,9,8,8,9,10,11,12,15,15,18,18,16,15,17,17,16,18,18,18,20,19,21,23,23,21,21,22,23,22,22,23,21,21,22,20,20,22,22,21,22,21,20,20,23,19,17,20,19],[29,28,28,29,29,29,28,28,29,27,28,28,28,27,27,27,26,28,27,27,27,26,27,28,27,27,28,28,27,27,26,27,28,28,27,28,27,27,28,27,28,27,27,27,26,26,25,24,25,24,24,24,24,22,21,22,21,19,19,18,15,13,10,8,6,5,4,4,4,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,5,5,5,4,5,5,5,5,5,6,6,5,6,6,5,5,5,4,5,5,5,4,5,5,4,4,5,5,4,4,5,4,4,5,4,4,4,5,6,5,5,5,5,5,4,5,4,4,4,4,4,3,4,4,3,3,3,4,4,4,4,4,5,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,3,3,3,4,3,3,3,3,4,3,3,3,4,3,3,4,4,3,4,4,5,5,5,5,5,5,5,5,6,5,6,5,5,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,3,3,3,3,4,4,4,3,3,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,1,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,5,5,7,9,10,10,13,14,16,13,15,18,16,16,18,18,18,19,19,20,21,20,22,23,23,23,24,21,21,23,21,21,23,22,24,21,22,23,24,24,27,25,26,26,27,27,27,27,26,27,26,27,27,27,27,27,27,27,27,27,27,26,27,25,26,27,25,27,26,26,27,24,23,25,24,25,23,22,22,21,20,17,17,16,14,11,8,6,5,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,5,6,6,6,6,6,5,5,5,4,4,4,5,5,5,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,5,6,6,6,5,5,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,5,5,4,4,4,3,3,3,3,3,3,2,3,3,2,2,2,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,3,3,4,4,4,4,3,4,4,4,3,4,4,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,4,4,5,5,4,5,4,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,7,8,8,8,9,11,11,13,15,16,19,20,18,15,17,17,17,20,19,19,20,20,24,22,23,22,22,20,24,23,23,22,21,22,21,19,21,23,21,20,21,20,20,22,22,19,19,22,19],[28,28,28,28,28,28,28,28,28,27,26,26,27,26,26,27,26,27,27,27,27,27,27,28,27,27,28,27,28,26,26,27,28,28,27,28,27,28,28,27,28,27,26,27,27,26,26,25,25,24,23,23,23,22,22,21,20,20,19,18,15,14,10,8,7,5,4,4,4,3,3,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,7,6,6,7,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,6,5,5,5,5,4,4,5,5,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,6,6,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,4,5,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,3,2,2,2,3,3,3,3,3,4,4,4,5,5,7,8,9,10,13,15,15,13,15,17,16,16,18,18,17,18,19,20,21,21,22,21,23,22,23,20,20,22,20,20,22,22,22,21,23,24,25,25,25,25,26,27,27,27,27,27,26,27,27,27,27,27,27,27,27,27,27,26,27,26,26,26,26,26,25,27,25,24,26,24,23,24,24,22,22,21,21,20,18,15,17,13,12,11,7,6,5,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,7,6,6,5,5,5,4,5,5,5,6,7,5,6,6,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,5,6,5,5,4,3,3,3,3,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,5,6,7,7,6,5,4,4,4,4,4,4,4,5,5,6,6,6,6,7,7,6,6,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,6,6,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,4,4,5,5,4,4,4,4,4,4,3,4,3,3,3,3,3,3,4,4,3,4,3,4,4,5,4,4,5,5,4,5,4,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,6,6,6,8,9,8,9,9,11,10,12,14,14,18,18,18,16,17,17,17,19,18,19,20,20,22,22,22,22,22,22,23,22,22,23,21,22,22,20,21,22,22,22,22,21,21,22,21,20,18,22,19],[28,28,27,27,27,28,28,27,27,26,26,25,26,25,26,26,26,26,26,26,26,26,26,27,26,26,27,27,27,26,25,26,26,27,26,27,26,27,27,27,27,26,25,26,26,26,25,24,24,23,23,23,22,22,21,21,19,20,19,18,16,14,11,8,8,6,5,4,4,3,3,3,2,2,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,6,6,6,5,6,6,6,5,6,5,5,5,6,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,6,6,5,5,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,5,4,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,3,3,2,3,3,3,3,4,3,3,4,4,5,6,7,9,10,10,13,14,15,13,15,16,16,15,17,18,16,18,19,19,20,20,21,20,22,20,21,20,19,21,20,20,20,21,21,21,22,22,24,23,26,23,24,25,25,26,25,25,25,25,25,25,25,25,25,25,24,24,24,24,25,23,24,23,23,23,23,25,23,23,24,22,22,23,23,21,20,20,20,19,19,15,17,15,12,12,7,6,5,4,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,7,6,7,7,7,7,6,6,5,5,4,5,4,5,5,6,6,6,6,6,5,6,5,5,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,5,5,5,4,4,3,3,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,5,5,6,7,7,7,7,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,5,5,5,5,6,6,6,6,6,7,6,7,6,6,6,6,6,5,5,5,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,5,5,5,6,6,5,5,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,5,6,6,6,8,9,8,8,9,9,11,12,14,15,18,17,15,15,17,17,16,18,17,18,20,20,22,22,22,21,23,22,22,24,22,22,21,23,22,20,20,22,22,22,22,20,20,20,22,19,18,20,20],[28,28,28,28,28,28,28,28,28,26,26,26,27,26,27,26,26,27,26,27,26,25,26,27,26,26,27,27,27,27,26,27,27,28,26,27,27,27,28,27,27,26,26,26,26,25,24,23,25,23,23,24,23,22,20,22,20,19,19,18,15,13,11,8,7,6,5,4,4,3,3,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,5,5,5,5,5,5,5,5,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,5,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,5,5,6,9,9,10,12,14,16,13,14,17,16,15,17,18,17,18,18,19,21,19,21,21,21,21,23,20,19,22,21,20,20,21,23,21,22,23,24,24,26,24,25,26,26,26,27,26,26,26,26,26,26,26,26,26,26,25,25,25,26,24,26,24,24,25,24,25,24,24,25,23,22,23,22,22,21,20,20,19,18,15,15,14,12,11,8,6,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,5,5,5,4,4,4,4,4,4,5,6,4,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,3,3,3,4,5,5,4,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,4,5,5,5,6,7,7,6,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,6,6,5,5,5,5,5,4,5,4,4,4,4,4,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,5,5,4,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,4,5,6,6,7,8,8,8,8,10,10,12,14,15,18,19,15,14,16,18,14,18,17,17,19,19,21,21,22,21,22,20,23,22,21,22,21,21,21,18,20,21,21,18,21,19,19,20,21,18,16,19,18],[29,29,29,29,29,29,28,28,29,27,28,27,28,27,27,27,27,28,27,27,28,27,27,28,28,27,28,28,28,28,27,28,28,29,27,28,28,28,28,28,28,27,27,27,27,26,26,25,25,24,24,24,24,23,22,21,20,20,19,18,16,13,11,9,7,6,5,4,5,4,3,3,3,2,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,6,6,7,7,6,6,6,5,6,6,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,5,5,5,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,5,5,5,6,6,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,5,4,3,4,4,4,3,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,4,4,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,1,2,2,2,3,3,3,3,3,3,4,4,4,5,5,7,8,9,10,13,14,16,14,15,17,17,16,19,19,18,19,20,21,21,21,22,23,24,22,24,21,21,23,20,21,22,23,23,22,23,25,26,26,26,25,27,28,28,28,28,28,28,28,28,28,28,28,28,27,28,27,28,27,28,27,27,25,26,28,26,28,26,26,27,25,24,25,25,25,24,23,23,22,21,17,18,16,14,12,7,6,5,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,5,5,4,4,4,4,5,5,5,5,4,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,5,5,5,4,4,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,6,6,7,7,6,5,4,5,4,5,5,4,5,5,6,6,6,6,6,7,6,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,3,3,4,4,4,4,4,4,5,4,4,5,4,4,4,4,5,4,4,5,5,5,5,4,5,5,5,5,5,5,5,6,6,6,7,6,7,6,7,7,6,6,6,6,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,5,4,4,4,5,5,4,4,4,4,4,4,4,4,3,4,3,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,4,5,5,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,5,6,6,7,8,8,8,8,9,11,12,14,15,17,18,16,15,18,19,17,20,19,20,20,20,23,22,23,22,22,21,23,22,21,22,21,22,22,20,20,21,21,20,21,19,21,21,22,20,18,20,18],[28,28,27,28,28,28,28,27,28,26,25,26,27,26,26,26,26,26,26,26,26,26,26,27,26,26,26,27,26,26,26,27,27,27,26,27,26,26,27,26,27,26,26,26,26,25,25,24,25,23,24,23,22,22,20,20,19,19,18,17,15,13,11,8,7,6,5,5,5,4,3,3,3,3,3,4,4,4,4,4,4,4,5,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,7,7,8,8,7,7,7,7,7,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,5,6,5,5,5,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,7,7,7,7,7,7,7,7,8,8,8,7,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,5,5,5,5,5,5,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,4,5,5,5,4,3,4,3,4,4,4,4,4,5,4,4,5,5,5,5,6,5,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,7,8,9,10,12,13,14,12,13,15,15,14,16,16,16,16,17,19,19,18,21,20,20,19,21,20,18,20,19,19,20,20,20,20,21,22,24,22,25,23,24,24,25,25,26,25,25,26,26,26,26,26,26,26,25,25,25,25,25,24,24,24,23,24,23,25,22,22,24,22,21,23,22,20,20,20,20,19,19,16,17,15,13,12,7,6,5,4,4,3,3,3,3,3,3,3,4,3,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,7,6,6,5,5,4,4,5,5,6,7,6,6,6,5,6,5,5,5,4,4,3,3,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,4,4,4,5,5,5,5,5,5,4,4,3,3,3,2,3,2,3,3,3,3,3,4,3,3,4,4,3,4,4,4,3,4,4,4,4,4,5,4,5,5,5,4,5,5,6,6,7,8,8,7,6,6,6,5,6,6,6,6,6,7,7,8,7,8,9,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,6,6,5,6,5,5,6,6,6,6,7,7,7,8,7,8,7,8,7,7,7,7,7,6,6,5,5,4,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,5,5,5,4,4,5,4,4,5,4,4,4,3,3,3,4,3,3,4,4,3,4,4,3,3,4,4,4,5,5,5,5,6,6,5,5,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,4,3,4,4,4,5,5,5,5,6,6,5,5,5,6,5,4,5,5,4,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,3,4,5,6,7,7,8,9,9,9,9,10,11,12,12,13,16,17,16,14,17,17,15,19,16,19,20,20,22,22,22,21,21,21,23,24,22,23,20,22,22,19,20,21,21,20,21,18,20,20,21,19,17,19,19],[28,28,27,27,28,27,27,28,26,26,25,25,27,24,26,25,26,25,25,26,26,25,26,27,26,26,26,26,26,26,25,26,27,27,26,26,26,26,26,26,26,26,25,25,25,25,24,23,24,23,22,21,21,21,21,20,19,19,18,17,15,14,11,9,8,7,6,5,5,4,4,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,6,6,7,6,6,6,7,7,7,7,7,7,7,7,7,7,7,8,8,7,7,6,6,7,7,7,6,7,7,6,6,7,7,6,7,7,6,6,7,6,6,7,7,7,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,5,6,5,6,6,6,6,6,6,6,6,6,5,6,5,5,6,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,6,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,7,7,7,6,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,5,6,6,5,4,4,4,4,4,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,2,2,2,3,3,3,4,4,3,4,4,4,4,4,5,6,6,8,10,10,11,13,13,14,14,14,16,15,15,17,17,16,17,18,18,19,19,20,20,21,20,22,20,18,20,19,18,20,20,21,20,21,22,24,24,26,23,24,24,24,24,25,24,24,25,24,24,25,25,25,24,24,24,23,24,24,23,23,22,23,23,23,24,23,22,24,22,22,22,22,21,20,20,19,18,18,14,15,13,12,12,8,6,6,5,4,4,4,3,3,3,3,3,4,4,4,4,5,5,5,5,6,7,6,6,7,7,7,8,7,7,6,5,5,5,5,4,5,6,6,7,7,7,7,6,6,6,5,5,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,4,4,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,6,6,7,8,8,8,7,6,6,6,6,6,6,6,6,7,7,7,8,7,8,8,9,9,8,7,7,7,7,7,6,6,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,3,2,3,3,3,3,4,4,4,4,4,5,5,5,4,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,5,6,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,8,8,8,8,8,7,7,8,7,7,7,6,6,5,5,5,5,4,5,4,4,4,5,4,3,4,4,3,4,4,3,3,4,4,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,4,4,4,4,4,5,4,4,4,5,4,4,5,5,5,5,6,6,6,7,7,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,3,3,4,4,4,4,5,5,5,5,6,5,5,6,6,5,6,6,6,5,5,5,4,4,4,4,4,3,4,4,3,4,4,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,9,9,10,12,13,15,14,17,17,16,15,17,17,16,18,16,20,21,19,22,22,22,22,21,22,22,23,23,22,20,23,21,19,19,20,22,19,21,18,21,20,21,18,17,19,19],[28,29,28,28,28,28,29,28,28,27,26,26,27,26,27,26,27,27,26,27,26,25,27,27,26,27,27,27,28,27,26,27,28,29,27,28,28,28,28,27,28,27,26,27,27,26,26,24,26,25,24,23,24,22,22,21,21,20,19,19,16,14,12,9,8,7,6,6,5,4,4,4,3,3,4,4,4,4,4,4,4,4,5,4,5,5,5,6,6,6,6,6,6,6,7,6,6,6,7,7,6,7,7,7,7,8,8,8,7,9,9,8,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,6,7,7,7,6,7,6,6,6,6,6,5,6,6,5,5,5,6,6,6,7,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,7,7,7,7,7,7,7,7,7,7,8,7,7,7,6,7,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,4,5,5,5,5,5,5,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,5,5,5,5,4,4,4,4,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,2,2,3,3,3,4,4,4,3,4,4,4,4,5,6,6,8,9,10,11,14,14,16,13,14,17,16,15,17,18,17,17,19,20,20,21,21,22,22,22,24,20,20,22,20,19,20,22,22,20,23,23,25,25,27,25,26,27,27,27,27,27,27,27,27,27,26,27,27,26,27,26,26,26,27,26,26,24,25,25,25,26,25,26,26,23,23,23,23,22,22,21,20,19,19,16,15,14,13,12,8,7,6,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,6,5,6,6,6,7,6,6,6,6,6,5,5,4,4,5,6,6,6,5,6,5,5,5,4,4,4,4,4,4,3,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,6,6,5,6,5,4,4,3,3,3,2,3,2,2,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,8,8,8,7,7,6,6,5,6,6,6,6,6,7,7,8,7,8,9,8,8,7,7,7,7,7,6,6,6,5,6,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,6,6,6,6,6,6,6,7,8,7,8,8,8,8,8,7,7,8,7,7,6,6,6,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,4,3,4,4,4,4,4,5,4,5,5,5,5,6,5,5,5,6,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,4,4,5,5,5,5,5,6,5,5,5,5,5,5,4,5,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,5,6,7,7,8,9,9,9,9,10,11,13,13,15,18,18,14,14,17,17,15,18,18,17,20,19,21,20,21,21,21,20,22,22,21,21,20,22,21,19,19,21,19,20,21,20,20,20,22,20,16,19,19],[27,27,26,26,26,27,27,27,26,26,24,26,26,26,26,26,25,24,25,25,25,25,25,26,26,25,26,26,26,26,25,25,26,27,26,27,26,27,27,27,27,26,25,26,27,26,25,25,24,23,23,23,22,22,21,21,19,20,19,18,16,15,12,9,10,8,7,7,7,6,6,5,5,4,5,6,6,6,6,6,6,6,7,6,7,7,7,8,8,8,8,8,8,9,8,9,8,8,9,9,9,9,9,9,9,9,10,9,9,10,10,9,8,9,8,8,8,8,8,8,8,8,7,8,8,8,7,8,8,7,8,8,7,8,8,9,9,9,9,8,9,8,8,8,7,8,8,7,7,8,7,6,8,7,7,8,8,8,8,8,8,7,7,7,7,7,7,7,7,6,6,7,7,6,7,7,6,6,6,6,6,6,5,6,6,6,6,7,6,6,7,7,7,7,7,8,8,9,8,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,7,7,7,7,7,6,7,7,6,6,6,5,5,5,5,5,4,5,5,6,6,6,6,6,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,6,6,5,5,4,5,4,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,5,6,5,5,4,5,5,4,4,4,4,3,3,4,4,4,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,3,3,3,4,5,4,4,5,5,5,5,6,7,7,8,10,10,11,13,14,15,14,14,16,16,14,15,17,15,16,17,19,19,19,21,20,20,20,21,21,18,20,18,18,21,21,20,19,21,22,23,23,25,24,24,25,26,26,27,26,25,26,25,26,25,26,27,26,26,25,24,25,24,24,24,23,24,23,24,25,23,23,24,22,22,21,22,21,19,20,18,17,18,15,16,14,12,12,8,7,6,5,4,4,3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,7,8,7,7,7,6,5,6,4,6,6,6,7,7,6,6,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,4,4,4,5,6,6,6,6,5,4,4,3,3,3,3,3,3,3,4,4,4,3,5,5,4,4,5,4,5,5,5,4,6,5,5,6,6,6,6,6,7,6,6,7,7,7,8,9,9,9,8,7,7,8,8,8,7,7,8,9,9,9,9,10,10,10,10,10,9,9,9,9,9,8,8,8,8,8,8,7,7,7,7,7,7,6,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,2,2,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,8,8,7,8,8,8,7,7,8,8,8,8,8,8,9,9,10,10,10,9,10,9,10,9,9,9,8,8,7,7,7,7,6,6,6,6,6,5,6,6,4,5,5,4,5,5,4,4,4,5,3,4,4,4,5,5,5,6,6,6,6,6,6,6,6,6,7,7,6,6,7,7,6,7,7,6,6,5,4,5,6,4,4,6,5,4,5,6,4,4,6,6,5,6,6,6,6,7,7,5,6,7,7,6,6,7,6,5,6,5,5,5,5,4,3,4,3,4,4,4,5,5,5,5,6,6,6,6,6,6,6,7,7,6,5,6,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,3,3,4,4,5,6,7,7,8,9,9,9,9,10,11,12,14,15,18,18,16,13,17,18,15,18,16,19,20,20,22,22,20,20,22,23,22,21,22,20,20,21,20,18,18,21,21,18,20,18,18,20,21,18,16,18,17],[29,29,29,29,29,29,29,28,29,28,27,27,28,27,27,27,27,27,27,27,27,26,27,27,27,27,28,28,28,27,27,28,28,29,28,29,28,29,29,28,29,28,27,28,28,28,27,26,26,26,25,25,25,23,22,23,22,22,20,20,17,14,12,9,9,7,6,6,6,5,5,4,4,4,5,5,5,5,6,5,5,6,6,6,6,6,7,7,7,7,8,8,8,8,8,8,7,8,9,8,9,8,9,9,9,9,9,9,9,10,10,9,8,9,8,8,8,8,8,7,8,9,8,8,8,8,7,8,8,8,8,8,7,8,8,8,8,9,8,8,8,7,8,8,8,7,8,8,7,7,8,7,7,7,8,8,7,8,8,7,8,7,7,7,7,6,7,7,7,6,7,6,7,6,7,7,6,6,7,6,7,6,6,7,6,6,6,7,6,6,6,7,6,7,7,8,8,8,8,8,8,8,8,9,9,9,9,8,8,8,8,7,7,7,7,6,6,7,7,6,6,6,6,5,6,6,5,5,5,5,4,5,6,5,6,6,6,6,7,6,6,5,5,5,5,5,5,5,4,5,5,4,5,5,5,6,7,7,6,5,5,5,4,4,5,5,4,6,5,5,5,6,6,6,7,7,7,7,6,6,6,6,5,6,5,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,2,2,3,3,3,4,4,4,4,4,4,4,5,6,6,7,9,11,11,12,15,16,14,14,17,16,15,17,18,18,20,21,21,22,22,22,23,24,23,24,22,21,22,20,20,21,23,23,21,24,24,25,27,27,26,28,27,28,28,27,28,27,27,27,27,27,27,28,28,26,27,26,27,27,26,26,24,26,26,26,27,25,26,26,23,24,25,24,23,23,21,22,21,20,18,17,16,14,12,9,7,6,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,6,6,8,8,7,7,6,6,6,4,5,5,5,6,6,7,6,6,6,5,5,5,5,5,4,4,4,3,3,3,3,2,2,2,2,1,2,2,2,2,3,2,2,3,3,3,3,4,4,4,5,6,6,5,7,6,4,4,3,4,3,4,4,3,3,4,4,4,4,4,4,4,5,5,4,5,5,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,7,8,9,8,8,7,6,6,6,6,7,7,7,7,8,9,9,8,9,10,9,9,9,8,8,8,8,7,7,7,6,7,6,6,6,6,6,5,5,5,5,5,5,4,4,5,4,4,4,4,3,3,3,3,3,2,2,2,3,3,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,5,6,6,5,6,6,6,6,6,7,7,7,7,7,7,8,7,7,7,8,8,8,9,8,9,9,9,9,9,8,8,8,8,8,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,3,3,4,4,4,4,4,5,5,5,5,6,5,6,5,5,5,5,5,5,6,6,5,6,5,5,5,4,4,4,4,4,4,5,4,4,4,5,4,4,5,5,4,5,5,6,6,6,6,5,5,6,5,5,5,5,4,4,4,4,4,4,4,4,3,4,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,6,6,7,7,8,9,9,10,10,11,11,13,14,15,19,19,16,15,18,18,17,18,18,19,20,20,22,23,21,21,21,21,22,23,21,22,21,22,21,19,19,21,20,20,22,20,19,21,22,19,17,20,19],[27,27,26,27,27,27,27,26,27,25,25,25,26,25,25,25,25,25,26,25,25,26,25,25,26,25,26,27,26,26,25,26,26,27,26,26,26,26,27,26,27,26,26,26,26,26,25,24,24,23,23,23,23,22,21,21,20,19,19,17,15,14,11,9,8,7,6,6,6,5,4,4,4,4,5,5,5,5,6,6,6,7,7,6,7,7,8,8,9,9,9,9,9,9,9,9,9,9,10,10,9,10,10,10,10,10,11,10,10,11,11,9,9,9,9,9,9,8,8,8,8,8,8,9,9,9,9,10,9,9,9,9,9,9,10,10,10,10,10,10,10,9,10,9,9,9,9,8,8,9,8,8,8,8,8,9,9,9,8,9,8,7,7,7,7,6,7,8,7,6,7,7,7,6,8,7,7,7,7,8,7,7,7,7,8,7,8,8,8,8,8,8,8,8,8,9,10,9,9,10,10,10,10,10,10,10,10,9,10,10,10,9,8,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,5,5,5,6,5,6,6,6,6,7,6,5,6,6,6,5,6,6,5,5,6,6,5,6,6,6,7,7,7,6,6,6,6,6,7,7,6,7,7,6,7,7,7,7,8,7,7,8,8,8,7,7,7,6,6,6,6,6,6,6,5,5,6,5,5,5,5,4,4,4,3,3,3,3,3,2,3,2,2,2,2,1,2,2,2,1,1,0,1,1,2,2,3,3,3,3,3,4,4,4,4,5,6,6,7,9,10,10,13,14,15,12,13,17,15,15,17,18,16,17,18,20,20,19,22,20,22,20,22,20,20,19,18,18,19,20,20,19,20,22,23,24,25,24,25,25,26,25,26,26,26,27,26,26,26,26,26,26,26,26,25,25,25,24,24,23,25,23,23,25,23,24,25,22,23,23,22,22,21,20,21,20,20,17,18,15,14,13,8,7,5,5,4,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,6,7,7,7,8,8,8,7,6,5,5,5,5,5,5,5,8,8,6,7,7,6,5,5,5,5,4,4,4,4,3,3,3,2,3,2,2,2,3,3,2,3,3,2,3,4,4,3,4,4,4,5,6,6,6,7,6,6,5,5,4,4,4,4,5,4,4,5,5,5,5,6,5,5,6,6,5,6,6,6,5,6,6,6,6,6,7,6,7,7,7,6,7,7,8,8,9,10,9,9,8,8,8,8,8,8,8,8,9,10,10,10,10,10,11,11,10,10,10,9,9,9,9,8,8,8,8,7,7,7,7,6,6,7,6,6,6,5,6,5,5,5,4,4,5,4,4,4,4,3,3,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,6,7,7,7,6,6,7,7,6,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,8,8,9,10,9,10,10,10,10,10,9,9,9,8,9,8,7,7,6,6,6,6,6,6,5,5,6,6,5,4,5,5,4,5,5,4,4,5,5,4,4,4,5,5,5,5,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,5,6,6,6,5,4,4,5,5,4,5,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,7,5,6,6,6,6,6,6,6,5,5,5,5,5,4,4,3,4,3,4,4,4,5,5,5,5,6,6,6,6,7,6,6,6,7,6,6,6,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,4,5,6,7,8,8,8,9,10,10,10,10,11,12,13,14,15,16,18,17,15,17,18,16,19,17,19,19,20,22,22,19,21,21,22,22,23,22,22,20,21,21,19,19,20,20,19,20,19,18,20,20,18,16,18,18],[29,29,28,28,28,28,28,28,28,27,27,26,28,26,27,26,27,27,27,27,27,27,28,28,27,27,28,27,28,28,27,28,28,29,28,28,28,28,29,28,29,28,28,28,28,28,27,26,26,25,25,25,25,24,24,24,22,22,21,19,17,16,13,11,10,8,7,6,6,6,6,5,5,5,6,6,6,6,7,7,7,7,7,7,8,9,8,9,10,10,10,10,10,11,10,10,11,11,11,11,12,11,11,11,11,11,11,12,11,12,11,11,11,11,11,10,10,10,11,10,10,10,10,10,10,11,10,11,11,10,11,11,10,11,11,11,11,11,10,11,11,10,11,11,10,10,11,10,10,10,10,9,9,9,10,10,10,10,11,9,9,8,9,8,9,8,9,9,8,8,8,9,9,8,9,9,9,9,9,9,9,9,9,9,9,9,9,10,8,9,9,9,9,9,10,10,11,11,10,11,11,11,11,11,12,12,11,10,10,10,11,10,9,10,10,9,9,9,9,8,8,9,8,7,7,8,7,6,7,7,5,6,6,7,6,8,8,8,8,8,7,7,7,7,7,7,7,7,6,7,7,6,7,7,8,8,8,8,8,7,7,7,6,7,7,7,7,8,8,7,8,8,8,8,9,8,8,8,8,9,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,6,4,4,4,4,3,3,4,3,2,3,3,2,2,3,3,2,1,1,0,1,1,2,3,3,4,3,3,4,5,4,5,6,7,7,8,10,11,11,14,16,16,14,16,18,17,16,18,18,18,18,20,21,20,21,23,21,22,21,23,21,20,21,20,19,21,21,22,22,23,24,26,25,26,25,25,26,27,26,27,27,27,27,27,27,26,27,27,26,26,26,26,26,26,26,26,24,26,25,25,26,24,24,26,24,24,24,24,23,23,22,22,20,19,16,18,16,14,13,8,8,5,5,4,3,3,3,3,4,3,4,5,5,5,6,7,6,7,7,7,8,9,9,8,9,10,11,10,9,9,8,8,6,5,6,7,8,8,9,9,8,7,8,8,7,6,6,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,8,8,9,9,8,7,6,6,6,5,6,5,6,5,6,6,6,6,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,7,8,8,9,10,10,10,10,9,9,9,9,9,9,9,9,10,11,11,11,11,11,13,12,12,11,11,11,10,11,10,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,6,5,4,5,5,4,5,4,5,5,6,6,5,6,7,6,6,6,6,6,7,7,7,6,7,6,6,7,6,6,7,7,6,7,7,7,7,7,8,7,7,8,8,8,8,8,9,9,10,9,9,10,10,9,10,10,10,10,10,11,10,11,11,11,11,11,10,10,10,10,9,9,8,8,7,7,7,6,6,6,6,6,6,6,5,5,6,5,4,6,6,4,4,6,6,4,5,6,6,6,6,6,7,7,7,7,7,7,7,7,6,7,7,6,6,7,7,6,6,6,6,5,5,5,5,5,4,5,6,5,5,6,6,5,5,6,6,6,7,7,7,7,8,8,6,7,8,7,7,6,6,6,6,5,5,5,5,5,4,3,4,4,4,5,5,6,6,6,6,7,7,7,8,8,8,8,7,9,8,7,7,7,6,6,7,7,6,7,7,6,6,6,6,6,7,7,7,6,7,7,9,9,10,10,12,12,12,13,12,14,15,16,17,18,20,19,19,19,20,19,21,21,20,21,23,22,24,24,23,23,24,24,25,24,25,25,23,25,25,23,23,24,25,24,24,23,22,23,23,22,21,22,22],[29,29,29,29,29,29,30,29,29,29,28,28,29,28,29,28,28,28,28,29,28,27,28,29,27,28,29,28,29,29,28,29,29,30,28,29,29,29,29,29,29,29,28,29,29,28,28,26,27,26,25,26,26,24,24,24,24,22,21,21,19,17,14,13,11,10,9,7,8,7,6,5,7,7,8,9,8,9,10,10,10,11,10,10,11,12,12,13,12,13,13,13,13,13,14,13,13,13,14,14,14,14,14,14,14,15,15,15,13,15,15,14,13,14,15,14,13,13,13,13,13,14,13,13,14,13,12,14,14,13,14,13,12,13,13,14,13,14,13,14,14,13,14,13,13,12,13,13,12,14,13,12,12,12,13,12,13,13,13,13,13,12,12,12,12,11,12,12,11,11,11,11,11,11,11,11,12,11,11,11,11,12,12,12,12,11,12,13,12,12,12,12,12,13,12,13,13,13,12,14,13,13,13,15,14,14,13,13,13,13,13,13,12,13,13,12,12,13,12,11,11,12,11,11,10,11,10,9,10,10,8,9,9,9,10,10,10,11,10,10,10,10,9,10,9,9,9,9,9,9,8,10,10,9,10,10,11,10,10,10,11,10,10,10,10,11,10,10,10,11,10,12,11,11,12,11,12,12,12,12,11,12,10,11,10,10,10,10,10,10,9,8,9,9,8,8,9,9,8,6,5,5,6,6,4,5,6,3,3,4,4,2,3,4,4,4,2,2,1,0,1,2,3,4,4,5,4,5,6,5,6,6,8,8,10,12,14,14,16,16,17,17,18,19,18,19,20,21,20,21,22,23,23,23,25,24,25,23,25,23,23,23,22,20,22,24,23,22,22,24,25,26,25,26,27,27,27,28,28,28,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,24,27,26,25,27,25,25,26,24,25,25,24,24,24,23,22,21,19,17,18,15,14,13,10,8,6,5,4,4,4,4,4,5,4,6,6,6,6,7,7,7,8,8,9,9,10,10,9,10,12,12,12,11,11,10,9,8,7,8,9,10,10,11,10,10,10,9,9,9,8,8,7,6,6,5,5,6,5,5,3,3,4,3,6,5,4,5,6,6,6,7,7,7,8,9,8,10,9,9,11,11,10,10,8,8,7,7,8,7,7,7,7,9,9,9,9,9,10,9,9,9,11,10,10,11,10,10,9,10,10,9,10,10,10,11,9,9,10,10,10,11,11,12,12,12,12,11,12,12,12,12,11,11,13,13,13,14,13,14,15,14,14,13,13,12,12,13,12,13,12,11,12,11,11,11,10,9,10,10,9,8,9,9,8,8,8,8,7,8,7,7,5,7,7,6,5,6,7,6,7,8,7,8,9,9,8,9,9,10,9,9,10,9,9,9,9,9,9,9,9,10,9,9,9,9,9,9,10,10,9,10,10,11,11,10,13,12,12,12,12,12,12,13,13,13,13,14,13,13,14,13,14,14,12,14,12,13,13,12,11,11,10,10,9,10,9,8,8,9,7,7,8,8,6,6,7,6,5,7,7,5,6,7,7,5,6,7,8,8,8,8,9,9,9,8,9,9,8,9,8,8,9,8,8,8,8,7,8,8,7,7,6,6,6,6,5,5,6,6,5,6,7,6,6,8,8,8,9,9,8,8,9,10,8,8,8,8,7,7,8,7,7,7,6,5,5,5,5,4,5,5,6,6,6,7,7,7,7,8,8,9,9,9,9,9,10,10,9,9,9,8,9,9,8,9,9,9,8,9,9,8,8,8,9,8,9,8,10,8,10,10,12,12,13,13,13,13,13,16,16,17,19,19,22,23,22,19,21,21,21,22,22,23,24,23,25,25,25,25,25,24,27,25,25,24,25,25,25,21,23,26,25,23,25,24,23,25,26,23,22,25,23],[29,29,28,29,29,29,29,29,29,28,28,28,28,27,28,28,28,28,28,29,28,28,28,29,28,28,29,29,29,29,28,29,29,29,28,29,29,29,29,29,29,29,28,29,29,28,28,27,28,26,26,26,26,25,25,25,24,23,22,22,19,17,15,14,12,11,9,9,9,9,7,7,7,8,10,11,10,11,13,12,12,13,13,12,13,14,14,15,16,15,16,15,16,16,16,16,15,16,17,16,16,17,16,16,16,16,16,16,15,16,16,15,14,16,15,15,15,14,15,15,15,14,14,15,15,15,14,15,15,15,16,16,15,15,15,16,15,16,16,17,17,16,17,17,16,17,16,15,14,16,15,15,14,14,14,14,15,15,14,15,14,13,14,13,13,13,14,14,13,13,13,14,13,13,14,14,12,13,13,13,13,13,14,14,14,13,14,15,14,13,14,15,15,16,15,16,16,16,16,17,16,16,17,17,17,16,17,17,16,16,16,17,15,16,16,15,16,16,15,13,13,14,13,12,13,13,11,12,13,12,10,10,11,12,10,13,13,13,12,12,13,11,12,12,12,10,12,11,11,11,10,10,10,12,11,12,12,12,12,12,11,12,11,11,13,12,11,13,13,12,13,14,14,13,14,13,14,15,15,15,14,13,13,13,13,12,11,11,11,10,11,12,11,10,10,11,10,10,9,9,7,6,8,6,5,6,6,4,4,5,5,3,4,5,5,5,3,3,2,1,0,1,3,4,5,4,4,6,7,5,6,7,8,9,12,13,14,16,16,19,19,18,18,21,19,19,21,21,20,21,22,24,23,24,26,25,25,24,26,24,24,25,22,22,24,23,24,23,24,25,26,26,27,27,27,29,29,28,29,29,29,29,29,29,28,28,29,29,28,28,28,27,27,27,27,26,27,26,26,27,26,25,27,24,24,26,24,25,23,22,22,20,19,17,17,15,14,14,10,9,8,6,5,6,6,6,5,6,6,7,8,7,8,9,9,9,9,9,10,10,11,12,12,13,14,13,13,12,12,10,9,10,8,9,11,10,13,14,11,12,11,10,10,10,9,9,9,8,8,7,6,7,6,6,5,6,5,5,7,6,7,7,8,8,8,8,9,8,9,9,9,11,10,11,11,11,12,10,8,10,9,9,9,7,11,9,9,10,10,10,10,11,12,11,11,11,12,11,11,12,11,12,11,12,12,11,13,11,12,13,13,11,12,13,12,14,14,14,14,14,13,15,14,14,15,15,14,15,16,16,17,16,17,16,17,17,17,17,16,16,16,16,17,15,15,15,15,14,14,14,13,13,14,13,12,12,12,11,11,10,10,10,8,10,9,8,8,7,8,8,6,7,7,8,9,10,8,10,10,11,11,11,11,12,11,11,11,11,12,12,11,12,12,11,12,12,11,12,12,13,11,13,12,12,11,13,13,13,13,13,15,14,15,15,13,15,15,15,16,15,15,15,15,15,16,15,16,16,15,16,15,15,14,15,13,13,13,12,12,12,11,11,11,11,9,9,11,11,7,9,10,8,7,10,10,8,8,10,9,7,8,10,11,10,10,10,12,11,12,12,12,12,12,12,11,11,12,12,12,11,11,9,10,10,9,8,7,7,8,9,8,8,9,8,8,8,9,8,9,10,9,9,10,10,11,12,11,11,9,12,11,11,12,10,10,9,8,8,8,8,9,6,6,5,7,7,7,8,8,8,8,8,9,9,11,11,11,13,11,11,11,12,12,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,11,11,10,9,11,11,12,13,13,13,14,15,14,15,15,16,18,19,19,19,22,23,22,20,22,22,21,23,22,23,24,24,25,25,24,24,25,25,25,26,26,25,24,25,26,23,24,25,26,24,25,24,23,24,24,22,22,24,23],[29,29,29,29,29,29,29,29,29,28,28,28,29,28,29,28,29,28,28,29,28,28,29,29,28,28,29,28,29,29,28,29,29,30,29,29,29,29,30,29,30,29,29,29,29,29,28,28,28,27,25,26,26,25,24,25,23,23,22,22,19,18,16,13,12,10,8,7,7,6,7,6,6,6,8,8,9,9,10,9,9,10,11,9,10,12,11,12,14,13,14,15,15,14,15,16,14,15,16,16,15,16,16,16,16,16,16,16,15,16,15,15,15,15,14,15,15,14,14,14,15,14,14,15,15,14,14,16,15,14,16,16,14,16,16,16,16,17,16,16,17,16,17,17,15,16,15,14,12,14,14,12,12,13,14,13,15,14,13,13,13,12,12,13,13,10,12,13,11,12,12,13,12,12,13,13,12,12,14,13,12,11,12,14,13,12,14,16,13,13,14,14,14,15,15,16,16,16,16,16,16,16,17,17,17,16,16,16,15,14,15,16,14,16,16,14,12,15,14,11,11,13,11,10,10,11,11,9,10,11,8,9,10,10,11,11,12,11,12,12,11,10,11,12,11,11,11,11,9,11,10,11,11,12,12,12,13,12,12,11,12,11,11,12,12,11,11,12,12,11,12,13,12,12,14,13,14,14,13,13,12,11,10,10,10,10,10,9,10,10,9,10,10,10,9,10,10,9,8,6,5,6,7,6,5,5,7,6,5,6,6,6,6,7,7,7,6,4,3,3,3,0,1,4,3,3,3,4,5,5,4,7,8,7,10,12,13,16,17,19,19,19,19,21,20,20,22,21,20,22,23,23,23,24,26,25,26,25,26,25,24,25,23,21,24,24,24,24,25,26,27,26,27,27,28,28,28,28,29,28,28,29,29,28,28,29,28,28,27,28,28,28,27,27,27,25,27,27,26,26,25,25,27,24,24,25,24,23,22,21,21,19,18,17,16,14,13,13,9,9,6,6,4,4,8,7,9,7,7,7,8,7,7,9,9,9,10,10,11,11,13,13,12,13,14,14,14,13,12,12,12,11,9,9,11,10,12,13,13,11,11,10,11,9,8,7,8,7,7,6,6,6,6,6,7,6,7,7,8,8,8,8,9,10,10,12,11,11,12,12,12,13,13,13,13,14,13,13,12,12,12,11,13,9,11,9,12,12,12,12,13,12,12,13,12,11,13,12,12,12,12,13,11,11,13,11,11,11,13,12,11,10,11,12,12,14,13,14,14,14,13,13,13,12,13,14,12,12,16,16,16,17,15,16,16,16,17,16,15,16,15,15,15,15,13,12,14,12,11,12,11,10,11,11,11,9,10,11,9,8,10,9,7,7,9,7,8,7,9,8,8,9,9,10,11,11,9,11,13,11,11,12,12,11,12,12,12,11,12,11,11,12,11,12,11,11,11,11,11,11,10,11,11,11,9,11,11,11,11,11,13,12,13,14,12,12,12,12,14,14,14,14,14,14,14,15,16,14,15,15,13,13,14,13,13,11,11,10,9,9,10,9,9,10,8,7,9,9,6,6,8,7,7,7,9,7,9,9,8,9,10,9,10,12,10,10,12,13,12,12,13,13,12,11,11,11,12,10,11,11,10,8,10,9,7,7,7,6,7,7,6,7,8,8,7,8,8,8,10,10,9,9,12,11,11,13,11,13,9,11,11,11,11,8,9,8,7,8,7,7,8,5,6,8,5,7,6,6,7,7,7,7,8,10,11,12,13,14,13,12,11,13,13,13,12,13,12,13,13,13,12,13,13,12,13,12,13,13,13,12,13,12,13,13,13,14,15,14,16,17,16,16,17,18,20,20,21,22,23,23,23,22,24,23,23,25,24,24,26,23,27,26,26,26,26,26,27,27,27,27,27,27,27,25,26,26,27,25,26,25,24,25,26,23,23,25,24],[29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,28,28,28,27,29,28,27,29,29,28,28,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,28,28,29,28,28,27,27,25,25,26,25,24,23,25,23,22,22,21,20,18,15,12,10,8,7,6,6,5,5,4,5,6,7,6,7,8,9,8,9,9,9,9,9,9,10,10,11,12,11,12,12,12,12,13,14,13,14,13,14,14,13,14,14,13,13,14,14,13,13,13,12,13,12,13,14,13,13,12,13,13,13,13,13,13,13,13,13,13,13,13,12,14,13,13,14,14,12,13,13,12,13,14,12,12,13,13,11,11,12,11,10,11,11,11,12,12,12,11,11,9,9,11,10,9,11,11,10,9,11,11,10,11,11,11,10,12,11,12,11,11,11,11,12,11,12,12,11,11,13,12,11,14,13,13,13,13,12,13,14,13,13,14,14,13,12,12,12,12,13,13,11,13,13,11,10,11,11,10,10,11,10,9,9,10,9,9,9,9,7,8,9,9,8,9,10,11,9,11,10,8,9,11,10,9,10,11,8,9,10,9,9,10,9,11,11,10,10,9,8,10,9,9,9,10,9,9,10,10,9,11,10,10,11,11,11,11,10,11,11,10,9,8,9,8,9,9,9,9,8,9,9,8,7,7,7,8,7,6,5,4,6,5,3,4,5,4,3,4,5,5,4,6,6,6,5,4,3,2,2,1,0,1,1,2,2,2,3,4,4,5,5,6,9,10,13,14,15,16,17,17,17,19,18,17,18,19,19,18,22,22,21,23,24,22,25,23,25,22,22,24,22,22,23,23,24,23,24,25,27,26,28,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,26,27,26,27,27,26,27,26,26,26,25,27,25,25,26,24,24,25,23,23,22,22,21,19,18,16,16,15,13,11,9,8,6,5,4,4,3,4,4,5,5,6,8,8,7,8,8,10,10,9,10,10,11,12,11,13,13,15,14,11,12,10,10,9,9,9,10,10,11,12,10,10,10,9,10,9,8,9,8,7,6,7,6,5,5,5,5,5,5,5,6,7,6,7,8,8,9,10,10,10,11,10,10,11,11,12,12,13,11,11,10,10,9,9,9,7,8,7,9,9,10,10,10,9,9,10,9,9,9,8,9,9,9,8,8,9,9,8,8,8,9,8,8,8,8,9,9,10,11,12,11,11,11,10,10,9,10,11,10,10,12,12,13,14,13,12,13,13,13,13,13,12,12,12,11,11,10,10,10,9,9,9,8,8,8,8,8,7,8,8,6,6,7,7,6,6,6,7,6,6,6,5,5,6,7,7,9,9,7,9,10,9,9,9,8,9,9,9,9,8,9,8,7,9,8,8,7,8,8,8,8,8,7,8,7,8,7,8,8,9,9,8,10,10,11,10,9,11,11,11,11,12,12,12,12,12,12,13,13,13,12,13,11,11,11,11,11,10,9,8,8,8,8,6,7,7,5,5,6,6,4,5,6,6,5,6,7,5,5,7,7,5,6,8,8,9,8,8,9,9,9,9,9,9,8,9,8,7,8,8,8,8,7,7,7,7,6,4,4,4,4,4,4,4,5,5,5,6,8,6,7,9,8,8,9,9,9,9,9,9,8,8,8,9,8,8,8,8,6,6,6,5,4,4,4,4,4,4,6,7,6,7,7,7,8,9,9,9,10,10,9,9,9,10,10,10,10,10,10,9,10,10,9,9,9,10,9,9,10,10,10,9,10,10,10,10,12,12,13,13,14,15,15,16,16,18,19,20,21,20,23,23,22,21,23,22,22,25,23,25,26,24,26,25,26,26,25,26,27,26,26,26,25,26,26,24,25,27,26,26,27,25,25,25,26,24,24,26,26],[29,29,29,29,29,30,29,29,29,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,28,28,28,28,29,28,29,28,28,28,28,28,27,25,26,25,25,25,25,24,23,23,23,21,21,20,18,17,14,11,10,9,6,5,5,4,5,4,5,6,7,6,6,9,8,8,9,9,9,8,9,10,9,10,11,11,11,12,11,12,12,12,13,13,13,13,14,13,13,13,14,13,13,14,13,14,14,14,13,14,13,12,13,13,12,13,12,13,12,12,13,13,13,13,13,13,13,13,12,12,12,14,12,14,12,13,13,12,12,13,12,12,12,12,11,12,12,10,10,11,12,11,12,11,12,11,10,9,9,10,10,9,10,12,10,10,10,11,10,11,11,11,11,10,11,11,11,12,11,11,11,11,11,12,11,11,12,11,11,13,12,13,13,13,12,13,13,12,13,14,14,14,12,12,11,11,12,12,11,12,12,11,11,11,11,10,10,11,10,10,9,10,10,8,9,9,8,8,9,8,9,10,10,10,10,10,10,10,9,10,10,10,9,10,10,9,9,9,10,10,10,11,11,11,10,10,11,9,10,9,10,10,10,10,10,10,10,11,10,10,10,11,12,11,10,10,10,10,10,9,8,9,9,8,8,8,8,8,8,8,8,8,8,8,7,6,5,4,6,5,4,4,5,5,4,5,5,4,5,6,6,6,5,5,4,3,4,2,1,0,1,1,1,1,2,3,3,4,4,6,8,10,13,14,14,16,16,16,17,17,17,17,18,18,18,20,20,21,22,22,23,24,23,23,24,23,24,24,22,23,24,23,24,23,24,26,26,25,27,27,27,28,28,27,28,28,28,28,28,28,27,28,28,28,27,27,27,27,27,26,27,25,26,26,26,27,25,25,26,23,24,25,23,23,22,20,20,19,17,15,14,16,13,11,9,7,6,5,4,4,4,4,5,5,6,7,8,7,7,8,9,9,10,11,10,11,12,12,12,13,13,14,14,13,12,12,11,10,10,10,11,10,12,14,12,12,10,10,9,9,8,8,8,7,7,7,6,6,6,5,5,5,5,5,6,6,6,7,7,7,8,9,9,9,10,10,10,10,11,11,11,11,12,11,10,9,9,9,9,8,9,8,9,9,9,9,9,10,10,9,9,8,10,9,8,9,9,9,9,10,9,8,9,9,8,8,9,8,8,8,9,9,11,11,11,12,10,10,10,10,10,11,10,10,12,13,12,12,14,13,13,12,13,12,12,11,12,10,11,10,10,9,9,8,8,9,8,8,8,8,7,7,8,7,7,6,7,7,6,6,6,6,6,5,6,5,5,6,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,7,8,8,8,8,7,8,8,9,8,8,8,7,8,7,7,9,6,7,8,8,8,9,9,8,10,10,9,10,10,10,11,11,11,11,11,12,12,12,12,12,12,12,11,10,10,10,10,9,8,8,7,6,7,6,6,6,6,5,6,6,5,5,6,6,5,5,7,5,5,6,6,5,7,8,8,7,8,7,9,8,8,8,8,8,8,9,8,7,8,8,8,8,7,7,7,6,5,4,3,4,5,5,4,5,5,6,4,5,8,6,6,7,7,8,8,8,9,9,8,9,8,7,8,9,9,7,7,7,5,6,6,5,4,4,5,4,4,5,6,7,6,7,8,6,8,8,8,9,10,9,9,9,9,10,9,10,9,9,9,8,8,9,10,9,9,9,10,8,9,11,9,9,10,10,11,10,12,12,13,13,14,16,15,15,16,17,18,19,21,20,22,22,22,21,22,22,23,25,23,24,25,24,26,25,26,25,25,25,26,25,25,26,25,25,26,23,24,25,25,24,26,25,25,26,27,24,24,26,24],[29,29,29,29,30,30,29,29,29,29,28,28,29,28,29,28,29,29,28,29,29,28,29,29,28,29,30,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,28,28,29,28,27,26,27,25,25,25,25,24,23,24,22,21,21,21,18,16,13,10,8,7,6,5,5,4,4,4,4,4,6,6,7,7,8,7,8,9,9,9,9,10,10,10,11,11,10,12,11,11,12,12,12,12,12,12,13,12,13,13,14,13,15,14,13,13,14,13,12,13,11,13,13,12,12,13,13,11,11,12,13,13,12,14,12,12,13,12,12,12,12,14,13,13,13,13,13,12,12,13,12,11,12,11,11,11,11,10,10,9,11,11,11,11,11,9,10,8,8,9,9,9,8,10,9,8,9,10,9,9,10,11,9,10,11,10,11,10,10,11,11,10,11,11,12,10,12,11,11,12,12,14,14,13,12,13,14,13,13,14,14,14,12,12,12,13,12,12,12,12,12,12,11,10,11,10,10,11,11,8,8,10,8,7,8,8,7,7,8,8,9,9,9,10,10,10,9,9,9,10,9,9,9,8,8,9,9,10,9,9,9,11,11,10,10,9,9,9,9,9,10,9,9,9,12,9,9,10,11,10,10,11,12,11,11,11,11,11,10,8,9,9,8,8,8,8,8,8,7,7,7,8,7,7,5,5,5,4,4,4,4,4,4,4,4,5,5,4,6,7,6,6,6,5,4,3,3,3,1,1,0,1,1,1,2,2,3,4,5,6,8,9,11,14,14,15,16,16,16,18,17,16,18,18,18,20,20,21,22,22,23,22,24,23,24,22,22,23,23,21,23,24,24,23,24,25,25,26,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,27,27,27,27,27,26,27,26,26,27,25,26,25,24,26,23,24,24,23,23,23,21,21,20,18,16,16,15,13,11,9,8,5,4,3,4,3,3,4,5,5,6,6,6,7,7,7,8,8,8,9,9,11,11,11,11,13,13,13,11,11,10,10,9,9,9,10,9,12,14,10,11,10,9,9,8,8,7,8,7,7,6,6,6,5,5,4,5,4,5,5,6,6,6,6,7,7,8,7,8,8,8,9,10,10,12,11,11,11,10,9,9,8,8,8,8,8,7,8,8,8,8,8,9,9,8,8,9,10,8,8,8,9,9,9,10,9,8,9,10,8,9,8,7,7,9,9,10,11,11,11,12,10,10,10,11,11,11,10,11,12,12,13,13,13,12,13,12,13,13,11,11,11,10,11,10,10,10,10,9,8,9,8,9,8,8,7,8,7,7,6,6,7,7,6,5,6,6,4,5,6,5,5,6,6,7,6,7,6,7,7,8,8,7,8,9,7,7,8,8,10,9,8,8,9,8,8,8,9,7,8,8,8,8,7,8,8,8,8,8,8,8,9,7,9,9,8,10,9,8,10,10,11,10,11,11,11,12,12,11,11,11,11,11,10,10,9,8,8,8,6,6,7,6,7,7,6,5,6,6,5,5,6,6,5,5,7,5,5,6,6,6,6,8,7,7,8,8,8,8,9,7,7,8,8,9,7,8,8,8,7,8,7,6,7,6,5,4,3,3,5,5,4,4,5,5,5,6,7,6,6,7,7,7,7,8,8,8,8,8,6,7,8,8,7,7,7,6,6,6,6,5,4,5,4,3,4,5,6,6,5,6,7,7,7,7,8,7,9,9,8,10,9,10,8,8,8,8,8,7,8,7,8,8,8,8,8,7,8,9,8,8,9,9,10,8,11,12,13,13,14,17,15,15,15,18,18,18,21,21,23,23,23,22,23,23,22,26,23,25,25,24,26,26,26,26,26,26,27,26,26,27,25,26,27,24,25,26,26,25,27,26,26,26,27,25,25,27,25],[29,28,28,28,29,29,29,29,29,28,27,26,27,27,27,27,27,28,27,28,28,27,28,28,27,28,28,28,28,28,27,28,29,29,28,29,28,28,29,28,29,27,28,27,28,27,26,24,26,25,24,24,24,23,22,22,22,20,20,20,17,16,14,10,9,7,6,5,5,4,5,5,5,5,6,6,6,6,8,8,8,7,8,8,8,9,9,10,10,10,10,11,10,10,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,11,11,12,11,11,12,10,10,12,12,11,11,12,11,11,13,11,11,12,12,13,11,13,11,12,12,11,11,12,10,11,11,10,10,10,10,9,9,9,10,10,10,10,10,10,9,8,8,10,9,8,8,9,9,8,9,9,8,8,9,9,8,9,10,10,10,8,9,10,9,9,10,11,9,9,12,11,10,11,11,12,12,13,12,12,13,13,12,12,12,12,12,11,11,10,12,11,9,12,12,10,10,10,9,9,9,9,8,8,8,8,8,8,7,7,6,6,8,8,8,7,8,8,8,9,7,8,7,8,8,8,8,8,7,7,8,7,7,8,8,9,10,9,9,8,7,8,8,7,8,8,8,8,9,8,9,9,10,9,9,10,10,10,10,10,9,9,9,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,5,5,4,4,4,4,4,5,3,4,4,5,4,5,5,5,5,5,4,4,3,3,3,1,1,1,0,1,1,1,2,2,3,4,5,7,10,12,13,13,15,15,15,16,16,16,15,16,16,16,17,19,19,19,19,22,21,22,20,23,21,21,22,20,21,22,23,24,22,23,24,26,26,27,26,27,27,28,27,28,27,28,28,28,27,28,28,28,28,27,27,26,27,27,25,26,24,25,25,23,25,24,23,25,22,23,23,22,22,20,20,19,18,17,14,15,13,12,11,8,7,5,4,3,3,3,4,4,5,6,6,7,7,7,8,8,8,9,9,9,9,10,11,9,11,12,14,13,11,11,10,9,9,8,9,9,9,11,12,10,10,10,8,9,8,7,8,7,6,6,6,6,5,5,5,5,5,4,4,5,6,6,7,7,7,7,7,8,8,8,8,8,9,10,10,10,10,10,9,9,8,8,7,6,7,6,6,6,7,7,7,7,7,8,7,7,7,7,7,8,7,8,8,8,8,8,7,8,8,8,8,8,7,8,9,8,9,11,10,11,10,9,10,10,9,10,10,9,10,11,12,12,12,13,11,12,13,13,12,11,11,11,10,10,10,11,10,9,9,9,9,8,8,8,8,7,7,7,7,6,5,6,6,6,5,5,5,5,5,5,5,4,5,5,6,6,7,6,7,6,7,7,7,7,8,8,7,8,7,8,8,7,8,8,8,7,7,7,7,8,8,7,8,7,8,7,7,8,8,8,8,9,8,9,9,8,9,9,9,10,10,10,10,10,10,11,11,11,11,11,11,10,10,10,10,9,8,7,7,6,6,6,6,6,7,6,5,5,6,5,5,5,5,5,5,6,5,5,6,7,5,6,7,7,7,8,8,8,9,8,8,8,8,7,8,8,8,8,8,7,7,7,5,7,6,5,4,3,3,4,4,4,4,5,4,4,5,7,5,7,8,7,7,8,8,8,8,8,9,7,6,7,7,7,6,7,6,5,6,5,5,3,3,4,3,4,5,5,6,6,6,8,7,7,8,8,8,9,9,9,9,9,10,9,8,9,8,8,8,8,8,8,8,8,8,8,7,8,8,8,8,8,8,8,8,10,11,12,12,13,14,14,14,15,16,18,18,19,20,22,22,22,20,22,21,20,24,22,23,25,25,25,25,26,24,26,24,26,26,25,26,25,26,26,24,24,26,26,23,26,24,24,25,26,23,23,26,24],[29,29,28,29,29,29,29,29,29,28,28,27,28,27,27,28,28,28,27,28,27,26,27,28,27,27,28,27,27,28,27,28,28,29,27,28,28,28,29,28,29,28,28,27,27,27,26,25,26,25,24,24,24,24,23,23,21,20,20,19,18,16,14,10,8,6,5,4,4,3,4,4,4,4,5,5,6,6,7,7,7,7,8,7,8,9,8,10,9,9,10,10,10,10,10,10,11,11,11,10,11,11,11,11,11,11,12,12,11,12,12,11,11,11,11,11,11,10,11,10,11,10,10,10,11,11,10,11,11,11,10,11,11,10,11,12,12,12,11,11,12,11,11,11,11,11,10,10,9,10,9,9,9,9,10,10,10,10,9,10,10,8,8,9,9,8,9,9,9,8,9,9,9,8,9,9,9,9,9,9,10,8,9,9,10,9,9,9,9,9,9,10,9,10,10,11,11,12,11,12,12,12,12,12,11,11,11,10,10,10,10,10,10,10,10,9,9,9,9,8,9,8,8,8,8,7,7,7,8,7,6,6,7,6,8,8,7,8,8,8,8,7,7,8,7,6,7,8,7,7,7,7,7,8,8,9,10,9,9,8,7,7,7,7,8,7,7,8,8,7,8,8,9,8,9,9,9,9,9,8,9,8,7,7,7,7,7,7,7,6,7,6,7,6,6,6,6,6,6,5,4,4,5,4,3,3,5,3,3,5,5,4,5,5,4,5,5,4,4,3,3,2,1,1,1,1,0,1,1,1,2,2,3,4,5,7,9,11,14,16,16,14,15,16,16,15,17,16,18,18,19,19,20,21,22,22,23,22,24,22,22,23,22,21,22,22,24,22,23,25,26,26,26,26,27,28,28,28,29,29,29,28,29,29,28,28,28,28,27,28,27,27,27,26,27,24,26,26,25,26,24,24,26,22,23,24,21,22,21,19,19,18,16,15,15,13,12,9,8,6,4,3,2,2,3,4,3,5,5,5,6,5,6,7,7,6,8,8,8,9,10,10,9,11,11,11,11,11,10,9,9,8,8,8,9,8,11,11,10,9,8,8,8,7,7,6,6,6,5,5,5,5,5,5,4,4,4,5,5,5,5,6,7,6,7,7,8,8,7,7,8,9,8,10,10,10,9,9,8,8,8,7,6,6,7,6,6,7,7,7,7,8,7,7,7,7,7,7,6,8,7,7,7,7,8,6,7,7,7,7,7,6,6,7,7,8,9,10,10,9,9,9,8,8,9,9,8,8,10,10,10,10,11,11,11,10,10,11,10,10,10,9,9,9,9,8,8,8,8,7,7,7,7,7,6,6,6,7,5,5,6,6,5,5,5,4,5,5,5,4,5,6,5,5,7,6,6,6,7,7,6,6,6,7,7,6,7,6,7,6,6,7,7,6,6,6,6,6,6,6,5,6,6,6,5,6,6,7,7,7,8,8,9,9,8,9,9,9,10,9,10,9,9,10,10,10,10,10,10,10,9,9,9,9,9,8,7,7,6,5,6,5,6,5,4,4,5,5,4,4,4,4,4,4,5,4,5,5,5,4,5,6,6,6,6,6,7,7,7,7,6,7,6,7,5,5,6,5,5,5,4,4,4,4,3,3,2,3,3,3,2,3,3,4,3,4,5,4,5,6,5,5,6,6,6,6,6,6,5,5,5,6,6,4,5,5,4,4,4,4,3,2,3,3,3,4,5,5,5,5,4,5,5,6,6,6,7,7,7,7,8,8,8,7,7,7,7,7,7,7,8,7,7,8,8,6,7,8,8,7,7,7,8,8,10,10,12,12,13,14,13,13,14,15,17,17,19,19,21,21,21,20,21,20,20,24,21,23,24,22,25,24,25,24,24,24,26,26,25,25,24,25,24,22,24,25,25,22,25,23,22,24,25,22,21,24,23],[29,29,29,29,29,30,29,29,29,29,29,28,29,28,28,28,28,29,28,29,29,28,28,29,28,29,29,29,29,29,27,29,29,29,29,29,29,29,29,29,29,28,28,28,28,27,27,26,26,25,25,24,24,24,22,23,22,21,21,21,18,15,12,8,8,6,5,5,4,4,4,4,5,5,5,5,6,8,8,6,7,8,7,7,8,8,9,10,10,9,10,10,10,11,10,11,11,12,11,11,12,12,12,12,12,12,12,13,12,13,13,12,11,11,11,11,11,11,11,12,12,12,11,11,12,11,11,12,12,12,12,12,11,11,12,13,12,12,12,11,12,11,11,12,11,10,11,11,9,10,10,10,10,10,10,10,10,10,10,10,9,7,9,9,9,8,9,10,9,9,9,10,10,10,10,10,10,9,10,10,10,10,10,10,10,11,10,11,11,10,11,10,11,11,11,11,12,13,12,13,13,13,12,13,13,12,11,11,11,11,11,11,10,11,11,10,10,9,10,9,9,9,9,8,8,9,9,8,8,9,7,7,8,8,9,9,8,9,9,9,9,9,8,9,9,8,8,9,9,9,8,9,9,9,9,10,11,10,10,9,9,9,9,9,9,9,9,9,10,9,9,10,10,9,10,10,11,10,10,10,10,9,9,7,8,8,7,7,7,7,7,7,7,8,7,8,7,7,7,5,5,4,5,5,4,4,6,4,4,6,6,5,5,6,6,6,5,4,4,3,3,3,2,1,1,1,1,0,1,1,2,2,4,5,6,7,8,11,11,15,16,13,13,18,17,14,18,17,17,18,19,19,20,21,22,23,23,22,24,23,22,23,22,20,22,22,24,23,24,25,26,25,28,26,27,27,27,27,28,28,28,28,28,28,28,28,27,27,27,27,27,26,27,26,27,25,25,26,24,26,24,24,26,23,23,24,22,22,22,20,20,18,17,16,15,15,11,9,8,6,4,4,3,2,3,4,4,5,5,6,6,6,6,7,7,7,8,8,8,9,11,10,11,11,12,12,13,11,12,10,10,9,8,8,10,9,11,12,10,10,9,9,8,7,7,6,7,6,6,5,5,5,4,5,4,5,4,5,6,6,6,7,7,6,7,8,8,8,8,8,9,10,10,11,11,10,10,10,9,8,9,8,8,8,8,8,8,8,9,9,8,9,9,9,8,8,10,8,8,9,8,8,8,8,7,7,8,8,8,8,7,7,7,8,8,9,10,10,11,11,9,9,8,9,9,10,9,10,10,11,10,11,11,11,11,11,11,11,10,9,9,9,9,8,8,8,8,7,7,8,7,7,7,7,5,6,7,7,6,6,7,6,5,5,7,6,5,7,7,5,6,7,6,7,7,8,7,7,8,8,7,8,7,8,8,8,8,7,8,8,7,8,6,7,7,6,6,7,6,6,5,6,6,6,6,5,8,7,7,7,8,7,8,8,8,9,9,9,9,9,10,9,9,10,10,10,10,10,9,10,9,9,9,8,9,7,7,6,6,5,5,5,5,5,4,4,5,5,4,5,5,4,4,5,6,4,5,7,6,5,6,6,7,7,7,6,8,8,7,7,7,7,7,7,6,6,6,7,7,7,6,5,5,5,4,3,3,2,5,5,3,3,5,5,4,5,5,5,5,7,7,6,7,7,7,7,7,7,7,6,7,7,7,5,6,6,4,5,5,4,3,3,3,3,3,4,5,5,5,5,5,6,6,6,7,7,8,8,8,8,8,9,8,8,8,8,9,8,8,8,9,8,8,8,10,7,8,9,9,8,8,9,9,9,11,12,13,12,13,15,15,14,16,17,18,18,21,20,22,23,23,21,22,22,22,25,23,25,26,23,26,26,26,25,26,26,27,26,26,27,26,25,27,24,26,26,26,25,26,25,25,26,27,25,24,26,25],[29,29,29,29,29,29,29,29,29,29,28,28,28,28,29,28,29,29,29,29,29,28,29,29,28,29,29,29,29,29,28,29,30,30,29,29,29,29,29,29,29,29,28,29,29,28,27,26,27,26,25,25,24,24,23,23,22,20,21,21,18,16,14,10,8,7,6,6,5,5,4,4,5,6,7,6,6,7,9,8,8,10,10,10,10,11,12,12,12,12,12,13,12,12,13,13,13,13,14,14,14,14,14,14,14,13,14,13,13,13,14,13,12,14,13,13,13,13,12,13,13,13,12,13,14,13,13,14,13,13,14,13,12,14,13,14,13,14,13,14,13,13,13,14,12,12,14,12,13,13,12,12,12,11,12,12,12,12,11,11,9,9,9,11,12,10,10,12,11,10,12,13,11,10,12,11,11,12,12,11,11,10,11,12,12,11,12,13,11,11,13,12,12,13,13,15,15,14,13,14,15,14,15,15,14,14,14,13,12,12,13,13,11,14,13,11,12,12,11,12,12,12,11,10,10,12,10,10,9,10,8,7,8,8,9,9,10,10,9,11,10,9,10,11,11,10,10,10,10,11,10,10,10,10,9,10,11,11,11,10,9,10,10,10,10,10,10,11,11,10,10,11,11,10,11,12,13,12,11,12,11,11,10,9,11,10,9,9,9,9,9,10,9,9,8,9,8,8,8,8,6,5,6,5,5,5,7,5,6,6,7,6,7,7,7,7,6,6,6,4,5,4,2,2,2,2,1,1,0,1,2,3,3,5,6,6,9,12,12,16,15,13,14,15,16,15,17,17,17,18,19,19,19,20,23,22,24,21,24,22,22,23,21,21,22,22,24,22,24,24,27,26,27,26,27,28,28,27,28,28,28,28,28,28,28,28,28,28,27,27,26,27,28,26,27,24,25,26,24,26,24,24,25,23,24,25,22,22,23,21,20,20,18,17,17,16,13,13,10,8,5,4,4,3,4,5,4,6,5,7,7,7,8,8,8,9,10,11,11,11,12,14,12,13,15,15,15,13,13,12,11,10,10,10,12,10,13,15,13,11,11,10,10,9,9,8,9,8,7,7,7,7,5,5,5,6,5,6,6,7,7,8,8,7,8,8,9,9,9,10,10,11,12,13,13,12,13,12,10,10,10,10,8,9,9,9,9,9,9,8,9,10,10,9,9,9,10,9,9,9,9,9,9,10,10,9,10,10,10,10,9,9,8,9,10,10,11,12,12,12,12,11,11,11,11,12,11,12,12,12,14,14,14,12,14,14,13,12,12,12,12,12,11,11,11,11,11,10,10,11,10,10,9,10,10,7,8,9,8,7,8,8,6,7,8,7,7,7,7,6,6,8,7,8,7,9,8,8,8,9,8,8,8,8,8,8,9,8,9,8,8,9,9,9,9,9,9,9,9,8,8,7,8,9,7,7,9,9,8,10,11,9,11,11,10,11,11,10,12,12,11,11,12,12,12,12,12,12,12,11,11,11,11,10,10,8,8,7,7,6,6,6,7,7,6,6,7,6,5,6,7,5,4,6,6,5,5,7,7,5,7,7,8,8,8,8,9,9,9,9,9,9,8,8,9,9,9,7,9,9,8,6,6,6,5,4,3,3,5,4,4,4,6,5,5,6,7,6,7,9,8,7,8,9,9,9,9,9,8,7,8,8,8,7,7,7,7,6,5,6,4,4,4,4,5,4,6,6,7,6,7,8,7,8,8,9,10,10,10,11,9,11,10,9,10,10,9,8,9,9,9,9,10,9,9,9,10,10,9,11,10,9,9,11,13,13,14,14,15,16,16,16,16,18,21,20,21,21,23,24,23,21,23,23,22,26,24,25,27,24,27,26,27,26,26,25,27,28,27,28,27,27,27,25,26,27,27,26,27,25,26,26,27,26,24,26,27],[29,29,29,29,29,30,29,29,29,28,28,28,29,28,28,29,28,28,28,28,28,28,28,29,28,28,29,28,28,29,27,29,29,29,28,28,28,28,29,28,29,28,27,28,28,27,26,25,25,25,24,25,24,23,22,22,21,20,20,20,19,17,13,9,9,7,6,7,6,6,5,5,6,7,7,7,8,9,9,9,10,10,9,10,10,11,11,12,13,12,13,14,13,12,14,16,13,15,15,15,14,15,15,15,15,15,15,15,14,14,15,14,14,15,14,14,14,13,13,14,14,13,13,14,15,13,15,15,14,13,14,15,14,14,15,15,15,16,15,14,16,16,15,15,13,15,14,13,12,13,12,11,12,12,12,12,14,13,11,13,11,10,10,11,11,10,10,12,11,11,11,12,12,11,11,11,11,12,12,12,12,11,12,13,12,12,13,14,12,12,14,14,12,14,14,14,15,15,14,15,15,14,15,15,16,15,14,15,14,13,14,14,12,16,14,13,13,13,12,11,11,11,10,10,10,10,10,9,9,9,8,8,9,9,9,9,10,10,10,11,11,10,10,11,10,10,10,10,10,10,10,10,10,11,11,11,12,12,12,11,9,10,10,11,12,10,10,11,11,11,12,12,12,11,11,12,12,13,13,12,12,11,10,11,10,10,9,9,8,8,9,9,8,8,8,8,8,8,7,7,6,5,7,7,6,6,6,6,6,7,7,6,8,8,8,8,8,7,7,6,5,5,3,3,3,2,2,2,1,0,1,2,3,4,6,7,8,11,12,15,15,13,14,15,15,14,16,15,15,17,19,18,19,20,22,21,23,22,23,22,21,23,22,20,22,22,24,23,24,26,27,26,28,26,28,28,28,27,29,28,28,28,28,29,29,28,28,28,27,28,27,28,28,27,27,25,26,26,24,26,24,24,25,22,23,23,21,21,21,19,19,19,18,16,15,12,13,11,9,7,6,5,4,6,5,6,6,8,8,10,9,9,9,10,10,11,11,12,11,12,13,13,12,13,15,15,15,13,15,13,12,12,11,12,12,12,14,15,12,12,13,11,11,11,10,10,11,9,8,8,8,8,7,7,7,8,7,7,9,10,9,11,11,11,10,11,11,12,12,12,13,13,13,13,13,12,14,13,12,12,11,11,10,9,9,9,9,10,10,9,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,11,10,10,11,10,9,10,11,11,12,13,13,13,12,12,12,13,11,12,13,11,12,14,14,14,14,15,13,14,15,14,13,14,12,13,12,12,13,12,11,11,11,11,11,10,11,10,10,10,9,9,9,8,7,8,9,6,7,8,8,6,7,8,8,7,8,9,10,9,10,11,10,9,11,10,10,9,10,10,9,10,10,11,10,10,10,10,11,10,10,9,10,11,10,10,11,11,11,9,10,10,9,10,9,11,9,11,12,10,11,11,10,12,12,12,12,12,13,13,13,13,12,13,13,12,12,12,11,11,9,9,9,8,9,8,8,8,9,7,7,7,8,5,6,7,6,6,8,9,6,6,9,9,6,9,10,10,9,11,11,11,11,11,11,10,11,10,11,10,11,11,9,10,11,8,6,8,7,5,4,3,3,5,5,4,5,5,6,6,7,8,7,10,10,10,10,10,11,11,10,9,11,8,9,9,11,10,6,7,7,6,6,6,5,5,4,5,5,5,6,7,9,8,8,9,7,9,10,9,10,10,11,10,11,11,12,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,12,11,11,12,13,13,15,15,15,17,16,17,16,19,19,20,21,20,23,22,22,22,22,21,23,24,24,23,26,24,25,25,27,25,26,25,26,26,26,27,26,26,26,25,26,26,26,25,26,24,25,26,26,25,24,25,26],[29,29,29,29,29,30,29,29,29,29,29,28,29,28,28,28,29,28,28,28,28,27,28,28,27,28,29,28,28,29,27,28,29,29,28,28,28,28,28,27,28,27,27,27,27,26,25,24,25,24,24,23,23,22,22,22,21,21,21,20,18,15,12,9,9,7,5,6,5,6,5,6,6,8,8,8,9,9,10,10,11,10,12,9,10,13,12,14,15,14,15,15,15,15,15,15,15,14,15,16,16,16,16,17,17,15,17,17,16,16,15,15,15,15,16,14,15,15,16,15,15,14,15,16,16,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,15,16,15,14,16,15,15,14,15,14,13,15,15,14,13,13,11,11,13,13,11,12,14,12,12,12,13,12,13,15,14,13,15,15,14,14,14,14,15,15,15,16,17,14,14,15,15,14,16,15,16,15,16,16,16,16,15,16,16,17,16,16,15,15,14,16,16,14,16,16,15,14,15,14,12,12,13,12,10,11,11,10,10,11,11,8,9,10,9,11,11,11,12,12,12,12,11,12,13,11,11,12,12,11,12,13,11,12,14,13,13,15,14,13,14,12,11,12,12,13,11,10,13,13,12,12,14,13,12,14,14,14,14,14,14,13,12,11,10,10,10,10,9,10,9,10,9,10,9,9,10,10,9,9,8,7,6,7,7,7,7,7,7,7,8,7,9,9,9,9,9,9,8,7,6,5,4,4,4,4,3,3,3,2,1,0,1,3,4,6,7,8,8,10,13,14,11,12,15,14,13,15,15,16,17,18,18,19,20,21,21,22,22,24,22,21,24,22,21,23,23,23,22,24,25,27,26,26,26,26,27,27,27,28,28,28,28,28,27,27,27,27,27,26,26,27,26,26,26,26,23,25,25,24,25,23,23,25,22,22,23,20,21,20,19,19,17,15,16,15,14,12,10,10,8,6,5,5,4,5,6,6,8,9,9,9,9,9,11,10,10,13,12,12,13,14,13,14,14,16,15,16,16,14,13,14,13,13,12,13,13,14,16,15,13,12,11,12,11,11,10,11,9,9,9,9,8,7,7,8,9,9,8,9,9,10,11,10,11,12,11,12,13,12,12,13,14,14,14,14,13,15,15,13,13,12,13,12,12,11,11,11,13,11,12,12,14,12,12,13,12,13,11,11,12,12,11,12,11,12,11,11,11,11,12,12,10,10,11,11,12,12,12,13,14,14,13,13,12,14,14,13,14,15,14,16,15,16,14,15,16,15,15,14,13,14,14,12,13,13,12,12,12,11,12,11,10,10,10,9,9,10,9,8,8,10,9,8,8,10,8,7,8,10,8,7,10,10,10,11,10,11,11,10,11,10,10,10,10,11,11,11,9,10,9,9,11,8,9,10,9,7,9,10,9,7,7,9,9,7,8,10,9,11,10,11,11,13,13,11,13,12,12,14,14,14,14,13,13,14,14,13,13,12,13,13,12,11,11,11,9,10,8,7,7,9,8,8,8,7,7,7,7,6,6,6,7,6,7,7,6,7,8,7,7,7,9,10,10,8,8,13,12,10,10,11,11,9,8,7,8,8,7,6,8,7,6,6,6,4,5,5,5,5,6,4,6,6,7,6,7,8,7,7,8,9,8,10,8,10,9,8,8,7,8,8,8,9,6,7,7,6,6,6,5,4,4,7,5,5,6,7,7,6,7,6,7,8,9,9,10,10,11,11,11,10,11,11,12,10,12,12,11,13,11,12,10,13,12,13,12,14,13,11,13,14,12,12,13,14,14,15,16,16,17,17,16,17,19,20,20,21,22,24,23,24,23,24,23,23,26,24,26,27,25,27,27,27,27,27,26,28,28,27,27,27,27,27,24,27,28,27,24,27,25,25,26,27,25,23,25,25],[29,28,29,29,29,29,28,29,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,27,28,29,27,29,28,27,28,29,29,28,29,28,29,28,28,29,28,28,28,27,27,27,25,25,25,24,23,23,23,21,22,21,19,19,18,16,15,11,8,8,5,6,6,5,6,6,7,9,11,11,9,10,11,11,11,10,12,11,11,12,12,12,14,14,14,14,15,15,15,16,16,16,16,16,16,17,17,16,17,17,16,17,16,17,17,16,15,14,16,17,15,15,16,16,16,16,14,16,16,16,17,16,17,16,16,17,16,16,16,15,16,17,16,17,17,17,16,16,17,16,17,16,16,14,15,15,14,13,15,14,15,15,14,14,15,13,12,14,13,13,13,12,14,13,14,13,15,14,14,14,14,14,16,15,16,15,15,15,15,16,15,15,15,15,15,16,14,16,15,16,16,16,16,16,16,16,15,15,16,15,16,15,14,14,14,16,16,14,16,15,15,13,15,14,13,13,14,14,13,12,13,12,11,12,12,11,11,11,10,12,12,13,14,13,14,12,13,13,14,14,13,13,14,13,14,14,12,13,13,13,14,15,14,14,14,13,12,13,14,14,12,12,13,14,12,13,13,13,13,12,13,13,13,12,13,12,12,11,11,11,12,10,10,10,11,12,11,11,10,13,10,10,11,11,10,9,8,9,10,7,8,9,10,9,9,11,11,9,10,10,10,10,8,9,8,6,5,5,4,5,4,3,3,4,2,1,0,1,2,4,5,6,8,7,11,10,9,9,14,12,11,15,15,14,15,16,17,16,18,21,20,23,21,22,22,20,22,21,19,22,22,23,22,23,24,26,25,26,25,26,27,28,27,27,28,28,28,28,28,27,28,28,27,26,27,27,26,26,25,26,24,25,25,23,25,23,24,24,21,20,22,20,18,20,16,18,18,17,17,14,15,12,12,10,8,7,6,4,6,6,7,8,8,10,11,10,10,12,12,11,12,12,13,13,13,14,14,14,13,16,17,16,16,16,15,14,14,14,14,14,12,16,16,13,14,13,12,12,12,11,11,12,11,10,10,10,9,9,9,10,11,10,10,11,12,11,14,13,13,14,15,15,14,15,15,14,15,14,15,15,16,16,15,15,14,15,14,14,13,12,14,14,14,14,14,14,14,14,14,13,12,14,12,13,12,13,12,12,12,11,11,11,11,11,11,11,10,9,11,10,12,12,13,14,13,13,13,13,12,12,14,13,13,14,14,16,14,16,13,15,16,14,14,13,13,13,13,12,12,12,12,11,11,12,11,12,10,10,12,10,11,11,12,10,10,10,10,11,10,11,11,10,10,12,11,10,11,11,14,13,13,14,12,12,14,13,12,12,12,12,12,12,10,11,10,10,10,10,9,10,10,9,8,10,8,7,9,9,9,9,9,10,10,11,10,11,10,12,12,12,13,13,11,13,13,13,15,13,12,14,13,13,14,12,13,12,12,11,10,11,10,10,8,8,8,8,9,10,8,8,8,8,7,8,8,8,8,7,9,10,9,10,10,10,9,10,9,11,10,12,11,12,11,11,11,10,11,9,10,9,8,9,7,7,9,7,6,6,7,4,4,3,4,5,4,5,6,6,7,8,8,8,8,8,10,9,10,10,10,11,11,9,11,9,8,8,8,7,8,8,6,7,8,7,6,6,4,6,6,6,7,9,9,9,9,9,8,9,10,10,11,11,12,12,12,10,13,13,13,12,13,14,12,13,12,13,13,14,14,14,13,15,15,14,14,15,14,15,14,16,16,17,16,18,19,18,19,18,20,22,21,22,23,25,23,25,23,24,24,24,27,25,26,27,25,27,27,28,26,27,26,28,27,26,28,27,27,26,24,27,27,27,25,27,25,27,27,28,26,24,26,26],[30,30,30,30,30,30,30,30,30,29,29,29,30,29,29,29,29,29,29,29,28,28,29,29,28,29,29,28,29,29,28,29,30,30,29,29,29,29,29,29,29,29,28,28,28,27,26,25,25,24,24,23,23,22,21,21,20,20,20,18,15,15,13,10,10,8,6,5,6,6,5,6,9,9,10,9,8,10,10,10,11,12,11,10,13,14,14,15,16,15,16,16,16,16,15,18,16,18,17,17,18,18,17,17,18,16,17,18,17,17,17,16,17,17,17,16,17,17,17,17,17,15,17,17,17,16,17,18,17,17,17,18,17,18,17,17,17,19,18,17,18,17,18,18,16,16,18,16,15,16,16,15,13,16,16,15,17,16,15,14,14,12,13,14,13,13,14,15,14,13,14,15,14,15,16,15,15,17,16,17,15,14,17,17,16,16,17,17,15,16,18,17,16,18,17,18,18,17,15,18,18,16,17,17,17,18,17,16,16,15,16,18,16,16,18,16,15,16,15,14,14,15,15,14,13,15,14,12,12,13,11,11,14,11,12,13,13,14,15,16,14,13,15,16,14,15,16,15,13,16,16,13,14,15,15,15,16,16,16,14,14,13,15,14,16,13,13,15,16,13,14,16,15,16,15,17,16,15,16,16,15,14,15,13,11,12,13,11,12,12,12,11,12,12,11,12,11,13,11,10,9,8,9,9,8,8,11,10,9,12,12,13,12,12,13,12,12,11,11,9,8,7,6,5,5,5,5,4,4,3,2,1,0,1,3,4,6,8,9,9,10,10,8,13,11,9,14,16,14,15,18,18,17,19,19,20,22,20,22,21,20,22,20,19,22,23,22,22,22,24,25,24,25,25,27,27,28,27,27,27,27,27,27,27,27,27,27,27,26,26,26,26,27,25,25,24,25,25,24,24,24,23,25,23,22,23,23,20,21,21,20,19,17,17,16,14,14,13,11,9,7,6,5,7,7,8,10,10,11,12,12,11,12,13,12,13,13,15,15,14,16,15,14,16,17,16,17,17,16,15,14,15,15,14,16,15,16,18,15,14,14,12,12,12,12,12,12,11,12,11,11,11,11,12,10,12,13,12,14,14,14,12,16,15,15,15,16,17,16,16,16,16,16,16,16,17,17,17,17,17,16,15,16,16,14,14,14,15,14,15,15,16,14,14,15,14,14,13,13,13,16,13,13,13,13,12,14,13,13,13,12,13,9,11,12,13,14,13,14,15,15,14,14,15,15,16,15,16,16,17,16,16,16,16,15,15,17,17,14,16,17,15,15,15,13,14,15,13,11,13,12,12,11,12,11,11,11,12,12,10,11,12,11,10,11,12,11,9,13,12,12,11,12,15,13,12,15,15,13,15,15,12,11,14,14,11,14,11,14,13,11,13,11,8,11,11,11,9,11,8,11,7,9,10,8,9,11,9,12,11,11,10,12,13,11,14,13,12,14,14,15,15,13,15,16,14,14,14,15,14,12,13,12,11,11,10,9,10,8,7,9,10,13,9,6,10,11,10,7,10,10,8,7,12,11,10,10,13,10,9,11,13,12,11,12,13,14,15,9,12,11,12,11,11,11,10,11,11,11,10,11,6,7,9,4,3,3,5,7,5,5,8,9,6,8,10,11,9,11,10,9,10,10,10,10,8,8,9,9,7,9,8,6,5,9,8,5,6,7,6,5,3,6,7,7,8,10,9,9,9,9,9,9,9,10,11,11,11,12,11,12,12,13,14,12,14,15,14,13,14,16,12,15,16,15,14,16,16,14,16,16,15,15,17,17,16,17,17,17,20,19,19,19,20,22,23,23,23,26,24,27,25,25,25,25,28,26,27,29,26,28,28,29,28,28,27,29,28,28,29,28,28,28,26,28,28,28,26,28,27,27,28,28,26,26,27,25],[29,29,29,30,30,30,30,29,29,29,29,28,29,28,29,28,28,29,27,29,28,27,28,28,27,28,29,27,28,28,27,28,29,29,28,29,28,28,28,28,28,28,27,27,27,26,25,24,24,23,23,22,22,21,21,22,20,20,20,19,17,14,12,9,9,7,7,8,7,7,8,8,8,11,11,11,10,12,11,13,12,14,13,12,14,15,15,16,19,17,18,17,18,19,18,18,18,20,18,19,21,20,20,20,21,20,21,21,21,20,20,19,19,20,19,19,18,19,18,19,19,19,20,20,19,21,19,20,20,20,19,20,20,20,19,20,20,21,20,20,22,19,19,20,19,20,18,19,16,18,19,17,17,18,18,18,19,18,16,16,16,15,14,16,16,16,15,18,17,17,16,17,17,18,19,17,17,19,19,19,19,16,18,19,19,17,19,20,18,19,20,19,19,20,21,20,20,21,19,19,19,20,20,20,19,20,20,19,18,19,19,19,18,19,20,18,20,18,17,16,16,17,16,13,17,16,14,13,15,16,13,13,14,14,14,15,15,16,16,18,16,16,16,17,17,15,17,16,16,17,17,17,16,17,18,18,19,18,17,17,17,16,16,16,17,15,12,16,17,13,16,17,17,18,17,18,17,17,17,17,16,16,15,13,14,14,11,11,14,12,13,12,13,13,11,13,14,13,12,10,9,11,11,12,11,9,12,12,10,13,14,17,13,15,15,14,16,13,13,12,10,10,9,7,7,7,7,5,5,5,4,3,1,0,1,3,5,6,7,7,8,11,11,10,10,10,11,14,12,14,17,17,16,19,21,21,23,21,23,21,20,22,21,19,21,23,22,21,23,25,25,26,26,26,26,27,27,27,28,27,27,28,27,28,27,28,27,27,26,27,26,26,26,25,25,23,25,25,23,25,24,23,25,21,22,22,21,21,20,19,20,19,18,17,17,15,15,13,12,10,9,7,7,10,11,12,14,12,15,14,14,14,15,15,14,14,17,16,16,18,19,17,18,19,20,18,19,21,18,17,17,17,18,17,17,18,18,19,18,17,16,18,17,16,15,14,16,13,13,13,13,12,13,13,15,13,14,15,17,18,16,15,17,17,17,17,19,18,18,18,19,17,18,19,18,19,18,19,18,18,18,17,18,17,16,16,17,18,16,15,17,17,17,14,16,15,14,15,16,16,16,16,15,15,16,14,14,14,15,16,15,14,13,15,14,16,15,17,18,17,18,17,16,17,19,17,17,18,18,18,20,18,18,18,17,18,19,19,16,18,20,17,17,17,16,14,15,14,14,14,14,12,12,14,12,12,13,13,12,12,12,13,11,11,12,14,12,11,13,15,14,13,14,18,15,14,16,16,14,16,17,15,13,15,17,15,15,14,14,16,14,13,13,13,13,12,16,12,13,10,13,12,10,11,11,11,14,13,13,12,14,13,15,16,15,14,15,14,18,17,17,16,16,17,18,16,17,16,17,18,14,15,15,14,12,11,13,11,9,9,10,10,11,12,11,10,11,11,8,11,11,11,11,11,13,12,13,14,15,12,13,14,14,13,16,14,16,16,16,14,15,15,13,12,14,15,14,11,11,9,12,7,7,8,6,6,3,5,7,5,5,8,8,6,10,11,13,9,15,15,14,13,12,12,12,9,9,13,14,12,12,11,10,7,13,15,10,7,9,12,7,6,9,11,13,12,11,12,12,11,15,14,11,11,11,13,13,16,14,16,16,16,15,16,15,16,19,17,15,16,18,15,17,15,15,16,18,17,16,17,20,18,18,18,19,19,19,19,20,21,21,22,20,23,23,23,23,23,25,25,26,25,26,25,24,28,24,27,27,26,28,28,28,27,28,25,28,28,27,27,28,28,27,26,26,27,28,25,28,26,26,27,27,25,25,27,26],[30,29,29,29,29,30,29,29,29,29,29,28,29,28,28,28,29,28,27,28,27,27,27,28,27,27,28,26,28,27,27,28,29,29,28,29,28,29,29,28,28,28,27,26,27,26,25,24,24,24,23,22,23,22,21,20,21,20,20,20,18,16,14,10,11,10,8,9,10,11,11,13,12,13,15,13,13,15,14,16,17,16,14,15,17,17,17,19,20,20,21,21,20,21,21,20,20,21,22,22,23,22,22,22,23,23,23,22,23,22,22,21,20,21,22,21,21,22,22,22,21,22,22,21,21,23,21,22,22,22,22,23,22,21,20,21,23,22,22,22,23,22,22,22,22,22,21,22,20,20,21,21,20,21,19,21,21,20,19,20,18,17,18,20,19,18,18,19,19,19,19,19,20,21,20,21,20,21,20,20,21,22,21,21,22,21,21,21,22,20,20,21,22,21,21,21,21,21,21,21,22,21,21,21,21,22,21,20,19,20,21,21,19,21,21,22,23,21,21,20,18,20,21,19,18,19,20,18,18,18,18,18,18,16,18,19,19,19,19,20,20,19,19,20,20,20,19,20,20,20,19,19,21,19,21,21,21,20,19,20,20,19,21,19,19,19,18,18,19,19,19,19,21,18,18,19,18,18,19,18,19,20,19,17,18,18,17,15,17,17,18,16,17,17,16,17,17,17,17,15,14,13,15,14,15,13,16,17,14,16,18,18,16,16,16,17,17,15,14,13,13,13,13,11,11,12,9,7,8,7,5,5,3,1,0,1,4,4,6,7,9,7,8,9,11,10,10,12,13,13,14,15,15,17,20,20,22,20,22,21,21,23,21,21,21,23,23,20,22,24,25,26,26,26,26,26,28,27,27,28,28,28,28,28,28,28,28,28,27,27,26,27,27,26,26,22,26,25,23,25,23,24,24,22,22,23,22,21,22,20,22,21,18,20,18,17,17,15,15,11,11,9,9,10,13,14,12,14,17,17,17,16,17,17,16,17,17,18,18,20,20,19,19,20,21,23,22,22,20,20,19,20,21,19,20,18,20,22,20,19,18,19,19,18,16,17,18,17,16,15,16,13,15,15,15,16,17,17,17,18,17,20,20,19,20,20,21,20,20,20,21,20,21,21,21,22,21,21,22,20,22,20,20,19,19,20,19,19,21,20,20,21,20,19,19,18,20,18,17,19,19,18,19,19,18,17,18,17,16,17,17,15,16,16,16,18,16,18,18,18,17,18,17,18,20,19,19,20,20,21,21,20,20,20,20,20,22,20,18,20,20,18,18,21,18,18,18,16,18,17,18,14,16,17,15,15,16,17,14,15,16,17,15,15,16,16,17,18,18,18,17,17,17,19,18,20,21,19,17,20,19,19,18,18,18,18,18,15,18,15,16,17,16,15,15,16,14,12,14,13,13,13,14,12,13,14,15,16,16,17,16,15,18,18,16,18,19,17,18,19,20,20,19,19,21,19,20,19,19,19,18,18,16,15,16,14,16,13,14,12,13,14,14,12,12,15,12,13,13,12,13,14,14,14,15,14,15,17,15,14,14,15,17,16,18,17,17,17,16,17,17,15,15,14,13,13,10,13,12,12,11,10,10,10,5,7,5,9,8,7,8,10,11,10,10,11,12,13,13,16,13,14,15,14,13,12,12,12,13,10,12,12,12,8,14,11,10,10,11,9,9,7,11,11,12,14,15,13,15,14,15,13,13,14,15,16,18,19,18,19,17,18,19,19,17,17,20,20,17,18,20,20,18,19,21,19,20,21,20,19,20,20,20,21,22,21,23,22,23,24,24,23,22,24,25,25,26,25,27,26,27,26,27,27,27,29,27,28,29,27,28,28,29,28,28,28,28,28,28,28,28,28,28,28,27,29,29,28,29,27,28,27,28,28,27,28,28],[30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,29,30,29,28,30,29,28,29,29,28,29,29,28,28,29,28,29,29,29,29,29,28,29,29,28,29,28,28,27,27,27,26,25,25,24,24,24,23,22,21,22,22,20,20,20,18,17,15,12,12,11,8,11,10,13,12,14,15,18,17,18,16,19,18,19,20,19,19,19,19,21,19,21,22,22,23,23,23,23,23,23,22,24,24,23,24,25,24,24,24,24,25,25,24,24,24,23,23,23,23,22,22,24,23,25,24,24,24,24,25,23,24,25,24,23,24,24,23,24,23,23,24,24,25,24,24,25,24,24,23,24,24,23,21,23,22,21,22,21,21,23,23,22,22,21,20,20,20,21,21,20,20,22,20,22,21,22,20,23,23,22,22,23,23,23,22,22,23,24,24,22,24,23,22,23,23,25,22,24,24,24,24,23,22,24,24,23,23,24,25,24,23,23,23,24,23,25,22,23,24,23,23,23,23,21,20,23,22,19,20,22,20,19,20,20,19,20,20,20,20,20,20,22,22,23,21,21,22,23,22,21,22,23,22,22,24,20,21,23,23,24,23,24,23,21,22,22,20,20,23,21,19,22,22,19,21,22,22,23,21,22,21,21,22,22,21,22,21,21,19,19,20,21,19,18,21,19,18,20,21,19,20,19,19,18,17,16,18,19,17,17,18,19,18,20,20,21,20,20,20,21,18,18,17,17,16,17,16,14,14,15,12,10,11,10,8,6,5,2,1,0,1,4,5,7,7,7,7,10,10,10,10,11,12,11,13,15,15,16,20,20,21,20,22,21,21,22,20,20,21,22,22,21,22,24,25,26,25,26,26,27,27,26,27,27,27,28,28,28,28,28,28,28,26,27,26,27,26,26,25,25,26,25,24,25,25,24,25,23,23,24,23,22,23,22,22,22,20,20,19,18,18,17,16,14,11,12,12,14,15,18,17,18,18,19,18,19,19,20,19,19,21,20,21,20,22,21,21,22,23,25,23,24,22,23,22,22,21,21,22,22,23,25,21,22,20,20,21,21,18,18,21,19,19,19,18,16,20,18,20,18,23,19,21,22,22,22,23,22,23,22,23,24,23,23,25,24,23,24,23,24,24,25,24,24,24,24,23,21,22,22,22,23,22,21,23,23,20,21,23,21,21,20,21,20,22,21,21,23,22,21,22,22,18,21,20,17,17,13,16,18,18,21,19,21,21,21,21,21,22,23,23,22,23,24,24,24,22,24,23,23,25,24,22,23,22,22,22,20,21,20,20,19,20,20,19,21,17,20,20,21,19,19,19,20,20,22,22,20,20,21,21,20,19,23,20,20,20,23,19,21,24,21,20,21,24,21,20,24,22,20,21,18,22,18,16,18,19,21,17,20,18,18,17,14,16,14,17,18,16,16,16,16,18,19,20,19,21,21,20,21,21,21,22,22,22,21,21,22,23,22,22,21,22,21,21,20,18,18,17,16,16,15,13,15,18,14,17,18,17,15,18,18,17,17,18,16,17,18,18,17,20,20,17,17,16,18,18,18,20,18,19,19,19,18,18,18,18,21,18,16,18,17,15,17,15,7,9,12,6,10,8,12,12,9,12,15,13,11,16,17,15,17,17,19,16,15,15,16,15,14,13,17,14,10,11,14,12,6,11,12,10,9,14,12,10,10,14,14,14,17,18,16,18,16,16,14,15,15,16,17,18,19,19,20,19,19,20,21,20,21,22,21,21,21,22,21,22,22,21,21,23,23,20,22,24,23,22,24,25,24,24,24,24,26,26,26,26,26,27,27,27,27,29,29,28,28,29,28,28,30,29,30,30,29,30,30,30,30,30,29,30,30,30,30,29,30,29,28,29,30,30,29,30,29,29,29,29,28,28,29,28],[30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,29,29,29,29,28,28,29,28,27,28,29,27,28,28,27,28,29,29,28,29,28,28,28,28,28,27,27,26,27,26,25,24,24,23,23,23,22,22,22,21,21,20,19,18,16,15,13,11,11,9,9,10,10,12,11,12,14,15,15,16,13,18,17,14,17,19,17,16,19,18,19,20,23,22,23,24,23,23,24,24,23,25,24,24,24,25,24,25,25,25,26,26,26,26,24,25,25,25,25,24,24,24,24,26,24,24,25,25,25,26,24,25,24,24,24,25,24,25,24,25,25,24,25,25,24,25,24,25,25,25,25,24,22,24,24,23,23,23,23,22,25,23,22,22,20,21,20,22,22,21,20,23,23,23,22,23,23,24,24,23,23,24,24,24,24,23,24,24,25,23,24,24,23,25,23,25,24,24,24,23,24,22,22,24,24,22,23,24,24,24,24,23,23,23,23,24,23,24,24,24,23,23,24,22,22,24,23,19,23,24,22,20,21,21,20,20,19,22,20,23,22,24,23,24,23,22,23,24,23,21,22,23,22,22,23,21,21,23,23,24,24,24,23,22,22,23,21,22,23,21,19,22,23,17,21,22,21,21,22,23,22,22,22,22,20,21,21,17,20,20,18,18,19,19,18,19,20,19,20,19,20,19,19,18,16,15,18,18,16,18,19,19,18,20,20,22,20,21,21,20,21,19,19,19,18,18,17,16,16,16,14,11,12,12,9,9,6,4,2,1,0,1,4,4,5,5,6,8,10,9,10,12,10,13,12,14,14,16,20,20,21,20,22,21,21,22,21,21,21,22,23,20,22,24,24,26,25,25,26,27,27,27,28,28,27,28,27,28,27,28,28,28,27,27,27,27,26,25,26,24,25,26,24,25,24,23,25,22,23,24,23,22,23,21,22,22,20,21,20,20,19,17,19,17,16,14,12,16,19,21,19,19,21,20,20,21,21,21,21,21,22,22,23,22,23,23,23,24,24,25,24,25,23,23,22,23,22,21,22,22,24,24,23,24,22,24,22,23,22,22,22,20,22,21,19,18,20,19,19,19,21,21,21,22,21,21,23,22,23,22,24,23,23,23,24,24,23,24,23,24,24,24,24,24,23,23,23,21,23,22,22,23,21,21,22,23,20,21,23,22,21,22,21,21,21,23,21,21,22,22,22,21,20,21,19,18,17,17,17,19,19,21,22,23,23,23,22,22,22,21,22,22,23,23,25,24,23,23,24,23,25,24,21,23,23,21,20,22,21,19,19,19,18,18,20,17,17,19,18,18,18,20,19,16,18,20,19,18,19,20,18,20,19,21,20,19,20,24,21,20,21,21,21,20,22,22,21,22,22,23,21,20,22,18,18,18,19,22,18,17,18,16,18,14,15,14,17,15,16,15,15,17,17,15,21,18,20,21,18,20,21,21,22,22,23,21,22,23,21,22,22,21,22,22,19,19,20,19,18,15,16,15,13,12,14,13,17,15,12,14,14,18,14,15,18,15,17,18,20,19,20,21,19,18,21,20,19,20,21,19,19,20,23,22,19,18,19,21,20,18,21,18,12,19,13,7,9,10,7,9,8,12,11,8,11,16,15,13,16,18,18,18,21,20,18,18,18,17,20,20,17,19,17,15,14,10,14,6,10,16,12,10,16,13,10,10,14,17,17,20,21,20,18,17,18,20,17,17,15,18,16,21,20,20,20,22,20,21,22,22,23,22,24,22,22,22,22,22,22,22,23,22,21,22,23,23,22,24,24,23,24,24,25,26,26,25,25,26,26,26,26,26,28,27,28,27,28,27,27,29,28,29,29,28,29,29,28,29,29,28,29,29,28,29,28,29,28,28,28,29,28,28,29,29,27,29,28,28,27,28,27],[30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,28,29,28,27,28,28,27,28,27,27,27,28,27,28,28,26,28,28,29,27,28,27,28,28,27,28,28,27,26,27,26,24,23,24,23,22,22,22,21,21,21,21,20,20,19,18,15,15,12,12,12,11,12,16,16,14,16,15,18,18,18,18,19,18,17,20,21,19,19,21,21,21,22,23,23,23,23,24,24,24,24,24,25,24,25,26,25,25,26,26,25,26,25,26,26,25,25,25,25,25,24,25,26,25,26,25,25,25,26,26,27,26,26,25,24,25,26,25,24,24,25,25,26,25,25,25,26,26,26,25,26,25,24,24,25,24,25,24,25,24,24,25,23,22,22,22,22,21,24,23,22,21,24,23,24,23,24,24,25,25,24,25,24,25,25,25,26,24,25,26,25,24,25,25,24,25,25,25,24,24,24,24,24,24,24,25,24,24,24,24,24,24,22,24,24,24,24,25,24,25,25,25,24,24,24,22,24,25,23,24,24,23,23,23,23,22,23,21,22,20,22,24,22,23,24,23,23,24,25,25,22,24,25,24,24,23,24,25,23,24,24,25,24,24,24,24,23,24,24,24,23,22,23,24,22,23,24,24,24,22,23,23,22,23,23,23,22,22,20,21,22,20,20,20,21,20,21,22,22,22,21,22,22,22,22,18,18,21,20,18,19,21,20,20,20,22,22,19,20,21,21,21,19,20,18,17,19,18,14,16,17,17,14,16,15,13,11,9,5,5,3,1,0,1,3,4,5,5,7,8,7,8,10,10,10,14,15,14,15,17,17,19,20,21,21,20,23,22,22,21,22,22,22,21,24,24,25,25,25,26,26,27,27,28,28,27,28,27,27,27,27,27,27,26,26,26,27,26,25,26,24,25,25,24,25,24,24,25,22,22,24,23,22,23,21,22,21,21,21,21,20,20,19,18,17,17,17,16,17,18,16,18,18,22,20,20,21,20,21,19,20,22,22,21,22,24,21,23,23,25,25,24,25,24,24,23,23,23,23,23,23,24,25,23,23,22,22,22,22,20,20,23,20,20,20,20,19,20,20,19,19,21,20,21,21,21,22,23,22,23,24,24,23,25,24,25,24,24,24,25,25,24,24,25,23,26,23,25,24,23,23,24,23,23,25,24,24,24,23,22,22,23,22,21,22,22,22,22,22,20,21,22,22,19,22,21,19,18,18,19,20,20,21,21,22,22,22,22,22,23,23,23,23,24,23,24,24,24,21,23,23,24,23,21,23,23,22,23,23,21,21,21,20,20,20,20,19,18,21,19,19,20,21,19,21,21,21,20,20,20,21,19,22,22,21,21,22,22,23,23,22,23,22,22,23,22,21,22,21,20,22,22,20,23,18,19,20,17,18,18,17,18,15,17,18,16,16,17,15,15,16,18,19,19,18,21,18,21,23,21,21,21,22,22,23,23,22,23,23,22,23,24,22,23,22,21,22,20,19,20,16,16,16,15,15,18,16,18,16,15,17,17,15,15,18,17,16,17,21,17,17,19,21,19,18,19,21,20,21,22,18,20,21,17,20,19,17,17,16,19,18,17,14,12,16,13,10,11,12,10,13,12,15,14,10,13,16,13,11,15,15,14,15,14,18,17,16,17,19,18,18,17,19,17,15,16,15,15,8,12,12,11,9,13,13,12,11,16,16,16,17,18,19,17,18,16,16,16,17,16,19,19,21,20,22,20,21,22,21,21,21,22,21,22,21,22,23,21,23,23,22,23,24,24,24,24,25,25,25,24,24,25,25,26,25,26,27,26,26,27,27,27,26,29,28,29,28,29,28,28,30,29,29,30,29,29,30,30,29,30,29,29,30,29,30,29,29,29,29,29,30,30,29,30,29,29,30,29,29,29,29,28],[30,31,30,30,30,31,31,30,30,30,30,30,30,29,29,29,29,29,28,29,28,27,29,28,27,28,28,27,28,28,26,28,29,29,28,28,27,28,28,28,29,28,27,27,27,27,25,25,24,24,24,24,22,22,21,22,20,19,19,17,17,15,15,11,13,14,11,15,14,18,16,18,19,21,20,20,21,23,22,20,23,23,22,21,23,23,22,24,25,25,25,25,25,25,25,25,25,25,25,24,25,26,26,26,26,25,27,27,25,27,27,25,25,25,26,26,25,26,26,27,27,25,25,26,25,25,25,26,25,25,26,25,23,26,25,25,25,25,25,24,25,25,25,25,24,26,24,24,24,25,24,24,25,26,23,25,26,25,24,25,25,24,24,25,24,24,24,24,24,24,23,24,24,26,25,24,25,25,24,25,24,24,24,24,25,24,25,25,24,24,25,25,24,26,24,24,25,24,23,25,25,24,25,26,24,26,24,24,24,25,24,25,23,25,26,25,25,25,26,23,24,25,26,23,26,26,24,24,25,24,23,24,23,24,24,26,26,25,26,25,25,24,25,26,24,25,24,26,23,24,25,24,25,25,25,24,25,25,25,24,24,25,23,24,25,23,22,25,25,21,23,24,23,24,24,25,25,23,24,24,23,23,23,23,23,22,22,21,23,21,23,22,24,22,24,23,24,23,24,24,21,21,23,21,21,21,23,21,21,22,22,24,22,21,23,22,22,22,23,20,21,22,21,18,19,22,18,15,18,18,14,11,11,7,6,4,3,1,0,1,4,3,4,3,4,6,6,8,8,9,10,12,11,12,16,16,19,18,19,19,20,22,20,21,22,22,22,22,24,24,26,25,26,26,27,27,28,26,28,28,27,28,27,28,27,28,28,28,26,27,25,27,26,26,26,24,25,25,24,26,25,25,25,23,24,24,23,24,23,22,24,22,22,22,21,21,20,19,20,17,18,16,17,21,19,19,19,20,22,22,21,22,22,23,21,21,23,23,22,21,25,24,23,25,26,26,25,26,25,25,26,24,23,24,25,24,24,26,24,24,24,21,22,24,22,20,24,23,22,21,22,20,22,21,21,22,24,22,23,24,24,25,24,23,24,25,25,25,24,24,25,24,25,25,26,25,26,25,25,25,26,25,26,25,25,24,26,24,24,23,25,25,23,23,25,24,23,23,24,23,23,24,24,23,23,23,24,25,21,22,22,20,21,19,21,20,22,23,22,23,25,24,24,24,23,24,26,24,24,25,27,26,25,25,26,27,24,25,25,24,24,24,24,22,23,24,22,21,22,22,21,22,21,23,22,22,22,23,24,23,22,24,23,21,22,23,21,23,23,22,22,23,23,25,23,23,23,24,23,23,25,24,23,23,23,24,23,21,24,21,21,22,22,23,20,22,21,17,20,15,18,16,17,20,20,19,18,20,22,22,23,22,23,24,22,24,24,23,24,25,25,25,26,24,25,25,25,24,24,23,24,24,20,22,22,20,20,20,16,17,19,19,21,18,18,21,20,21,19,21,21,20,21,23,21,20,22,24,22,21,21,21,21,22,25,21,22,23,22,22,20,22,18,22,20,18,21,19,14,13,16,12,10,14,10,15,12,16,18,11,13,17,16,15,17,20,17,17,20,21,17,17,20,19,20,17,18,19,15,13,14,14,13,9,14,13,11,11,16,12,12,12,15,19,18,20,19,20,20,17,19,16,18,19,20,20,22,22,22,21,21,25,23,24,24,23,24,23,23,23,23,24,24,23,23,23,24,24,23,23,25,25,24,25,25,25,25,25,26,27,27,26,26,27,27,28,27,27,29,29,29,28,29,29,28,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,29,29,30,30],[30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,28,28,28,28,27,28,28,27,28,28,27,28,28,26,28,28,29,28,28,27,28,27,27,28,26,25,26,26,25,25,22,24,24,23,22,22,22,21,20,20,19,18,17,16,14,14,11,12,11,12,14,15,16,16,17,19,20,19,18,20,21,20,17,22,22,21,20,21,22,19,22,22,23,24,24,23,25,25,26,24,24,26,26,26,26,28,26,27,27,27,27,27,28,27,27,27,27,27,27,26,28,27,28,28,26,27,27,26,27,26,28,26,25,26,26,24,26,25,26,27,27,27,26,26,25,26,26,25,26,26,25,22,25,25,25,24,26,24,26,26,26,25,25,25,23,23,25,24,23,24,26,24,24,25,25,24,26,26,25,24,26,26,27,25,26,25,25,25,24,26,25,24,24,25,26,23,26,25,26,27,25,23,25,26,24,25,26,26,26,25,23,24,23,24,24,24,24,26,24,25,25,24,22,23,25,26,22,24,24,23,23,24,25,23,25,24,25,23,25,25,26,27,28,25,25,26,27,26,25,26,27,25,26,27,25,26,26,25,26,26,26,26,24,25,25,23,23,25,23,23,24,25,22,22,25,24,25,24,25,25,23,24,22,25,23,23,21,22,23,21,21,22,21,22,23,22,21,22,24,24,21,24,23,22,21,22,21,21,21,24,22,22,23,23,25,21,23,23,24,22,23,23,20,20,21,21,17,17,18,18,16,15,16,16,13,11,8,7,5,4,2,1,0,1,1,2,2,3,3,3,4,5,5,6,9,9,10,13,14,17,15,19,17,20,22,20,18,20,21,21,21,23,24,24,24,26,25,26,26,26,26,27,28,27,27,27,27,27,27,26,26,25,26,25,26,26,25,25,23,23,24,24,24,24,24,25,22,23,24,23,23,22,22,23,21,21,21,21,19,20,19,18,17,17,18,16,19,19,20,20,21,23,22,21,21,22,22,20,22,22,22,21,21,23,23,23,24,24,26,23,24,23,24,22,24,22,23,23,23,24,26,22,24,23,22,20,22,22,20,22,22,21,19,22,21,20,21,22,21,21,21,22,23,23,23,23,23,24,24,24,25,24,24,26,25,24,25,24,24,26,26,26,26,26,26,26,25,25,25,25,25,24,23,24,25,23,23,24,23,23,23,23,24,24,22,22,22,22,23,22,22,20,21,20,22,20,21,19,22,22,23,22,23,23,23,23,22,23,23,24,23,24,24,26,26,26,23,24,24,26,24,23,23,23,22,22,22,20,21,20,20,22,19,21,20,20,20,20,21,20,20,19,22,20,21,20,21,21,20,22,22,23,22,23,23,23,23,22,23,24,23,23,24,23,23,22,23,23,24,23,21,24,22,21,20,21,21,23,21,20,17,19,18,18,17,19,18,16,16,19,20,19,18,21,20,22,22,21,23,24,22,23,23,25,24,24,24,23,24,23,23,23,23,21,20,21,20,21,18,18,19,16,17,19,19,20,18,16,20,17,16,18,19,19,16,19,20,20,19,24,22,19,19,22,22,21,21,25,21,23,24,22,22,22,22,19,22,19,16,19,17,14,15,15,9,10,14,11,13,15,13,14,11,14,17,15,12,19,19,15,18,21,19,17,19,21,18,19,17,15,19,16,14,13,13,15,8,11,15,12,13,13,15,12,15,17,20,16,19,19,19,19,18,20,17,18,20,19,21,20,22,21,22,22,23,22,23,22,24,24,23,24,23,22,25,24,23,22,23,24,24,22,24,25,25,25,26,26,26,25,26,26,28,27,27,26,27,27,28,28,29,28,28,29,27,28,29,29,30,29,30,30,30,31,30,30,30,30,29,29,30,29,30,29,30,29,30,30,30,29,29,30,30,29,30,30,29,29,30,29],[30,30,30,30,30,30,30,30,29,29,29,28,29,28,28,28,28,28,27,28,28,27,28,28,26,28,28,26,28,28,26,28,28,28,28,28,27,28,27,27,28,27,26,26,26,25,25,23,22,23,23,21,21,21,20,19,19,18,18,15,15,13,15,12,13,15,14,15,15,19,16,18,19,19,20,20,21,21,21,19,22,23,21,19,23,24,21,23,24,25,25,25,25,25,24,25,25,25,24,26,26,26,27,26,27,26,27,27,26,26,27,26,26,27,25,26,26,27,27,28,27,26,26,27,26,27,27,27,27,26,26,27,25,26,25,27,26,27,26,26,27,26,26,26,26,26,26,26,24,26,26,26,24,27,24,25,27,25,24,26,25,23,24,26,24,24,23,26,23,26,24,26,25,26,26,26,26,26,25,27,26,27,25,26,27,26,26,26,26,25,26,26,25,26,25,25,25,26,23,25,25,24,23,25,25,25,23,23,23,24,24,26,24,26,27,25,27,25,26,23,23,26,27,22,25,26,25,23,25,25,24,24,24,25,24,25,25,25,26,26,25,25,26,27,26,25,26,27,25,25,26,26,26,25,26,25,26,26,26,25,25,26,23,25,26,24,23,25,25,21,22,25,24,23,22,24,24,23,24,23,25,23,23,20,23,22,21,19,23,21,20,21,24,21,21,23,23,23,24,23,21,21,22,21,21,21,23,21,21,22,23,25,21,23,23,22,23,22,21,20,19,19,19,16,16,17,18,17,17,16,15,15,10,9,8,5,3,3,3,1,0,1,1,2,2,3,3,4,3,6,7,8,9,10,13,12,17,15,18,17,19,19,18,19,20,20,21,21,21,23,24,25,26,25,25,25,26,26,26,26,25,26,25,25,26,26,25,25,25,24,24,25,24,24,24,23,23,25,23,25,24,23,26,23,23,25,24,24,24,22,24,22,22,21,22,20,20,19,19,17,17,17,19,19,18,19,18,19,23,22,22,21,22,22,19,20,23,22,19,21,25,22,21,24,24,24,24,24,25,25,24,24,24,23,24,24,24,26,24,24,24,21,22,23,20,20,23,21,20,20,22,20,20,20,21,21,23,22,22,23,23,25,22,23,25,24,24,24,25,24,25,25,26,25,25,26,26,26,26,25,27,25,26,25,26,25,26,25,25,24,25,26,24,24,25,22,24,21,22,23,23,23,22,22,21,22,23,23,20,21,21,21,21,21,21,20,20,21,20,22,22,22,22,22,23,23,24,22,23,25,26,26,25,24,25,25,25,25,24,24,22,23,24,22,21,22,21,20,22,20,21,20,21,21,21,21,21,22,22,20,22,22,21,21,22,22,21,22,23,22,21,23,23,23,24,23,24,22,23,24,21,22,21,22,20,23,22,19,23,21,20,20,21,20,20,21,21,17,18,16,18,17,17,19,19,19,19,20,19,20,21,20,22,23,20,24,24,23,23,25,25,25,25,24,24,25,24,24,23,23,22,21,19,20,22,19,18,19,16,17,18,19,22,18,18,20,20,19,19,19,21,18,19,23,21,18,20,22,21,19,19,21,19,18,24,20,20,22,21,18,19,21,18,20,17,16,19,17,12,14,15,11,12,14,14,12,15,14,14,13,15,16,17,14,15,18,15,17,17,17,16,16,18,16,17,16,16,15,15,14,13,12,13,9,13,14,14,14,15,14,14,16,17,19,16,19,19,18,17,17,19,19,17,18,18,18,20,20,19,20,21,22,21,22,21,21,21,22,22,20,22,24,23,22,24,23,24,26,24,24,26,26,26,26,25,25,25,26,26,27,27,27,27,27,27,28,28,28,29,28,29,29,29,28,29,29,29,30,30,30,30,30,30,29,30,29,30,30,29,30,29,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,29],[30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,28,29,28,28,29,28,28,29,28,28,28,28,27,28,28,27,28,28,29,28,28,27,27,27,27,27,27,26,26,25,25,24,24,22,23,22,21,21,21,20,21,20,19,18,18,16,13,14,12,12,12,11,14,15,16,17,16,18,19,19,19,20,22,21,20,22,22,22,20,22,22,20,21,22,23,23,24,24,23,24,25,24,25,26,26,26,26,26,26,26,26,27,27,26,26,26,26,26,27,26,26,26,27,27,28,27,24,27,27,26,26,27,27,26,26,26,27,25,25,25,25,26,26,26,26,26,26,26,27,26,27,27,26,24,26,26,25,24,25,24,24,26,25,24,25,24,22,23,25,24,22,24,25,23,24,25,26,24,26,26,26,25,26,26,26,25,25,25,26,25,26,26,26,25,25,26,25,25,25,25,24,25,25,23,25,25,24,24,25,25,24,23,23,23,24,25,25,23,25,26,25,25,26,26,24,23,26,26,22,24,26,24,23,24,25,22,23,24,24,25,25,25,25,26,26,25,25,26,27,25,26,26,26,24,26,26,24,25,25,25,24,25,25,25,25,24,24,23,25,25,23,21,24,25,22,22,24,22,21,22,23,22,24,22,24,23,22,21,19,22,23,22,19,23,22,20,21,24,22,22,22,23,22,24,23,19,21,22,19,21,22,23,22,22,23,22,24,23,23,22,23,23,24,23,21,20,20,20,16,18,20,19,16,16,17,15,13,12,8,7,6,3,4,2,1,1,0,1,2,2,2,3,3,3,4,8,8,8,10,13,13,16,15,20,19,18,21,19,21,21,21,22,21,23,24,26,25,26,26,26,26,27,26,27,28,27,27,27,27,27,27,27,27,26,26,25,27,27,24,26,23,24,26,24,26,24,23,26,23,23,26,24,23,25,23,24,24,23,23,21,21,22,18,21,18,19,18,16,19,19,18,20,20,22,23,22,21,22,23,21,22,23,24,21,22,24,23,24,25,25,26,24,26,24,26,24,24,24,24,25,25,25,27,25,25,25,23,24,23,23,22,24,23,20,22,22,22,21,21,21,23,22,22,22,23,24,24,23,24,25,25,25,25,25,24,25,25,25,25,26,25,26,26,26,25,27,25,27,25,25,23,26,25,24,23,26,26,23,24,25,23,23,22,22,22,22,22,22,22,22,21,23,23,21,21,21,21,21,19,20,20,20,21,20,23,21,22,21,20,22,23,23,22,22,23,25,24,22,21,22,22,22,21,21,22,21,20,22,20,20,20,21,19,20,20,21,20,19,21,21,20,19,21,22,20,22,22,21,20,22,21,21,22,22,21,22,23,24,22,23,23,22,22,22,22,21,23,22,21,20,22,22,20,22,21,21,22,21,18,20,20,20,19,19,17,18,16,18,18,17,18,19,19,20,19,21,21,21,21,21,23,23,21,22,24,24,23,23,23,22,22,22,20,21,21,20,21,18,19,21,19,18,17,15,17,19,17,21,19,17,17,20,18,16,19,21,18,18,21,21,19,19,21,21,19,20,20,20,20,22,20,22,23,21,21,22,21,20,21,19,15,19,15,14,14,15,11,11,14,11,14,13,15,15,14,14,16,18,16,17,17,19,16,17,18,16,17,19,19,19,16,17,18,15,15,14,11,13,9,12,16,14,14,15,14,14,14,19,18,17,19,19,19,19,20,18,17,18,20,20,21,21,22,22,22,21,23,23,20,22,22,22,22,22,23,22,24,24,22,24,24,25,25,24,25,26,24,25,26,26,25,25,26,26,27,27,27,28,28,28,28,28,28,29,29,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29],[30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,28,28,28,28,27,28,28,27,28,28,26,27,27,25,28,28,28,27,27,26,27,27,26,27,26,25,26,25,24,23,22,22,21,21,19,19,19,19,19,18,18,16,16,14,13,13,12,12,12,12,14,15,14,17,14,17,18,19,18,21,19,19,18,20,21,20,18,20,21,20,21,22,23,23,24,24,24,24,25,25,25,26,26,26,26,27,27,26,27,27,27,27,27,26,27,27,27,26,27,26,27,26,27,27,26,27,26,26,27,26,28,26,26,26,27,26,26,25,26,26,27,26,26,27,25,27,27,26,27,26,26,25,26,26,25,24,25,25,24,26,25,25,24,24,22,22,25,24,21,22,26,24,24,25,27,25,26,26,26,25,26,25,26,26,25,25,26,26,26,26,26,26,26,25,27,25,25,25,25,25,25,22,24,25,23,24,25,25,25,23,24,23,23,24,25,22,25,25,25,25,26,25,24,23,27,26,22,24,25,24,23,24,24,21,23,22,24,23,25,25,25,25,25,25,24,25,26,25,25,25,26,24,25,26,24,24,23,26,25,25,26,25,25,24,25,22,25,26,25,21,25,25,21,23,25,23,22,23,23,24,24,22,24,23,23,21,18,23,23,21,20,22,21,20,22,24,22,22,23,24,22,23,22,19,21,21,19,21,20,22,20,21,22,22,23,22,23,21,23,22,23,22,20,21,21,20,18,18,20,19,15,17,17,16,14,11,9,7,5,5,4,2,2,1,1,0,1,2,2,3,3,3,4,6,9,8,8,14,14,16,15,19,16,18,20,20,20,19,22,23,21,22,24,22,25,26,25,26,26,26,26,27,28,26,27,27,27,26,27,27,26,26,26,25,26,26,25,25,23,24,25,24,24,25,23,25,23,23,25,24,24,24,23,24,23,23,22,23,22,22,19,20,18,19,17,18,20,19,20,20,20,22,21,22,21,21,22,21,22,22,23,22,21,23,23,24,25,25,26,25,25,24,25,23,24,23,24,24,23,25,27,24,26,25,24,23,22,23,21,23,23,21,21,21,21,21,21,20,22,22,22,21,24,23,24,21,23,24,24,24,25,23,24,25,25,26,26,25,24,26,26,25,26,25,25,25,24,25,22,24,24,24,22,24,25,23,23,25,23,22,21,22,21,22,22,22,22,19,22,22,20,20,21,20,19,19,19,19,20,20,22,22,22,22,22,22,21,21,22,21,22,22,23,25,24,23,23,23,25,25,23,23,21,22,22,22,21,19,19,20,20,20,19,19,18,18,20,17,19,18,20,19,20,19,20,19,20,20,20,20,22,21,21,21,23,23,22,22,23,21,21,22,23,21,21,21,21,20,22,21,21,22,21,21,21,20,20,21,19,19,18,17,15,16,15,16,16,15,15,17,18,18,17,20,19,20,22,22,23,24,22,23,24,24,23,23,24,22,22,22,22,21,21,20,19,18,18,18,16,16,17,15,15,18,16,17,18,17,17,17,18,17,19,20,20,19,21,23,19,22,22,20,18,19,22,20,20,23,20,21,23,23,21,20,20,21,21,17,16,18,15,14,13,17,8,9,13,11,14,14,14,14,12,16,18,17,14,18,20,17,17,19,19,18,17,17,17,18,17,14,17,17,13,12,13,14,11,13,15,14,14,15,15,14,15,19,19,18,20,20,19,18,18,20,16,17,19,17,19,19,20,20,21,21,23,21,21,22,23,22,21,23,22,21,24,24,23,22,24,26,23,24,25,25,24,26,26,26,25,25,25,26,28,27,26,27,28,28,28,28,28,29,29,29,29,29,28,29,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,29,29],[30,30,30,30,30,31,30,30,30,30,29,29,30,28,29,28,28,29,28,28,27,27,28,27,26,28,28,26,28,26,26,28,28,28,28,28,27,27,27,27,27,26,26,26,26,25,24,24,23,23,22,22,21,22,21,20,20,20,18,16,17,15,14,12,12,14,14,15,15,16,16,17,18,20,19,21,20,21,21,20,22,22,21,20,22,22,20,21,23,24,24,25,25,24,25,26,27,27,27,27,27,27,28,27,27,27,28,27,27,27,27,27,27,27,26,27,27,27,26,28,28,27,27,27,26,28,26,28,27,27,26,27,26,26,26,27,26,27,27,27,28,26,27,27,27,27,27,27,25,26,27,27,25,26,26,25,27,26,25,25,25,23,23,25,25,24,24,26,26,26,25,28,27,26,27,27,26,26,27,27,27,26,26,27,27,27,26,27,27,26,27,26,26,26,26,26,26,26,25,26,26,25,25,26,26,25,23,25,24,23,26,26,25,26,27,26,25,26,26,25,24,27,27,23,26,26,26,23,25,25,25,24,22,24,22,24,25,25,25,26,26,25,26,27,27,24,26,25,26,26,26,25,26,25,26,26,26,27,26,26,26,25,26,26,26,26,23,25,26,22,24,25,23,23,23,24,25,25,24,25,24,24,24,21,24,25,23,22,24,23,22,24,25,24,23,23,24,23,24,23,22,21,23,21,22,22,24,22,22,23,24,26,23,24,23,22,23,22,21,22,19,20,19,17,18,18,19,16,17,16,13,14,14,9,8,5,4,4,2,2,2,1,1,0,1,2,2,2,3,3,5,6,9,9,10,13,15,14,16,16,18,19,19,19,19,21,21,21,22,24,23,24,25,25,26,26,26,26,26,27,26,27,26,26,27,27,27,27,26,26,24,26,26,24,24,22,23,24,24,24,24,24,25,23,24,24,23,24,23,23,24,22,22,22,23,21,20,21,19,18,18,19,18,19,17,20,20,21,23,23,23,21,22,22,21,20,23,23,21,21,24,23,22,23,24,25,23,24,24,25,25,25,24,23,25,24,24,26,23,24,24,21,24,22,21,20,23,22,21,21,22,20,21,20,22,22,22,22,22,23,24,25,24,24,25,25,25,25,24,25,25,26,26,26,26,26,26,26,26,25,27,25,26,25,26,25,26,25,25,25,25,26,24,26,25,24,24,22,22,23,24,23,22,23,21,22,24,23,20,22,21,21,21,21,21,20,22,21,21,22,22,23,23,23,22,23,22,22,23,24,25,24,24,24,25,25,24,24,25,23,23,22,23,22,21,20,21,22,21,20,20,21,22,21,21,23,20,22,22,21,21,22,22,21,22,22,22,25,23,23,23,24,25,25,23,25,24,22,22,25,23,23,21,21,21,21,21,21,23,23,21,21,23,19,21,21,19,18,18,19,16,17,20,18,19,18,20,20,20,20,22,21,22,22,23,23,24,23,23,25,25,24,24,24,23,23,23,23,23,23,22,21,20,20,20,19,19,19,17,18,20,19,20,20,19,20,20,19,20,19,22,19,20,22,21,19,21,22,19,19,20,22,19,21,24,20,23,24,22,19,21,21,19,21,18,15,18,17,12,14,16,12,11,13,11,15,15,15,17,13,16,17,16,14,18,20,15,18,19,18,15,17,18,19,19,15,14,18,15,13,14,14,15,11,15,14,13,13,17,15,14,14,17,18,16,19,19,19,17,16,17,17,17,19,18,19,19,20,20,20,19,21,21,21,22,22,22,22,22,23,23,24,24,22,25,23,25,25,26,25,26,26,26,25,26,26,25,26,27,28,27,27,27,28,28,28,28,28,29,28,30,28,29,29,29,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30],[30,30,30,30,30,30,30,29,29,29,29,28,29,28,29,28,29,28,28,28,28,27,28,28,27,28,29,27,28,28,27,29,29,29,28,28,27,28,27,28,28,27,25,26,26,25,24,24,22,23,22,20,20,20,20,20,19,19,18,15,16,14,15,13,12,16,15,17,18,17,19,18,20,22,20,21,22,22,22,19,24,24,23,22,24,23,22,22,23,25,24,25,26,25,25,26,26,27,28,28,28,28,28,28,28,28,28,28,27,28,28,28,27,28,27,28,28,28,27,29,28,27,28,28,27,28,28,28,28,27,27,27,27,27,27,27,27,27,28,27,28,27,28,28,28,28,28,28,27,28,28,28,26,26,26,25,27,27,25,26,25,23,25,27,26,24,26,28,26,26,27,27,27,28,27,28,27,28,27,27,27,28,26,27,27,28,27,28,28,26,27,28,27,26,26,26,27,27,25,27,26,25,25,26,26,25,23,24,24,24,26,26,25,27,27,27,26,27,27,27,25,28,28,23,26,27,27,24,25,27,24,24,25,25,25,26,27,27,27,27,27,27,27,28,27,27,27,28,26,28,27,27,27,26,27,26,26,26,27,27,26,26,26,26,26,26,24,26,26,22,24,26,23,21,24,24,24,26,22,25,25,23,22,21,24,25,23,21,25,24,22,24,26,25,22,24,26,24,25,23,19,22,23,22,21,23,25,23,23,25,24,27,25,26,24,24,24,24,22,22,20,21,22,17,18,19,20,17,18,18,17,16,16,11,8,7,5,4,3,3,2,2,2,1,0,1,2,2,2,3,4,5,6,9,11,10,14,14,16,16,17,18,17,19,20,20,20,20,22,23,25,23,26,25,26,25,26,25,27,27,26,27,27,26,26,25,26,26,25,25,24,25,26,24,25,23,23,25,22,24,24,22,26,24,22,26,23,24,24,24,24,24,23,22,23,21,22,21,21,20,18,19,18,20,19,19,20,21,23,24,23,21,23,24,21,22,23,24,21,24,26,24,23,25,25,25,25,26,25,27,26,26,26,26,26,25,26,27,26,25,25,22,24,25,24,23,24,24,21,23,24,22,23,21,23,24,23,24,24,25,25,26,26,25,26,27,26,27,26,25,26,26,27,27,26,27,27,28,28,27,28,27,28,27,26,26,28,27,27,26,27,27,25,26,26,25,25,22,24,24,23,22,23,23,23,22,23,22,21,21,21,21,21,19,22,20,21,22,21,23,22,23,22,21,21,24,25,22,23,24,26,26,24,23,22,24,23,23,23,23,22,22,24,21,21,22,22,21,22,21,22,21,21,22,21,21,21,23,21,19,23,23,21,21,24,22,22,25,24,23,23,25,26,24,24,25,24,24,23,24,23,23,23,22,22,21,22,20,21,22,19,22,22,19,21,21,18,17,18,19,16,18,18,20,19,18,20,19,22,21,22,22,22,23,23,24,24,22,23,25,26,24,25,24,23,24,23,22,23,23,21,22,20,20,22,21,19,20,18,19,20,19,21,20,19,18,21,19,19,19,22,19,18,21,22,19,19,22,20,19,19,20,20,20,22,20,21,22,21,19,20,20,18,20,17,16,15,14,14,15,16,15,11,14,12,16,16,16,18,13,17,18,16,15,17,20,16,18,18,18,18,17,19,17,18,17,16,15,15,16,13,12,16,12,16,14,16,15,18,16,16,16,18,18,17,20,19,18,18,19,17,18,18,19,19,19,19,21,19,20,19,22,21,20,21,22,23,23,22,22,24,25,25,24,26,26,25,27,27,26,27,26,27,27,27,26,26,27,28,28,27,28,28,28,28,29,29,28,29,29,30,29,29,29,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29],[30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,28,29,28,28,28,27,27,27,27,27,27,28,27,27,27,26,28,28,28,27,27,27,27,27,27,27,25,25,25,25,24,24,23,22,23,22,21,21,20,19,21,20,18,17,17,17,17,16,14,13,17,14,15,17,17,18,17,19,19,20,19,21,20,20,20,22,22,21,20,21,22,21,21,23,23,23,24,25,25,25,26,26,26,26,27,28,27,27,28,28,27,27,27,27,27,27,28,28,28,27,27,27,28,27,28,28,27,28,28,26,28,28,28,28,27,27,27,27,26,25,26,26,27,26,27,28,27,27,27,27,27,28,28,26,27,27,26,25,24,26,25,26,26,26,25,25,23,24,25,25,24,24,26,26,26,26,27,26,27,27,27,26,27,26,27,27,27,26,27,27,27,27,27,27,26,27,26,26,26,26,26,26,26,24,26,26,25,24,25,25,24,23,24,24,24,25,25,24,26,26,26,25,26,27,26,24,27,27,23,26,27,25,23,24,26,23,24,24,25,25,25,26,27,27,27,27,26,27,28,26,26,27,27,26,27,27,26,25,26,26,26,27,26,26,27,25,26,24,25,27,25,22,25,26,22,23,25,23,22,23,22,22,25,22,24,24,24,22,20,23,24,22,20,23,22,20,22,25,23,21,22,25,22,23,22,19,21,22,20,21,21,24,22,21,24,23,24,23,25,23,23,23,23,22,22,21,21,21,20,20,20,19,17,19,20,17,16,13,10,8,7,6,5,4,3,3,3,3,2,1,0,1,3,2,4,5,6,7,9,12,12,14,14,16,15,16,18,19,19,19,22,22,21,23,24,25,25,25,26,26,26,27,26,27,27,26,27,27,27,26,27,27,27,25,26,24,25,25,24,24,24,24,23,23,24,24,23,25,24,24,26,23,23,25,23,25,23,23,24,23,23,23,21,24,20,20,19,19,21,21,20,20,20,23,23,23,21,22,23,22,21,22,24,23,22,25,25,24,24,24,26,25,26,25,26,25,25,23,25,26,23,25,26,24,24,25,24,23,23,24,23,24,23,22,21,23,22,21,21,21,23,22,22,21,22,24,24,24,25,26,26,26,26,26,25,26,27,26,26,26,26,26,27,27,27,26,26,27,26,25,24,26,26,25,24,26,26,24,24,24,24,24,22,23,22,22,22,22,21,20,21,23,19,19,20,19,17,19,20,19,18,20,21,22,22,21,22,21,22,21,23,22,22,23,23,25,24,24,22,23,23,22,21,22,21,21,21,21,19,19,19,19,19,20,18,19,17,20,21,18,18,19,22,19,18,22,21,18,19,22,19,20,22,22,20,21,23,23,23,23,24,21,21,22,23,20,21,21,20,19,21,21,20,20,21,20,20,21,19,19,20,17,17,19,16,15,15,16,20,18,18,18,19,19,19,21,19,20,22,21,24,24,22,23,24,25,23,24,25,23,23,23,22,22,21,20,21,19,19,21,19,19,19,17,16,20,17,18,18,17,16,19,18,17,17,20,18,16,20,20,19,18,19,20,18,20,21,20,20,22,19,22,23,21,20,20,19,19,19,21,17,16,15,13,14,16,12,11,13,13,17,16,17,17,14,16,18,14,15,17,19,17,17,19,19,17,17,19,20,20,20,18,17,18,16,15,15,16,11,14,16,16,17,17,16,16,16,19,20,19,20,20,21,18,19,19,18,20,21,20,20,22,21,20,22,19,23,21,21,23,22,22,21,22,23,22,24,24,23,25,25,25,25,25,26,26,25,26,26,27,26,26,27,28,28,28,28,28,29,29,28,29,28,29,29,30,29,30,29,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29],[30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,28,29,28,28,28,27,27,28,27,27,28,28,27,28,27,26,28,27,28,27,27,26,26,26,26,26,26,25,25,24,24,24,22,22,22,22,20,20,21,19,19,19,19,17,16,15,15,14,12,12,14,14,15,16,15,18,18,20,20,21,21,21,21,21,21,23,23,22,22,23,24,23,23,25,25,25,25,27,27,26,26,28,27,28,28,28,27,28,28,28,28,28,27,28,28,28,28,28,28,28,28,28,28,27,28,28,27,28,28,27,29,29,28,28,27,27,28,27,27,26,27,27,28,28,27,29,28,28,28,28,28,28,29,27,27,28,27,26,26,27,26,27,27,26,26,26,25,24,27,26,25,25,27,27,26,27,29,28,28,28,28,27,28,28,27,28,28,27,28,28,28,28,28,28,27,28,27,28,27,28,27,27,27,26,27,27,26,26,26,26,25,24,25,26,26,26,26,27,27,27,27,26,28,28,27,26,29,29,25,26,28,27,25,25,27,24,25,24,26,25,25,26,27,27,28,27,27,28,29,27,27,28,28,27,27,27,27,26,27,27,27,28,27,27,27,27,27,26,27,27,27,24,26,27,23,24,26,24,23,25,24,25,27,24,24,26,25,25,22,25,26,23,23,24,23,22,24,26,25,24,23,26,24,24,24,22,22,24,21,22,23,25,24,23,25,25,26,24,26,24,24,24,24,22,22,22,21,21,20,19,20,20,19,19,19,17,16,15,10,9,7,6,5,4,4,3,3,3,3,2,1,0,1,3,3,5,6,7,8,10,13,14,13,16,16,16,18,19,18,18,21,21,20,22,24,23,25,25,24,26,26,26,25,26,26,26,26,26,27,26,27,27,26,25,25,24,26,24,24,23,23,24,23,23,24,24,24,25,24,24,25,23,24,23,23,24,23,22,23,22,22,21,21,21,19,20,20,20,20,21,21,22,22,25,23,23,22,23,23,23,23,22,23,23,23,25,24,24,23,25,25,24,26,25,25,26,25,25,25,26,24,25,25,25,24,26,24,24,23,24,22,24,24,24,22,23,22,22,22,23,23,23,23,23,23,25,25,24,25,27,27,25,27,27,26,26,27,27,27,27,26,27,28,27,27,27,27,28,27,27,26,27,26,27,26,27,27,25,26,26,25,26,23,24,24,25,23,24,23,22,21,23,21,20,20,21,20,20,21,20,21,22,23,24,25,23,23,23,24,24,24,24,24,24,24,26,25,26,24,25,26,25,23,24,23,24,22,22,21,21,20,21,20,22,19,21,19,20,22,21,20,21,23,22,20,23,22,21,21,23,22,22,25,23,23,22,25,25,24,24,25,23,22,23,25,23,22,21,22,21,21,22,20,23,24,21,21,23,21,21,22,18,19,19,19,17,16,18,18,18,17,18,19,20,20,22,21,22,23,23,25,25,23,25,25,26,24,25,26,24,24,25,24,23,23,22,20,19,21,21,19,19,20,17,17,19,17,19,19,19,18,19,19,19,18,21,18,20,22,22,20,21,22,21,20,21,23,21,22,25,23,23,25,23,21,21,21,20,21,22,16,18,17,14,15,17,12,11,14,12,15,17,19,17,14,17,19,16,15,19,21,16,18,22,20,18,19,20,20,19,19,14,17,17,14,13,15,16,11,15,17,16,13,19,18,16,16,20,20,19,21,20,21,20,20,20,19,20,21,19,21,20,21,21,21,22,23,22,23,22,23,24,23,24,24,23,25,25,25,26,26,26,25,26,26,27,26,27,27,27,28,27,27,28,28,28,28,28,29,28,28,29,29,28,28,30,28,29,29,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30],[30,30,30,30,30,30,30,29,29,29,29,28,29,29,29,28,29,28,27,29,27,27,28,27,27,28,28,27,28,27,26,28,27,27,28,27,26,27,26,26,25,26,26,25,24,24,25,23,23,24,23,22,21,22,21,21,20,20,19,17,18,17,16,15,15,17,16,17,19,19,20,20,22,23,24,23,24,24,23,23,25,25,24,24,25,26,25,23,25,26,25,25,28,27,27,28,28,27,28,28,29,28,29,29,29,28,29,28,28,28,28,29,28,29,28,28,29,29,28,29,29,28,29,28,27,29,29,29,29,28,28,28,27,27,27,28,28,28,28,28,30,28,29,29,28,29,29,29,28,28,29,28,27,27,28,26,28,28,27,26,27,26,26,28,27,26,26,28,28,28,28,29,29,28,29,28,27,28,28,28,29,29,27,28,29,29,28,28,29,28,29,28,28,28,28,28,27,28,26,28,28,26,26,27,27,25,23,26,26,25,26,27,28,28,29,28,27,28,29,28,27,29,29,27,28,29,28,27,27,28,27,27,26,27,26,26,27,28,27,28,28,28,27,29,28,28,28,28,28,28,28,27,28,27,28,26,28,28,27,28,27,28,28,28,28,28,26,27,28,24,26,27,24,24,26,23,26,27,24,24,27,25,26,23,26,27,25,25,26,26,23,26,28,27,26,25,27,26,26,26,24,25,26,24,25,25,26,26,25,26,26,27,25,26,25,25,26,25,23,25,22,23,22,20,20,21,21,19,19,19,17,17,16,13,10,7,7,5,5,4,5,4,4,3,3,2,1,0,2,4,4,5,6,7,10,11,12,14,15,15,16,17,18,17,19,19,21,20,21,21,24,23,25,24,25,25,26,25,26,26,25,26,25,25,25,26,26,25,24,25,23,25,23,24,22,23,23,23,23,24,24,23,25,24,24,24,23,23,23,23,24,24,21,23,22,22,21,20,22,19,19,21,20,21,20,21,22,24,26,25,24,24,25,25,23,22,24,24,22,23,26,24,22,23,25,25,25,25,26,26,26,27,27,26,27,25,26,26,26,24,26,23,25,25,23,24,25,25,24,24,24,22,23,24,23,25,26,25,26,26,26,27,27,26,27,27,27,27,27,27,26,27,27,26,27,26,27,28,27,27,28,27,28,27,28,28,28,28,27,27,27,28,27,27,27,26,27,25,26,26,26,24,26,25,23,23,25,22,21,21,21,21,21,21,22,21,22,22,23,25,23,24,23,25,22,25,26,24,24,25,27,26,26,25,25,26,25,24,25,24,23,23,23,20,21,23,22,21,23,22,21,21,23,24,22,22,23,25,24,23,26,24,23,24,25,24,25,26,25,25,25,27,26,27,26,27,26,24,25,27,24,24,24,23,23,21,23,20,23,23,20,22,23,21,19,21,21,20,20,20,20,21,21,21,21,21,20,22,22,23,23,24,23,24,25,26,26,25,26,27,27,25,26,27,25,25,26,24,23,24,24,23,21,22,23,22,23,22,21,19,22,20,22,20,22,21,23,21,21,20,22,19,21,22,22,21,21,22,21,22,21,23,22,21,24,22,23,23,22,20,20,20,20,21,19,17,19,20,13,16,18,14,14,17,16,18,19,20,19,17,18,19,17,16,18,20,18,18,21,19,18,18,19,17,18,18,15,16,16,14,14,14,15,12,13,16,15,15,18,19,18,17,19,21,19,22,21,21,20,20,17,19,19,19,19,20,19,20,20,21,21,21,21,23,22,22,24,23,23,24,24,25,26,25,27,26,26,26,27,27,28,27,28,27,27,27,27,27,29,28,27,28,28,28,28,28,29,28,29,28,30,28,29,29,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,29,30,30,29,30],[30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,28,28,28,28,28,27,27,27,27,27,27,27,27,27,28,26,28,27,28,28,27,27,27,27,27,26,26,25,26,25,24,25,24,23,23,24,23,21,21,21,21,19,20,19,17,18,18,17,14,17,19,19,21,23,22,23,21,24,25,25,23,25,26,25,22,26,26,24,23,26,27,25,24,26,27,25,27,28,28,28,29,28,28,29,29,29,29,29,28,29,29,29,29,29,30,29,30,29,29,29,29,29,30,30,30,30,28,29,30,29,29,30,30,29,29,28,28,28,28,27,28,28,28,28,29,30,29,29,29,29,29,29,30,29,29,29,29,28,27,29,27,28,28,28,28,28,26,28,29,28,26,28,29,28,29,29,29,29,29,29,29,28,29,28,29,29,29,28,29,29,29,29,29,29,28,29,28,28,28,28,28,27,28,27,28,28,27,26,27,27,26,25,27,27,27,28,28,28,29,29,29,28,29,29,29,28,29,30,27,28,29,29,27,28,29,27,27,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,28,28,28,28,29,28,28,28,28,28,28,29,26,26,27,26,25,26,25,25,28,25,27,28,27,27,23,27,28,26,24,27,27,24,26,28,27,25,25,28,27,26,25,24,25,27,25,25,26,28,25,25,28,27,27,27,28,27,28,27,26,25,25,24,24,24,23,23,23,23,21,23,23,21,20,18,14,9,9,8,6,6,4,5,4,4,4,3,3,2,1,0,2,4,4,5,7,9,10,10,11,13,15,16,17,18,20,19,20,22,21,22,23,24,24,26,25,25,25,26,25,26,25,25,26,25,25,26,26,26,26,25,25,24,24,24,24,23,23,23,23,22,24,24,23,24,25,23,25,25,25,25,23,26,26,24,25,25,24,25,24,25,24,23,23,23,24,23,22,22,24,26,27,25,24,26,27,26,24,26,26,24,25,28,26,25,27,27,28,27,28,28,28,28,28,28,28,29,27,28,28,27,27,28,26,27,27,26,25,27,27,25,25,26,26,25,25,25,27,26,26,26,27,27,28,28,28,29,28,28,28,28,27,28,28,28,28,28,29,29,29,29,28,29,29,29,28,29,28,29,29,28,28,29,28,27,27,27,27,28,24,26,26,27,26,26,26,24,24,26,22,22,22,22,20,21,21,23,21,23,23,24,26,24,27,24,26,24,26,27,24,25,27,27,27,26,25,27,27,25,23,27,24,24,23,25,21,22,24,24,21,23,23,23,21,23,25,21,21,24,26,22,23,25,25,24,23,26,25,23,27,26,25,25,27,28,27,26,27,26,25,26,27,24,25,25,24,23,23,25,22,23,24,22,22,23,21,22,23,19,19,22,19,21,20,21,22,22,22,22,23,24,24,24,25,24,26,25,27,27,25,26,28,28,26,28,27,25,26,26,26,25,24,24,25,22,23,24,25,24,24,23,21,25,22,22,22,22,22,23,22,22,22,24,21,21,23,22,21,22,23,23,21,23,23,22,22,24,22,23,23,22,21,22,21,20,23,18,17,19,20,15,16,20,16,14,20,19,20,20,24,22,21,21,21,20,20,22,22,20,21,23,22,20,21,21,19,21,21,18,18,20,16,14,15,20,14,16,20,21,18,21,22,21,19,22,23,21,23,24,23,23,24,22,20,21,22,21,22,22,22,22,23,21,25,24,23,25,24,25,24,25,25,26,26,26,27,28,27,28,28,28,27,28,28,29,28,29,27,28,29,29,29,29,29,30,29,29,29,30,29,30,29,30,30,30,29,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,30,30,30,30],[30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,28,28,28,28,28,28,28,28,26,28,28,28,28,27,27,28,27,27,27,26,26,25,25,24,24,23,22,23,24,22,21,22,21,20,20,20,19,18,17,19,18,16,17,20,20,21,23,23,22,23,24,25,26,24,26,27,25,24,25,27,25,25,26,28,26,26,27,28,27,28,28,28,29,29,29,29,29,29,30,29,29,29,30,29,29,29,29,30,29,30,30,30,29,29,29,30,30,30,30,29,30,30,29,30,30,30,29,29,28,29,29,28,28,29,29,28,28,29,29,29,29,29,30,30,29,30,29,29,29,29,28,28,29,28,29,28,29,28,28,27,27,29,28,27,28,29,28,29,29,29,29,30,30,29,28,29,29,29,29,29,29,29,30,29,29,29,30,29,29,27,29,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,28,28,27,29,29,29,29,29,29,29,28,30,30,28,29,30,29,27,28,29,28,27,27,28,28,28,29,29,29,29,29,29,29,30,29,29,30,30,29,29,29,28,28,29,29,28,29,29,29,29,29,29,28,29,29,28,28,29,29,26,28,28,28,26,27,27,27,28,27,27,28,28,28,24,27,28,27,26,28,27,25,27,29,28,26,27,28,28,27,26,25,26,28,24,26,27,29,25,26,28,28,28,28,29,28,28,28,28,26,25,25,25,26,24,24,24,24,22,24,23,24,22,19,15,11,9,9,8,9,7,7,5,6,6,4,4,4,3,2,0,3,4,4,6,8,10,11,12,14,13,15,18,16,19,20,20,22,20,21,24,24,24,26,25,27,27,27,26,27,27,26,27,26,26,26,26,26,26,24,25,23,25,24,23,24,22,23,24,23,24,24,24,26,24,24,26,25,26,25,26,27,26,26,27,26,26,25,25,25,24,25,23,24,26,25,23,24,25,27,28,27,25,27,28,27,25,27,28,26,26,29,28,27,28,28,29,29,28,28,29,29,29,28,29,29,27,29,28,27,28,28,26,27,28,27,26,29,28,26,26,28,27,25,26,26,28,26,27,26,28,28,28,27,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,29,29,28,29,28,27,28,26,27,27,27,26,27,26,25,25,27,23,23,24,23,22,23,22,23,23,25,24,26,27,26,27,26,26,26,27,27,26,27,27,28,27,28,27,28,28,26,26,28,25,26,26,27,23,24,25,25,23,24,25,24,22,24,26,23,23,25,27,24,25,27,26,25,25,27,25,25,27,28,25,26,27,28,27,28,28,27,25,27,28,25,26,26,25,24,26,26,24,26,25,24,24,24,24,24,24,23,22,23,21,21,20,22,22,23,22,21,23,22,23,25,24,24,26,26,28,27,25,27,28,28,27,28,28,26,26,27,27,25,24,25,25,22,24,24,24,23,24,22,22,24,23,24,22,22,24,24,23,23,22,25,23,24,25,25,23,25,25,25,25,26,27,25,25,27,26,26,27,25,24,25,25,24,25,22,20,20,22,18,19,21,18,17,21,18,22,23,25,24,22,24,24,22,23,25,25,23,23,26,25,23,23,24,23,24,23,20,21,20,17,16,18,20,16,20,21,20,22,23,22,23,23,25,25,22,25,25,25,25,24,24,23,23,25,22,25,25,26,25,26,24,27,26,25,27,27,27,25,27,28,26,28,29,27,28,28,29,29,29,29,29,28,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,30,30,30,31,30,31,30,31,30,31,31,30,31,31,30,30,30],[30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,29,28,29,28,28,29,28,28,28,29,28,28,28,27,28,28,29,28,28,27,28,27,28,27,27,26,26,26,26,26,25,23,24,25,24,22,24,22,23,22,21,20,20,19,19,18,16,18,19,21,22,22,24,24,25,25,27,27,26,27,27,26,25,27,28,27,26,28,28,28,27,28,29,28,28,29,29,29,30,30,29,30,30,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,29,29,29,29,28,28,30,29,29,30,29,30,29,30,29,30,30,30,30,30,30,30,29,29,28,30,29,29,29,29,29,29,28,28,29,29,28,28,30,29,29,29,30,30,30,30,30,29,30,29,29,30,30,29,29,30,30,29,30,30,29,30,29,30,29,29,29,29,29,28,29,29,29,29,29,28,28,27,29,29,29,29,29,29,29,30,29,29,30,30,30,29,30,30,29,29,30,29,28,29,29,29,28,28,29,28,28,29,29,29,29,29,29,29,30,29,29,29,30,30,30,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,30,29,29,29,28,29,29,29,28,28,27,28,29,27,28,29,29,29,26,29,29,28,28,28,29,26,28,29,29,28,27,28,29,28,28,27,26,28,27,27,27,29,27,27,28,28,29,27,28,28,28,29,27,26,27,26,25,26,25,25,24,25,23,23,23,23,22,20,18,13,13,10,9,11,10,11,7,6,8,6,5,4,4,3,1,0,2,3,5,6,7,10,12,13,13,15,17,18,19,19,20,22,21,21,23,23,24,26,23,26,25,25,26,26,26,25,25,25,25,26,26,26,26,25,25,24,24,24,22,24,23,23,23,23,24,23,23,24,24,23,24,24,24,25,26,26,26,25,26,24,25,24,24,25,23,24,25,24,26,25,25,25,27,29,28,27,27,28,28,27,26,28,28,26,27,29,27,26,27,28,27,27,28,28,28,29,28,29,28,29,28,28,27,28,26,28,26,27,29,26,27,28,28,26,27,27,26,27,27,28,28,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,30,29,29,29,29,29,29,29,30,29,29,29,29,28,30,28,28,29,29,28,29,29,26,27,29,26,25,25,25,24,25,25,25,25,26,26,26,28,28,29,28,29,27,28,29,28,27,28,29,28,28,27,28,28,28,27,29,27,27,27,28,25,25,27,27,24,27,27,25,24,27,28,25,25,27,28,26,27,28,27,26,27,29,27,27,28,29,29,28,28,29,29,29,29,29,27,29,29,28,28,28,27,27,27,27,26,28,28,26,27,27,26,25,26,25,24,26,24,25,23,25,25,24,24,23,24,25,26,27,26,27,27,28,28,28,27,28,29,29,28,28,29,27,28,28,28,26,27,27,26,24,25,25,25,24,25,23,24,25,24,25,25,24,25,25,24,25,25,26,24,25,27,27,25,27,27,26,26,27,27,27,27,28,27,28,28,27,26,27,27,25,27,23,21,24,24,17,22,23,19,19,22,20,22,23,24,24,22,24,24,23,23,25,26,21,25,26,26,23,25,26,24,25,24,21,22,23,18,17,19,20,15,18,21,19,20,24,24,22,23,25,25,24,26,26,26,26,26,25,23,25,26,25,27,25,27,27,27,26,28,27,28,28,28,28,26,27,28,28,29,29,29,30,29,29,29,29,29,29,29,30,30,29,29,28,29,30,29,29,29,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,31,31,30,30,31,30,30,30,31,31,30,31,31,30,30,31,31,31,31,30,31,31,31,31,31,31,30,31,31],[31,31,31,30,31,31,30,30,30,30,30,29,30,29,30,29,29,29,28,29,28,28,28,28,28,28,29,28,28,28,27,28,27,28,28,27,27,27,27,27,26,26,25,25,25,25,25,25,23,24,25,24,22,24,23,22,23,24,22,22,21,22,22,20,22,23,24,24,26,27,26,27,28,28,29,28,29,29,29,26,28,29,29,28,29,30,29,28,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,30,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,30,29,30,29,29,29,29,29,29,30,29,29,29,30,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,29,30,30,30,29,30,30,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,30,30,29,30,30,30,30,30,30,29,30,29,29,30,30,29,29,28,29,30,29,29,30,30,30,28,30,30,29,29,30,29,28,30,30,30,29,29,29,29,29,29,28,28,29,28,29,29,30,28,28,29,29,30,29,29,29,29,29,29,28,28,27,27,27,26,26,26,27,24,26,25,24,25,21,19,16,16,14,11,12,11,11,9,7,8,7,6,6,4,4,4,2,0,2,4,5,6,7,9,13,13,15,17,17,19,19,19,21,21,21,22,24,23,26,25,26,26,26,25,26,25,24,25,24,24,25,25,25,26,23,24,23,24,23,24,23,23,22,24,24,24,26,24,26,25,24,26,25,26,26,25,27,26,25,27,26,26,25,26,25,25,25,26,24,27,26,26,26,28,29,29,29,28,29,29,28,28,29,29,27,28,30,29,27,28,29,28,29,29,29,29,30,29,30,29,30,29,29,29,29,27,29,26,28,29,27,28,29,29,27,28,29,27,28,28,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,30,29,29,29,30,29,29,29,28,28,29,27,27,27,27,27,26,26,27,27,28,28,29,30,29,29,28,29,28,29,29,29,29,29,30,30,30,29,30,30,29,28,29,28,28,29,29,26,26,28,29,26,28,28,27,25,28,29,27,27,29,29,27,28,29,28,28,28,29,28,28,29,29,29,29,28,29,29,29,30,30,28,29,30,28,29,28,29,28,29,28,26,28,28,27,27,27,27,27,27,26,26,27,24,26,26,27,27,26,26,27,27,27,28,28,28,28,29,29,30,29,28,29,30,29,29,30,30,28,29,29,29,29,29,28,28,27,27,27,28,28,27,27,25,27,27,28,26,26,26,27,26,26,26,27,26,26,28,28,26,27,27,27,27,28,27,27,26,29,27,28,28,27,26,26,27,25,27,25,22,25,25,21,24,26,23,22,25,24,26,26,27,26,25,25,25,26,24,25,26,22,25,26,27,23,25,25,24,24,24,19,23,23,18,18,19,19,19,21,22,21,23,24,25,25,23,26,26,25,27,27,26,26,26,26,24,25,26,24,26,25,26,26,27,26,28,27,28,28,28,29,28,28,29,29,30,29,29,30,29,30,30,30,29,29,29,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31],[31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,28,28,28,28,28,29,28,29,28,29,29,27,28,28,27,28,27,27,26,26,26,25,27,25,24,26,26,25,23,24,24,23,23,23,22,22,22,23,23,21,24,26,25,27,27,28,28,27,29,29,29,28,29,29,29,28,29,29,29,28,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,30,30,30,30,31,31,31,30,30,30,31,31,31,30,30,31,30,30,30,31,30,30,30,30,30,30,29,29,29,30,29,30,30,30,30,30,30,30,31,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30,29,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,29,29,29,30,29,29,29,30,29,29,30,30,30,30,30,29,30,30,30,29,29,28,28,29,27,28,28,27,26,28,27,28,26,25,22,19,18,17,15,13,12,13,12,11,10,7,9,7,6,5,5,4,2,0,2,4,5,6,9,10,11,14,16,16,19,19,19,21,21,21,23,25,23,26,24,25,26,26,25,26,25,24,25,24,25,24,25,25,25,24,24,24,24,24,22,23,22,21,23,22,24,24,23,25,24,24,26,24,26,26,26,27,27,26,28,27,27,27,27,27,27,28,27,27,28,29,27,27,29,29,30,29,28,30,30,29,28,29,30,28,28,30,30,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,29,30,28,29,30,29,28,30,30,28,29,30,29,28,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,30,30,29,30,30,29,28,30,28,28,28,28,27,27,27,27,27,28,27,29,30,29,30,29,30,29,29,29,29,29,29,30,30,30,29,30,30,29,29,30,29,29,29,30,27,28,29,28,27,29,29,28,26,29,29,28,27,29,29,28,29,29,29,28,29,29,29,28,30,30,29,29,29,30,30,30,30,30,29,29,30,29,30,29,29,28,29,29,27,29,29,28,28,28,27,27,28,27,27,28,26,28,26,27,27,28,27,27,28,28,28,29,29,28,29,29,30,30,29,29,29,30,29,30,30,29,29,30,29,29,29,28,29,27,28,28,28,28,28,28,27,29,28,28,28,27,28,28,27,28,27,29,27,28,29,29,27,29,28,29,28,29,29,28,28,29,28,29,29,28,27,27,27,27,28,27,24,27,28,23,26,27,25,24,28,26,27,27,29,29,27,28,27,28,27,27,28,26,27,28,28,26,27,28,27,27,26,23,25,25,22,21,22,24,24,25,25,25,26,27,27,27,27,28,28,27,29,29,28,28,28,27,26,27,28,26,28,27,28,27,28,27,29,29,29,29,29,29,28,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,31,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,30,31,31,31,31,30,31,30,30,30,30,30,30,30,30,30,29,30,29,29,30,29,29,29,29,29,29,30,28,29,28,29,29,28,28,29,28,28,28,28,27,27,27,26,27,26,24,25,26,24,25,25,24,24,23,23,22,21,21,22,21,20,24,25,27,26,27,27,28,28,29,29,29,28,30,30,29,28,29,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,30,31,31,30,30,31,30,30,31,31,31,30,31,30,31,30,31,30,31,31,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,31,31,30,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,31,31,30,30,31,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,29,30,30,30,30,29,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,29,28,29,28,28,28,28,27,26,23,21,22,21,16,18,17,15,14,15,13,10,10,10,9,7,7,6,4,2,0,1,4,5,7,8,10,12,14,16,18,18,20,20,20,21,23,25,23,26,25,26,26,27,25,27,26,25,26,25,25,26,27,26,26,24,25,22,23,24,21,24,22,22,24,22,25,24,23,26,25,24,26,26,26,26,27,27,27,26,27,27,27,26,27,28,27,28,28,28,29,29,29,29,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,29,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,31,30,31,31,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,28,28,28,29,28,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,29,29,30,29,29,30,29,28,28,30,30,28,29,29,29,28,29,29,28,29,30,30,28,30,30,30,29,29,30,30,29,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,29,29,29,29,28,28,29,28,28,27,27,27,28,27,28,28,28,28,29,28,29,29,29,30,30,29,29,30,30,29,30,30,29,30,29,30,29,29,29,29,28,28,28,29,28,29,28,27,28,28,29,28,28,28,28,28,28,28,29,28,28,30,29,28,30,30,29,30,30,30,29,29,30,29,30,30,29,29,29,29,29,29,29,27,28,28,25,27,27,26,25,27,26,27,28,28,28,27,28,27,28,28,28,28,27,29,29,29,28,28,29,28,28,27,26,27,27,23,23,26,26,23,26,28,27,27,29,28,28,28,29,29,29,30,29,29,29,29,28,27,28,29,28,29,28,29,28,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,29,30,29,29,29,29,28,28,29,29,29,29,29,28,29,28,29,29,28,28,28,28,28,28,28,27,26,27,26,27,25,26,27,27,25,25,26,26,25,25,25,24,23,23,24,23,23,26,26,27,27,27,29,29,29,29,29,30,29,30,30,30,29,30,30,30,30,30,30,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,31,31,30,31,30,30,30,30,30,31,30,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,30,31,30,30,30,31,31,30,31,31,31,30,31,31,31,31,31,30,31,31,31,30,30,31,31,30,31,31,30,30,30,31,30,30,30,30,30,30,31,30,30,31,30,31,31,31,31,31,30,31,30,30,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,31,31,30,30,31,31,30,31,31,31,30,30,31,31,31,31,30,30,30,31,30,30,31,30,31,30,30,30,30,30,30,30,30,30,31,31,30,30,31,30,30,30,30,30,30,29,30,30,30,30,29,30,30,31,30,30,30,30,30,30,29,30,29,29,29,28,28,29,29,28,28,27,28,27,25,24,22,22,21,17,19,20,19,15,14,15,13,11,10,10,7,7,5,5,4,2,0,1,3,4,7,8,10,13,14,16,17,18,20,19,20,23,23,23,25,24,24,24,25,24,26,24,24,25,24,24,25,25,24,24,23,24,21,24,23,22,23,23,22,23,23,25,25,24,25,25,24,25,25,26,26,26,27,26,26,27,27,27,26,27,26,26,28,29,27,29,29,29,29,30,30,30,30,29,30,30,30,29,30,30,30,29,30,30,29,29,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,29,30,28,30,30,29,29,30,30,29,30,30,30,30,30,30,31,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,31,31,31,30,30,30,31,30,30,30,30,29,29,30,29,30,30,30,31,31,30,31,30,31,30,30,30,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,31,29,30,30,30,29,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,30,31,30,31,30,30,30,30,30,29,30,30,29,30,30,29,30,30,29,29,30,28,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,31,31,30,31,31,30,31,30,31,30,30,30,30,29,29,30,30,29,29,29,29,29,29,30,29,29,29,29,29,29,28,29,29,29,30,29,29,30,30,30,30,30,30,30,29,30,30,30,30,29,29,29,29,28,29,29,27,29,29,25,28,28,27,26,28,28,28,29,29,29,29,29,28,29,29,29,29,28,29,29,30,28,29,29,29,29,27,25,28,28,23,24,26,26,24,27,27,26,27,29,28,28,28,30,29,29,30,29,30,29,29,29,28,28,28,28,29,29,29,29,29,29,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,30,31,30,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,30,29,29,29,29,29,29,28,28,28,28,28,28,29,28,29,28,29,29,28,28,28,28,28,28,28,26,26,27,26,27,26,25,26,27,25,23,25,25,25,25,26,24,24,25,25,25,26,27,28,28,29,29,30,29,29,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,30,31,30,31,31,30,30,31,31,30,31,31,31,31,31,31,30,30,31,30,31,31,31,30,30,31,31,30,31,31,30,30,30,31,30,30,30,30,30,30,31,30,30,30,30,30,31,31,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,31,31,31,30,31,30,31,30,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,31,31,31,31,31,31,31,30,30,30,30,31,31,31,30,30,31,30,31,31,30,30,30,30,30,30,31,30,30,31,30,31,31,31,30,31,31,30,30,30,29,30,30,29,30,30,30,29,30,29,29,28,27,26,24,24,23,19,21,18,20,17,14,17,16,13,12,12,10,8,8,6,5,4,2,0,1,3,5,6,8,10,11,13,15,16,18,18,19,21,23,23,24,23,23,24,24,24,25,24,23,24,24,24,24,25,25,25,23,24,23,23,22,22,22,22,22,23,22,24,23,24,24,23,24,26,25,26,26,25,28,27,26,27,27,27,27,27,28,28,29,29,29,30,30,29,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,30,29,29,30,29,29,30,30,30,31,30,30,30,30,30,30,30,30,29,30,29,30,30,29,29,30,30,30,30,30,30,30,30,30,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,30,30,31,30,30,31,31,30,31,30,30,30,31,30,30,30,30,29,30,30,29,29,30,29,30,30,30,31,30,30,30,30,30,30,30,31,31,31,30,30,31,31,30,30,31,30,30,30,31,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,30,29,30,30,29,30,30,29,29,30,28,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,30,31,30,30,31,31,31,30,30,30,29,29,30,30,30,30,29,29,30,30,30,30,29,30,30,29,30,30,30,29,30,30,30,29,30,30,30,30,30,30,29,29,30,29,30,30,30,28,28,29,28,29,28,27,29,29,27,29,29,28,28,29,29,30,29,30,30,29,30,29,29,29,29,29,28,29,29,29,28,29,29,28,28,27,25,28,28,23,23,27,26,27,28,27,27,29,29,29,29,30,30,30,29,29,29,29,29,29,29,27,27,28,28,29,28,28,28,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,30,30,30,30,30,29,29,30,29,29,29,29,29,29,29,28,30,29,29,29,29,29,28,28,29,28,28,27,28,27,27,27,27,25,27,26,25,25,26,25,25,25,25,25,23,24,25,25,25,28,28,28,29,29,30,30,30,30,31,30,30,31,30,30,30,31,31,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,30,30,29,30,29,29,29,28,26,27,25,23,20,23,22,21,19,18,17,16,15,14,14,11,10,10,7,7,6,4,2,0,1,4,4,5,7,7,11,12,14,16,17,18,19,21,21,24,22,24,24,25,25,26,24,24,24,24,25,25,25,25,25,23,24,21,23,23,22,22,22,22,22,22,24,25,23,26,24,25,25,25,27,25,27,28,27,26,28,27,28,27,27,28,28,29,29,29,30,30,29,30,30,31,31,30,29,30,30,30,29,30,30,29,29,30,30,29,29,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,29,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,30,31,31,30,31,30,30,30,30,31,30,30,31,31,30,30,30,30,30,30,31,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,31,30,30,30,30,30,30,30,29,30,29,30,29,30,30,30,30,30,30,30,30,31,30,30,31,30,31,31,30,31,31,31,31,31,31,30,30,30,31,31,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,30,29,28,29,29,27,29,29,28,28,29,29,30,30,30,30,30,30,30,30,29,30,30,28,29,30,30,29,29,29,29,29,27,26,28,28,23,25,28,26,26,28,27,27,29,29,28,29,29,30,30,29,30,29,30,30,29,29,28,27,29,28,30,29,30,29,30,29,30,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,28,29,28,29,29,27,28,28,27,28,27,28,28,27,27,27,27,27,26,27,27,25,26,28,26,26,26,27,26,25,25,26,27,26,29,29,29,29,30,30,30,30,30,31,31,30,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,30,31,31,30,31,31,31,31,31,31,30,30,30,30,31,30,30,30,30,30,30,30,30,29,28,26,26,27,24,22,24,24,24,23,21,20,19,17,17,16,13,12,11,10,9,7,6,5,2,0,1,3,5,6,6,8,10,12,17,17,18,21,20,23,25,24,25,24,25,24,26,25,24,25,24,24,24,24,25,24,23,23,22,24,22,20,22,21,21,22,21,24,24,24,26,23,25,27,25,27,27,27,28,28,27,29,28,29,28,28,29,28,29,28,30,30,30,29,30,30,31,31,30,29,30,31,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,31,31,30,30,30,30,30,31,30,30,30,30,28,30,30,29,28,30,31,30,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,31,31,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,30,30,31,31,30,30,31,31,30,30,31,30,30,30,31,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,29,29,29,30,29,28,29,30,29,29,30,29,30,30,31,30,29,30,30,30,29,30,30,29,29,30,30,29,29,29,29,29,25,26,28,27,22,26,27,26,27,28,27,25,29,29,28,29,30,30,30,29,30,29,30,29,29,29,27,26,29,27,30,29,30,29,30,29,31,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,29,30,30,29,29,29,29,29,29,28,29,29,28,29,29,27,29,28,29,29,28,28,28,27,28,27,28,27,27,27,27,27,27,26,26,26,25,25,26,25,25,25,26,24,24,25,26,25,26,27,28,28,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,30,30,30,31,31,31,30,30,30,30,30,31,30,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,30,31,30,31,30,30,30,30,31,30,31,30,30,30,31,31,31,31,31,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,31,31,30,30,30,31,31,30,30,31,30,30,31,31,31,31,31,30,30,31,31,31,30,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,29,30,30,29,30,30,30,29,30,29,28,28,28,25,26,24,23,22,23,23,22,21,18,19,18,15,16,16,14,11,13,11,8,8,7,6,4,2,0,1,3,4,5,6,7,11,14,14,15,18,19,19,23,20,22,22,24,23,24,24,23,24,23,24,24,25,25,25,23,23,21,23,23,20,23,20,21,22,22,23,24,23,25,24,24,26,24,26,25,26,27,26,26,27,26,26,27,27,28,27,29,28,29,30,30,29,30,29,30,30,30,29,30,30,30,29,30,30,28,29,30,29,28,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,27,29,30,29,28,30,30,29,29,30,30,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,31,31,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,30,31,30,31,30,30,30,31,31,31,31,30,30,30,30,31,31,30,31,31,30,31,31,30,30,31,31,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,31,31,31,31,30,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,29,30,30,30,30,29,30,30,29,29,30,29,29,29,29,30,30,30,30,30,30,30,31,30,30,31,31,30,31,30,31,31,31,31,30,31,30,30,30,31,31,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,29,29,30,29,29,29,29,29,29,29,29,29,27,28,29,29,26,29,29,28,29,30,29,30,29,30,30,29,29,30,30,29,30,29,28,29,29,29,27,28,29,28,28,26,26,28,27,23,25,26,25,26,28,26,25,29,28,28,28,29,30,30,29,30,29,29,29,28,29,27,26,27,27,29,28,29,29,30,28,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,30,30,29,30,29,28,30,29,29,29,29,28,29,29,29,28,29,28,28,28,27,28,27,26,26,27,25,26,26,26,26,26,27,26,24,25,26,26,26,28,29,29,30,30,30,30,30,30,30,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,30,31,31,31,31,31,30,30,31,30,30,30,29,30,30,29,30,30,30,29,30,30,28,28,28,24,26,27,24,23,25,25,25,22,22,22,20,19,20,19,17,13,15,12,11,9,7,6,6,3,2,0,1,3,3,4,7,7,11,12,14,16,17,19,21,21,22,22,24,22,24,23,23,23,23,24,24,24,24,24,23,22,21,22,21,21,21,21,21,22,22,23,23,22,24,25,25,25,24,25,25,26,26,26,26,27,26,27,26,27,27,27,29,28,30,30,30,28,30,29,30,30,30,28,30,30,29,28,30,30,28,28,30,30,28,29,30,30,30,30,30,30,31,30,30,30,30,29,30,29,29,29,29,26,29,30,29,27,30,30,29,29,30,30,30,30,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,30,31,31,31,30,31,31,30,31,30,31,30,31,31,30,30,31,31,30,31,30,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,30,29,30,31,29,30,30,30,30,30,29,30,30,29,30,30,29,30,29,30,30,30,30,30,30,30,31,31,30,30,31,30,31,31,30,31,31,31,30,31,31,30,31,31,30,31,30,31,31,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,29,30,31,30,29,30,30,30,30,30,30,30,30,30,29,29,30,30,29,30,30,29,29,27,28,30,30,28,30,30,28,29,30,30,30,30,30,30,29,30,29,30,29,30,30,29,28,29,29,27,28,29,28,27,24,26,28,26,21,26,25,25,26,27,26,26,28,28,27,28,29,30,30,28,29,29,29,28,28,28,25,25,28,26,29,28,29,28,30,29,30,29,30,31,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[30,31,30,30,30,31,31,30,30,30,30,30,30,29,30,29,30,30,29,30,29,29,30,29,28,29,28,28,28,29,28,29,28,28,28,28,28,28,28,28,28,28,28,27,27,27,28,26,25,28,27,25,25,26,26,26,26,27,25,26,26,26,26,28,28,29,28,29,29,30,29,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,29,29,29,28,29,28,25,28,27,24,24,26,24,25,24,21,22,23,21,19,20,19,15,16,16,12,11,9,6,7,6,3,2,0,1,3,4,4,6,8,11,13,15,16,19,19,19,22,22,23,22,24,23,23,24,23,24,23,23,23,23,21,24,20,22,22,19,22,19,22,22,21,23,23,22,24,22,25,27,24,26,26,26,27,27,26,28,27,27,27,27,28,28,29,28,28,29,29,27,29,28,30,30,30,28,29,29,29,28,29,29,28,28,29,29,27,29,29,29,29,29,30,30,30,30,29,29,30,28,29,29,29,28,29,27,28,29,29,27,29,30,29,28,30,29,29,30,29,30,30,30,29,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,30,29,29,29,29,28,29,29,29,29,29,29,30,30,29,30,29,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,29,29,28,29,30,28,29,28,29,29,30,28,29,29,28,29,30,29,29,29,29,30,29,29,30,30,29,30,30,29,29,30,30,30,30,29,30,30,30,30,30,31,30,30,31,30,30,30,30,30,29,30,30,30,29,29,30,29,29,30,30,29,28,30,29,28,29,29,29,28,29,29,29,28,30,29,29,29,29,30,29,29,29,27,28,29,28,28,28,29,28,28,27,28,28,28,27,29,29,28,29,29,29,29,29,30,30,28,29,29,29,28,29,29,28,27,29,28,28,27,28,28,27,25,24,26,25,21,25,26,25,26,27,26,26,28,28,26,28,28,29,29,28,29,28,28,28,26,28,26,24,27,26,28,27,28,28,29,28,29,28,28,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30],[31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,30,30,30,29,30,29,29,30,29,29,30,30,29,30,29,28,30,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,28,27,28,28,27,26,27,27,27,27,27,26,25,27,27,27,26,28,28,28,30,29,30,30,30,30,31,30,31,30,30,30,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,30,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,31,31,30,30,31,30,31,30,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,28,29,30,30,29,30,29,28,28,28,25,27,27,23,24,26,26,25,24,22,24,23,21,21,22,19,15,19,16,14,13,11,8,7,6,5,3,1,0,1,2,4,5,5,8,11,13,15,16,19,19,21,21,22,23,24,24,23,24,23,24,24,25,25,25,24,24,22,23,23,21,21,20,21,23,22,24,24,24,25,25,25,26,25,27,26,27,28,27,26,28,27,27,27,26,27,28,29,28,29,30,30,28,30,29,30,30,30,28,30,30,29,28,29,30,28,28,30,29,26,29,30,30,30,29,30,30,30,30,29,30,30,29,30,29,29,29,29,27,29,29,29,27,30,30,29,29,30,30,30,30,30,30,31,30,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,30,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,30,30,30,30,31,30,30,30,30,30,31,31,30,30,30,30,30,31,31,31,31,31,30,31,30,31,31,30,30,31,31,30,30,30,30,29,30,31,29,30,29,29,30,30,29,30,30,29,29,30,29,30,29,30,30,30,30,30,30,30,30,31,30,31,31,30,31,31,30,31,31,31,30,30,31,30,31,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,31,30,30,30,29,30,29,29,30,29,29,30,29,28,29,29,28,29,27,28,29,29,28,29,29,28,29,30,29,29,30,30,30,29,30,30,30,28,29,29,28,28,29,29,26,27,28,26,27,25,25,26,26,22,25,25,25,26,27,26,25,28,28,27,28,29,29,30,27,29,28,29,28,26,28,25,24,26,26,28,27,28,28,29,29,30,29,29,30,30,29,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,29,29,30,30,30,29,30,29,29,29,29,29,29,29,29,29,29,28,28,27,28,28,26,27,28,27,27,27,28,27,27,28,28,27,27,29,30,29,30,30,30,30,30,30,30,31,30,30,31,31,30,31,30,30,31,31,30,31,31,31,31,31,30,31,31,31,31,30,31,30,31,30,31,30,31,31,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,31,30,31,31,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,30,30,30,31,31,30,30,30,30,31,30,30,30,30,30,30,31,30,31,30,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,31,30,30,31,30,31,31,31,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,31,30,30,31,30,30,30,31,30,31,30,30,30,30,30,30,30,29,29,30,30,29,30,30,29,29,28,26,27,28,26,26,26,25,27,24,23,25,24,22,22,23,20,17,20,18,16,15,12,10,8,7,6,5,4,2,0,1,2,4,4,6,8,12,13,16,19,18,21,21,22,23,23,24,22,24,24,25,26,25,25,25,25,25,20,24,25,21,23,21,22,24,23,24,24,24,26,24,26,27,24,28,27,26,28,27,28,28,28,28,28,26,28,27,29,28,29,30,29,28,30,28,30,30,29,27,29,29,29,25,29,29,27,27,29,28,26,28,29,29,30,30,30,30,30,30,29,30,30,29,30,29,28,29,29,27,28,29,28,27,29,30,28,28,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,31,31,30,31,31,31,31,30,31,31,31,31,30,31,31,31,31,31,31,31,30,31,30,31,31,31,31,30,30,31,30,30,31,30,30,30,30,30,30,31,30,30,30,30,29,30,30,29,30,30,30,30,30,30,31,30,31,31,30,31,31,31,31,31,30,31,31,30,31,30,31,31,30,30,31,31,30,30,31,31,30,30,30,30,29,30,30,29,30,30,30,29,30,30,30,29,30,30,30,30,31,31,30,30,30,30,30,30,30,30,29,30,31,29,30,30,30,29,29,30,28,30,28,29,30,29,27,30,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,31,31,30,31,31,30,31,30,30,30,30,30,30,30,30,29,30,30,30,29,29,30,30,28,30,30,29,28,30,30,30,29,29,30,29,29,30,28,28,28,29,27,28,28,29,28,26,28,28,29,27,29,29,28,29,29,30,30,30,30,30,28,29,29,29,28,29,29,27,27,28,28,27,26,28,27,26,24,25,27,25,21,26,25,23,26,27,26,25,28,27,26,28,29,29,30,29,29,28,28,28,26,28,26,23,26,25,28,27,28,28,29,29,30,29,29,30,29,29,30,30,30,30,31,30,30,30,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,30,31,31,31,31,30,31,31,30,30,30,30,30,30,31,30,30,30,29,30,30,29,29,30,29,29,29,29,28,29,29,29,29,29,28,28,28,28,28,29,28,28,28,28,28,27,27,28,28,26,28,28,27,28,28,28,27,28,28,28,28,28,29,29,29,29,30,30,30,29,30,30,30,30,30,31,30,29,30,30,30,30,31,31,31,30,31,31,31,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,30,30,30,30,30,31,31,31,31,31,30,31,31,31,31,30,31,30,30,31,31,31,31,31,30,31,30,31,30,31,30,31,31,30,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,30,31,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,30,30,31,31,31,30,30,30,30,30,30,30,31,31,30,31,31,30,31,31,30,30,31,31,31,31,31,31,30,31,31,30,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,30,31,31,30,31,31,30,30,31,31,30,30,31,30,29,31,31,30,30,30,31,30,31,30,29,30,31,29,30,30,30,30,29,31,30,29,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,29,30,30,28,29,28,25,27,28,25,25,26,26,27,25,23,25,25,22,23,23,22,18,21,20,18,18,15,13,11,8,7,6,6,4,1,0,1,3,3,4,5,8,10,13,16,15,19,19,20,21,23,22,23,23,23,23,23,24,24,23,23,23,21,24,23,22,23,20,22,23,23,24,25,24,26,22,26,27,25,27,27,26,28,28,28,28,29,28,29,27,28,27,28,28,29,29,29,28,29,29,30,30,30,28,29,30,29,27,29,30,27,28,29,29,26,28,29,29,29,30,30,30,30,30,29,30,30,28,29,29,28,29,29,27,28,29,29,27,29,29,28,28,30,30,29,30,29,30,30,30,29,30,30,31,29,30,31,31,30,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,31,30,30,31,30,29,30,31,30,28,30,31,29,29,30,30,28,30,30,29,30,30,30,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,31,31,30,30,31,31,29,30,30,30,29,30,30,29,30,30,30,28,29,30,29,28,29,30,28,29,30,30,29,29,30,30,29,30,30,29,29,30,30,28,29,30,29,28,30,30,29,30,27,29,30,29,27,30,30,29,29,30,29,29,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,29,28,29,29,29,28,29,29,27,30,29,28,27,30,29,29,29,29,30,28,29,30,28,28,29,28,28,29,30,28,29,27,28,29,28,28,30,29,28,29,30,30,29,29,30,29,29,29,30,28,27,28,29,28,28,28,28,28,27,28,27,25,21,24,26,25,19,24,24,23,27,27,25,25,28,26,25,28,29,29,30,28,29,28,28,27,25,27,24,20,25,24,27,28,29,28,30,28,30,30,29,30,30,29,30,30,30,29,31,30,30,30,31,31,30,30,30,31,31,31,31,31,30,30,30,31,31,31,31,31,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31],[31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,28,30,30,30,29,30,29,29,29,29,29,29,29,28,29,28,29,28,26,28,28,26,26,27,26,27,27,28,26,26,28,28,27,26,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,30,31,30,31,30,30,31,31,30,31,31,31,31,31,31,31,30,30,31,31,30,31,30,31,31,31,30,31,30,30,30,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,30,31,30,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,30,31,31,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,30,30,30,31,30,31,31,30,31,31,30,30,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,31,29,31,31,30,30,30,31,30,31,31,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,27,29,30,29,28,30,29,27,28,28,24,27,27,23,23,26,25,26,23,22,24,24,21,22,22,20,16,20,19,16,17,15,14,13,9,7,6,5,5,4,1,0,1,3,4,4,6,8,10,14,14,18,17,19,20,22,22,22,23,22,23,23,23,23,23,22,22,21,23,22,21,22,20,23,23,23,23,24,24,25,25,24,25,25,26,25,26,28,26,26,28,27,26,27,25,27,26,28,27,28,29,29,27,29,29,30,30,29,26,28,29,27,27,28,29,26,27,29,27,24,28,28,29,29,29,29,30,30,29,28,29,29,28,29,29,28,27,28,26,27,29,28,27,29,29,28,28,30,29,29,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,31,30,30,31,30,30,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,31,31,30,30,31,30,29,30,31,29,29,30,30,29,30,29,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,30,30,30,30,31,31,31,30,30,31,31,30,30,31,31,29,30,30,30,29,30,30,29,30,31,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,31,30,29,30,30,29,29,30,30,29,29,30,29,30,29,29,30,29,28,29,30,29,29,30,29,29,29,30,29,29,29,29,30,30,30,30,30,30,31,30,31,31,30,30,31,31,31,30,30,30,31,30,30,31,30,30,30,30,30,30,30,29,30,29,29,30,29,30,29,29,30,29,29,29,29,29,29,29,30,29,29,30,29,29,29,29,30,28,29,30,29,28,30,29,27,28,29,28,29,27,27,29,29,28,29,29,28,29,30,29,29,29,29,29,29,29,29,29,28,29,29,28,28,28,27,27,26,28,27,26,20,25,27,25,20,26,24,23,26,27,26,26,28,28,26,27,29,29,30,27,29,28,27,28,25,27,26,22,25,24,27,26,28,27,29,29,29,29,28,30,30,29,29,30,30,29,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,30,30,31,29,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,30,29,30,29,29,29,29,29,29,29,29,29,29,29,28,28,27,27,28,28,26,27,26,27,27,27,28,27,27,28,27,27,27,29,28,28,29,29,30,29,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,31,31,31,31,31,31,31,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,31,31,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,28,29,30,29,28,30,29,28,29,28,26,26,26,24,24,26,26,26,25,24,26,25,24,23,23,22,19,23,21,19,18,17,16,15,13,12,7,7,6,5,4,2,0,1,3,4,5,7,7,12,12,16,16,19,20,21,22,22,23,22,23,23,23,23,24,22,23,22,24,22,21,22,21,22,23,24,24,24,24,25,25,24,26,24,26,25,25,27,25,26,28,27,28,28,26,27,27,28,27,28,29,29,27,29,29,29,30,29,27,28,29,28,27,28,28,25,27,29,27,24,28,28,29,29,28,29,30,30,30,28,29,29,28,29,29,27,28,28,26,27,28,28,28,28,28,28,28,29,29,29,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,31,30,30,30,31,30,30,30,30,29,30,29,30,30,30,30,30,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,28,30,29,29,30,30,28,30,29,29,28,29,28,29,29,29,30,29,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,30,30,30,30,29,30,29,30,30,30,30,29,29,30,29,29,29,30,30,29,30,30,30,29,30,30,29,29,29,30,28,29,30,27,28,30,29,26,27,28,27,28,26,27,28,28,27,28,29,28,28,29,29,29,30,30,30,29,29,29,29,27,29,29,27,26,28,27,26,25,27,25,26,21,24,25,25,20,24,24,23,26,26,25,24,26,27,26,26,28,28,30,27,29,28,28,27,25,27,25,22,25,26,27,26,27,27,28,27,29,28,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,28,29,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,27,29,28,27,27,28,28,28,28,28,28,27,28,27,27,27,29,29,29,29,30,30,30,29,30,30,30,30,30,31,30,30,30,31,30,30,31,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,30,31,31,31,31,31,30,31,31,31,30,31,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,31,31,30,31,31,30,30,31,31,31,30,31,30,31,30,30,30,31,31,31,31,31,30,31,30,30,30,31,30,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,29,31,31,30,30,30,31,30,31,30,28,30,30,29,29,30,31,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30,29,29,29,29,28,30,29,28,29,28,26,27,27,23,25,26,26,27,24,22,25,25,24,23,24,23,18,22,21,19,18,17,17,15,14,14,10,8,7,5,4,4,2,0,1,3,5,5,7,8,9,13,14,16,18,20,20,21,23,23,23,22,23,23,23,22,24,22,24,24,22,23,21,23,24,24,25,25,24,26,23,25,26,24,27,27,26,28,28,28,29,28,28,28,27,28,28,29,29,29,29,29,28,29,29,29,30,30,28,28,29,28,26,28,28,26,27,29,28,24,26,28,28,29,29,29,30,30,30,29,29,29,28,29,29,28,27,28,25,26,28,27,28,29,29,28,28,29,29,29,29,29,30,30,30,30,29,30,30,29,30,31,30,30,31,31,30,30,31,31,30,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,30,28,29,29,30,29,30,30,30,30,30,31,30,30,30,30,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,31,30,30,30,30,29,30,30,30,29,30,30,28,29,30,30,29,29,30,29,28,29,30,28,29,30,30,29,29,30,30,29,30,30,29,28,30,30,28,28,30,29,27,30,30,28,29,27,28,29,29,27,29,29,28,28,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,30,31,31,30,31,31,31,30,30,30,30,30,30,30,30,30,30,29,30,30,30,28,29,29,29,29,29,29,29,27,29,30,29,28,30,29,29,29,29,30,28,29,29,28,28,28,28,27,28,29,27,28,26,27,27,28,27,29,29,28,28,29,29,29,29,29,29,28,29,29,29,27,29,29,28,27,28,27,27,26,27,25,25,21,23,26,26,20,24,23,23,26,27,26,26,27,27,27,28,29,29,29,28,29,27,27,28,25,27,26,22,25,26,27,26,27,27,28,27,30,29,27,29,29,28,29,29,29,29,30,30,30,30,30,30,30,31,30,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,30],[31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,30,30,30,30,30,30,29,30,29,29,30,30,30,30,30,29,29,29,29,29,29,29,29,29,28,29,28,27,29,29,28,27,29,28,28,28,29,27,27,29,28,27,28,29,29,29,29,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,31,30,31,31,31,30,31,31,30,31,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,29,29,29,27,28,28,26,25,27,27,27,25,24,26,26,23,23,25,23,18,23,22,19,19,19,17,16,15,14,12,10,8,7,5,5,4,2,0,1,3,5,5,6,8,11,12,15,17,19,20,20,21,21,21,22,22,22,22,23,23,22,23,22,22,22,21,22,23,23,23,24,24,24,24,25,25,24,26,26,27,28,27,27,28,27,28,28,27,29,27,28,29,29,29,29,28,29,28,29,29,29,27,28,28,27,27,28,29,26,27,28,27,22,26,28,28,29,28,29,29,30,29,28,29,29,28,28,28,28,27,28,26,27,28,28,27,28,29,29,28,29,29,29,29,30,30,29,30,30,29,30,30,30,30,31,30,29,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,30,31,31,30,31,31,30,29,30,31,29,30,30,30,29,30,30,30,30,30,30,31,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,30,30,31,31,30,31,31,30,30,30,31,29,30,31,30,29,30,31,30,29,30,30,29,30,30,30,29,30,30,30,29,30,30,30,28,30,31,29,29,30,30,29,30,30,29,30,29,29,30,30,28,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,29,30,30,29,30,30,29,28,30,30,29,29,29,30,29,29,30,28,29,30,29,28,29,30,29,29,27,28,29,29,28,29,30,29,30,30,30,30,30,30,30,29,29,30,29,29,29,29,28,28,28,28,27,26,28,27,27,21,26,27,26,22,28,25,25,27,27,28,27,28,27,27,27,29,29,29,28,28,28,26,27,24,26,26,23,25,24,26,27,28,27,29,28,29,29,28,30,30,29,29,30,30,29,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,30,31,31,31,31,30,31,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,30,29,29,30,29,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,28,28,28,28,29,28,26,28,28,27,28,28,29,28,28,28,27,27,27,28,28,29,29,30,29,30,29,30,30,30,30,30,30,30,30,31,31,31,31,31,30,30,31,31,31,31,30,31,31,31,31,30,30,31,31,31,31,31,31,31,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,31,31,31,31,31,30,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,31,31,30,30,31,31,31,30,30,31,31,31,31,31,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,30,31,31,31,31,30,31,31,30,30,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,30,30,30,31,30,30,31,31,30,31,31,31,30,30,31,31,30,31,31,30,30,30,31,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,28,29,30,29,28,30,29,27,29,28,26,28,28,25,25,27,27,28,26,24,26,27,24,23,26,23,20,23,23,21,20,21,20,18,17,17,15,13,11,8,7,6,6,4,2,0,1,3,5,6,7,9,11,13,15,18,20,20,22,22,23,22,22,23,22,22,22,20,23,23,22,22,21,22,23,23,24,24,25,25,25,25,26,25,26,25,27,28,26,26,28,26,27,27,26,27,25,28,28,29,29,29,27,29,28,29,30,29,27,29,29,27,27,28,28,26,26,29,25,24,26,28,27,28,28,29,29,29,29,28,29,29,28,29,29,27,26,28,26,26,29,29,27,29,29,28,28,29,29,29,29,29,30,30,30,30,29,30,30,30,30,30,31,30,31,31,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,30,30,30,31,30,30,31,31,30,30,31,31,30,30,30,30,29,29,29,30,30,30,30,31,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,30,31,31,30,30,31,31,30,31,30,30,30,31,30,30,30,31,30,29,30,30,30,28,30,30,29,29,30,30,29,29,30,30,29,30,30,30,29,30,30,29,29,30,30,29,30,30,29,30,29,29,30,30,29,30,30,29,29,29,29,29,29,30,29,30,30,29,30,30,30,31,30,30,31,31,31,31,30,30,31,31,31,30,31,30,31,31,30,31,31,30,31,30,30,30,30,29,29,29,29,29,30,30,29,29,30,29,29,29,29,29,29,30,30,29,28,30,29,29,29,29,29,28,28,30,28,28,30,29,28,29,30,29,29,27,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,27,28,27,27,27,27,26,26,21,25,26,26,21,25,24,25,26,27,26,26,28,28,27,27,29,29,30,27,28,28,27,27,24,27,25,22,25,25,26,25,27,27,29,28,29,28,28,29,30,28,30,30,30,29,30,30,30,30,30,31,31,31,30,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,30],[31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,29,30,30,29,29,30,29,29,30,29,29,29,29,28,30,29,30,29,29,29,29,29,29,29,29,29,28,29,29,29,28,27,28,28,27,27,28,28,28,28,28,27,28,28,27,27,27,29,29,29,30,30,30,30,30,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,31,30,30,31,30,30,31,31,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,29,28,29,28,26,28,28,25,26,26,27,26,26,22,27,27,25,24,26,24,21,24,24,22,21,21,20,20,17,18,17,15,13,10,7,7,6,5,5,2,0,1,3,4,5,9,10,13,14,15,17,18,20,20,21,21,21,22,22,21,21,21,22,22,22,22,21,22,23,24,24,24,24,25,25,25,26,25,26,26,26,29,27,27,28,28,28,27,28,28,27,28,28,29,30,29,28,29,29,29,30,29,27,29,29,27,28,28,28,26,27,29,26,25,26,29,26,29,28,29,29,30,29,29,29,29,28,29,29,28,28,28,28,28,29,28,28,29,29,30,29,30,29,29,29,30,30,30,30,30,30,31,31,30,30,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,30,31,30,30,30,30,29,30,30,29,30,30,30,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,31,30,31,30,30,30,31,31,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,31,29,30,29,29,30,30,29,30,29,30,29,29,29,30,29,29,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,29,29,30,28,28,30,28,27,29,29,27,28,29,28,28,26,27,28,29,27,29,29,28,29,30,29,30,30,30,30,29,30,29,30,28,29,29,28,28,28,28,28,27,27,27,26,23,24,27,27,23,25,26,25,27,28,25,26,28,28,27,28,29,30,30,28,28,28,28,27,26,28,26,23,27,24,26,27,27,27,28,28,29,28,29,30,30,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,30,29,30,30,30,30,30,30,29,29,30,29,29,30,30,29,30,29,29,30,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,28,28,29,29,28,28,29,28,28,29,29,28,28,29,29,29,28,29,29,30,30,30,30,30,29,30,30,30,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,30,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,31,30,31,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,28,29,30,29,29,29,29,28,29,28,27,28,29,27,26,28,26,28,27,24,27,28,25,24,26,25,21,24,24,22,22,21,21,21,18,19,17,16,14,12,10,8,6,6,5,3,2,0,1,2,5,6,7,9,11,12,15,16,17,18,19,20,20,20,20,21,22,22,22,22,22,22,22,24,23,24,23,24,24,25,25,26,26,26,27,26,27,29,26,27,28,27,28,28,27,29,26,28,28,29,29,30,28,29,28,30,30,29,27,28,29,28,28,28,28,25,25,28,25,23,25,27,26,28,27,29,29,29,29,28,29,29,28,29,28,27,27,28,26,26,28,28,28,28,29,29,28,30,29,29,29,29,30,30,30,30,29,31,31,30,30,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,30,31,31,30,31,30,30,30,30,31,30,30,31,30,30,30,30,30,29,30,30,29,29,30,30,30,30,30,30,30,30,31,30,29,31,31,30,30,31,30,29,30,30,29,30,29,29,30,30,29,30,30,29,29,30,29,29,29,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,31,30,30,30,30,29,30,29,30,29,30,30,29,29,30,29,29,29,29,30,28,28,30,28,28,29,29,28,28,29,29,28,27,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,29,29,29,29,29,29,28,28,28,28,27,26,28,27,26,21,25,26,27,23,27,27,26,28,28,26,27,29,28,28,28,30,30,30,27,29,28,28,27,25,27,26,22,26,24,26,27,27,27,29,29,29,28,29,30,29,29,30,30,30,29,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30],[30,30,30,30,30,31,31,30,30,30,30,30,30,29,30,29,30,29,29,29,29,29,30,29,28,29,28,28,29,29,28,29,29,29,29,29,28,28,29,28,28,29,29,29,28,28,28,28,28,28,28,27,28,28,27,28,28,28,28,28,28,27,28,28,29,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,31,31,30,31,31,30,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,30,31,30,31,31,31,30,30,30,30,30,30,30,30,30,31,31,31,31,30,31,31,31,30,30,31,30,30,30,31,31,30,30,30,30,30,30,31,31,30,30,31,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,31,30,30,31,31,31,30,31,31,31,31,31,30,31,31,31,30,30,31,30,31,30,29,30,30,29,29,30,31,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,28,29,29,29,29,29,29,28,29,29,27,28,28,26,26,26,26,27,26,24,26,26,25,25,25,24,23,23,24,23,20,22,22,20,18,19,17,16,14,12,10,9,7,6,5,4,2,1,0,1,3,5,7,8,10,12,14,15,18,19,20,20,21,22,22,21,22,22,22,22,22,22,21,22,23,23,25,23,24,25,25,26,26,25,27,26,26,29,27,27,28,28,28,28,27,28,27,29,28,30,30,29,28,29,28,29,29,28,27,28,28,27,27,27,27,26,27,28,26,25,26,28,27,28,27,29,28,29,29,28,29,29,28,29,28,27,28,28,28,27,28,28,28,28,29,29,29,29,29,30,29,29,30,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,30,30,30,31,31,30,31,31,30,31,30,30,31,30,30,31,30,30,30,31,30,30,30,30,29,30,30,30,29,29,29,30,30,29,31,30,31,30,30,30,31,31,30,31,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,29,29,30,30,29,29,30,30,29,29,30,29,29,29,29,30,30,29,29,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,31,31,30,31,30,30,31,31,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,29,29,30,29,28,29,29,29,28,28,30,29,28,29,28,27,29,29,27,27,28,27,28,26,27,28,29,29,29,29,29,29,29,29,29,29,29,30,28,29,29,29,28,29,29,28,28,28,28,27,27,27,26,24,22,25,27,26,23,25,27,26,27,28,26,27,29,28,27,28,29,29,29,28,29,28,28,27,25,27,26,22,26,25,26,26,25,27,28,27,28,27,29,29,28,29,29,30,29,29,30,30,30,30,30,31,30,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,30],[30,30,30,31,31,31,31,30,31,31,30,30,30,29,30,29,30,29,30,30,29,29,30,29,29,30,29,29,30,29,28,30,29,29,29,29,29,29,29,28,29,29,29,28,29,28,28,28,28,28,28,27,28,28,28,28,28,29,28,29,28,27,28,29,29,30,30,30,30,30,30,29,31,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,31,31,31,31,31,31,31,30,30,31,31,30,31,30,31,31,31,30,31,31,31,30,31,30,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,30,30,30,31,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,31,31,30,30,30,30,30,30,29,29,30,29,29,30,29,28,30,30,28,29,28,28,28,28,26,26,27,27,28,26,23,28,27,24,25,26,25,22,24,24,22,21,22,21,20,19,19,17,16,15,12,13,11,8,6,5,5,4,3,1,0,1,3,5,5,6,9,11,13,15,16,17,17,19,19,19,20,21,20,22,22,21,22,22,22,23,23,24,22,23,25,24,26,25,24,27,26,27,29,27,27,29,29,28,29,28,29,27,29,28,30,30,30,28,29,28,30,30,30,27,29,29,28,27,29,29,26,26,28,28,23,26,28,27,27,28,29,29,30,29,29,29,28,29,29,28,28,27,28,26,27,29,28,27,28,30,29,28,30,30,30,30,29,30,29,30,29,30,31,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,31,31,30,30,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,30,29,30,30,29,29,29,30,29,29,29,30,29,29,30,30,30,30,30,29,29,30,30,29,29,30,30,29,30,31,29,30,29,29,30,30,29,30,30,29,29,30,30,30,30,30,30,30,30,31,30,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,31,30,30,30,31,30,30,30,30,30,29,29,29,30,29,29,30,30,28,29,30,29,29,29,29,29,30,30,29,28,30,30,28,30,30,29,29,28,28,29,29,29,29,30,29,29,30,29,29,29,29,30,29,29,29,30,29,29,30,29,29,29,29,29,28,29,28,27,23,26,28,27,24,27,26,23,28,29,26,26,29,29,28,28,29,30,30,28,29,28,27,28,27,28,28,24,28,26,29,27,28,29,29,29,29,29,29,30,30,29,30,30,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30],[31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,30,30,29,30,29,29,30,29,30,29,30,29,29,29,29,29,29,29,29,29,30,29,29,28,29,29,28,28,28,28,29,29,29,28,29,29,29,28,29,29,30,30,30,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,28,29,29,28,29,30,28,27,28,29,29,28,26,28,29,27,27,28,26,23,25,26,24,24,24,24,23,21,22,20,19,20,16,15,14,12,10,9,9,8,5,3,2,0,1,3,4,6,7,9,12,14,16,17,18,19,19,20,19,20,21,21,21,22,22,22,24,24,23,24,24,24,25,26,26,26,26,27,26,27,29,27,27,28,28,29,28,28,29,28,28,29,30,30,30,29,30,29,29,30,29,28,29,29,28,28,28,28,24,26,28,26,23,25,27,25,27,28,28,29,30,29,28,29,29,28,28,27,27,25,27,26,27,28,28,26,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,31,30,30,31,30,30,30,31,30,30,30,30,31,30,29,31,30,30,29,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,31,30,30,30,30,30,30,30,30,29,29,30,30,28,30,30,29,29,30,30,29,29,30,29,28,30,30,29,29,30,29,29,29,29,29,30,29,30,30,29,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,29,30,28,29,28,29,28,27,24,27,29,29,26,28,28,27,28,29,28,28,30,29,28,29,30,30,30,28,30,29,28,29,27,29,28,24,27,26,27,27,27,28,28,30,30,28,29,30,29,29,31,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,29,30,29,30,30,29,30,30,29,29,30,29,29,30,29,29,30,29,30,30,30,29,30,30,29,30,30,29,29,29,29,28,28,28,28,28,27,28,28,28,28,28,28,28,28,29,28,28,29,29,30,30,30,30,30,30,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,31,31,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,31,30,31,30,30,30,30,30,29,29,30,30,29,30,30,29,29,28,28,29,29,28,27,27,28,28,27,25,28,27,26,27,27,25,23,25,25,23,23,24,22,22,20,22,19,19,19,17,16,15,14,13,10,8,10,5,5,3,2,0,1,3,5,6,6,8,11,13,15,16,16,17,18,18,19,20,21,22,22,21,22,23,23,22,23,24,23,24,25,26,26,25,27,26,27,29,26,26,28,28,28,28,28,29,27,29,29,30,30,30,29,29,29,29,30,29,29,30,29,27,28,29,28,26,28,29,27,25,26,29,27,28,28,30,29,30,30,30,30,30,29,30,29,29,28,29,28,28,29,29,28,30,30,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,29,30,31,30,30,31,30,30,30,31,30,30,31,31,30,30,31,31,30,30,31,30,30,30,30,31,30,30,30,31,30,30,31,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,31,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,30,29,30,30,29,29,30,29,30,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,29,29,28,29,29,27,24,26,29,27,24,28,28,27,28,29,27,28,29,29,29,29,29,30,30,29,30,29,29,29,27,29,28,25,28,27,29,28,28,28,29,29,29,29,29,30,29,29,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,30],[31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,29,30,30,30,30,30,29,30,30,30,29,29,29,29,29,28,29,29,29,29,29,29,28,30,30,29,29,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,31,30,31,31,31,30,31,31,31,31,30,30,30,31,29,30,30,30,30,30,30,30,30,30,29,29,30,29,28,28,28,29,28,26,28,29,27,27,28,26,23,26,26,25,24,25,24,22,21,23,21,21,20,18,19,17,16,14,13,11,11,7,5,5,3,2,0,1,3,5,6,7,9,11,14,15,17,18,19,19,20,20,21,22,22,22,22,23,23,24,24,24,24,25,26,27,27,27,27,27,27,29,28,27,29,29,29,28,28,29,28,29,29,30,30,30,29,30,29,30,31,30,28,30,29,28,28,29,29,25,27,29,27,25,26,29,27,29,28,29,29,30,30,30,29,30,29,30,29,29,28,30,28,28,30,29,28,30,30,30,29,30,30,30,30,30,30,30,30,29,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,31,30,30,30,31,30,30,31,30,30,30,31,30,30,30,31,30,30,31,31,30,30,31,30,30,31,30,31,31,30,31,31,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,31,30,29,30,30,30,29,29,30,29,30,30,29,29,30,30,29,30,30,30,30,29,29,30,30,29,30,30,30,30,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,27,25,28,30,29,25,29,29,27,29,30,27,29,30,30,29,30,30,30,30,29,30,29,29,29,27,30,29,26,28,27,28,28,27,29,29,29,29,28,29,30,29,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,30,29,30,30,29,29,29,29,29,28,29,29,29,27,28,29,28,29,29,29,28,29,29,29,29,29,30,30,30,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,30,31,30,30,30,31,30,30,31,30,31,31,31,31,31,31,30,30,30,30,30,30,29,30,30,30,29,30,29,29,29,29,28,29,30,29,28,28,28,29,28,27,28,29,26,27,28,26,23,25,26,24,24,25,23,23,22,24,22,21,22,19,19,19,17,16,14,12,10,8,6,6,4,4,2,0,1,3,5,6,6,8,11,13,15,16,17,17,18,19,20,20,21,21,21,22,22,22,23,23,23,24,25,26,25,26,27,26,27,29,26,26,29,28,28,28,28,29,28,29,29,30,30,30,29,30,29,30,30,30,28,30,30,28,28,29,29,26,27,29,28,25,26,29,27,29,29,30,30,30,30,29,29,30,29,30,29,29,27,29,28,28,29,29,28,30,30,30,29,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,31,30,30,30,31,30,30,31,31,30,31,31,30,30,31,31,30,30,31,31,30,31,31,30,31,31,30,31,31,30,31,31,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,29,30,30,30,30,29,30,29,30,30,30,29,30,30,29,30,31,30,30,29,29,31,30,30,30,30,30,30,31,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,28,25,28,30,29,26,29,29,28,30,30,28,29,30,30,29,30,30,30,30,29,30,29,29,29,28,30,29,26,28,27,28,29,28,29,30,30,30,29,30,30,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,29,29,30,29,30,30,29,29,30,30,29,29,29,28,29,28,29,28,29,29,29,28,29,29,30,29,29,30,30,31,30,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,31,30,30,30,29,29,29,30,29,29,28,29,29,28,27,29,29,27,27,29,27,24,26,27,25,25,26,24,23,23,23,22,23,22,20,21,20,19,19,17,15,12,9,8,6,5,6,5,2,0,1,4,5,6,6,8,12,13,15,16,16,17,18,20,21,21,21,22,23,22,22,23,24,23,24,26,26,26,26,27,27,27,29,28,28,29,28,29,28,29,30,29,30,30,30,30,31,30,30,30,30,31,30,29,30,30,29,28,30,30,25,28,30,28,25,27,29,27,30,29,30,30,30,30,30,30,30,30,31,30,30,28,30,28,29,30,30,28,30,30,30,30,31,31,31,31,30,31,30,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,30,30,31,31,30,30,31,31,30,31,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,29,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,30,30,30,30,30,31,30,30,30,30,30,30,30,29,29,30,30,28,26,28,30,29,25,29,29,28,30,30,29,29,30,30,30,30,30,31,31,30,30,30,29,30,29,30,29,26,29,28,29,29,28,29,30,30,30,29,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,31,30,30,30,30,30,31,30,30,30,30,29,30,30,29,30,30,30,30,30,29,30,29,29,30,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,30,29,29,29,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,31,31,29,30,30,30,30,30,30,30,30,29,29,29,30,29,28,29,29,30,28,26,29,29,27,27,29,27,23,26,27,24,24,25,24,23,22,24,22,23,21,19,21,20,19,20,17,16,13,11,10,9,6,6,6,6,2,0,1,3,4,5,6,7,11,12,13,15,16,17,18,19,20,21,21,22,21,22,22,23,22,23,25,25,26,26,26,26,26,29,27,27,29,28,29,29,29,30,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,29,30,30,26,28,30,28,26,27,29,28,30,29,30,30,30,30,30,30,30,30,30,30,30,27,30,27,29,30,30,29,30,30,30,30,31,30,31,31,30,31,30,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,30,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,31,31,30,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,30,31,31,30,30,30,30,30,30,31,30,29,31,30,29,30,31,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,30,31,30,30,30,31,30,30,30,30,30,30,30,29,29,30,30,29,27,28,30,29,25,29,30,27,30,30,28,28,31,30,29,30,31,31,31,29,30,30,30,29,29,30,29,26,29,27,29,29,29,29,30,30,30,29,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,31,30,30,30,30,30,31,30,30,30,30,29,30,30,29,30,30,30,30,29,29,29,29,29,29,29,29,28,29,29,28,28,28,29,29,27,28,28,28,29,28,29,28,29,29,28,29,29,30,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,31,30,30,30,30,30,29,29,29,30,29,28,28,29,29,28,26,29,28,26,27,28,25,22,26,26,23,24,25,23,23,22,24,22,22,21,19,21,20,19,20,17,17,14,12,13,11,7,7,6,7,4,2,0,1,4,4,5,5,7,11,12,13,15,16,17,18,19,20,20,21,20,21,21,23,22,22,25,26,26,25,26,27,27,29,27,27,29,28,29,28,28,29,28,30,30,30,30,31,30,30,30,30,31,30,29,31,30,29,29,30,30,26,29,30,29,26,28,30,29,30,29,30,30,30,31,30,30,30,30,31,30,30,27,29,28,29,30,30,29,30,30,30,30,30,30,31,31,31,31,30,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,30,30,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,31,31,31,31,30,31,31,30,31,31,30,31,31,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,30,30,31,30,30,30,30,30,30,31,30,29,30,30,29,30,31,30,30,29,30,30,30,30,31,31,30,30,31,30,31,31,30,31,30,30,30,31,30,30,31,30,30,30,30,29,29,30,30,28,25,28,30,29,24,29,29,27,30,30,29,28,30,30,30,30,31,31,31,30,30,30,30,30,29,30,29,26,29,27,29,29,28,29,30,30,30,29,30,30,30,30,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,29,29,29,29,29,29,29,29,29,28,28,28,29,28,28,29,28,29,28,29,28,29,29,28,29,29,30,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,31,30,31,30,30,30,30,29,30,30,29,28,28,29,29,28,26,29,29,27,27,28,26,23,26,26,24,24,25,24,23,22,23,22,22,22,20,22,21,20,21,18,18,15,15,15,14,9,8,6,7,6,5,2,0,1,4,4,5,5,8,10,11,13,14,16,17,18,19,20,21,21,21,22,23,22,22,25,26,25,25,26,27,27,29,27,27,29,28,29,28,28,29,28,30,30,31,30,31,30,31,30,30,31,30,29,30,30,29,29,30,30,27,29,30,29,27,28,30,28,30,29,30,30,30,30,30,30,30,30,31,30,30,28,29,28,30,30,30,29,31,31,30,30,31,31,31,31,31,31,30,31,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,31,30,30,30,31,30,30,31,30,30,31,31,30,30,31,30,30,29,30,31,31,30,31,31,30,30,31,31,31,31,31,31,30,31,30,31,30,31,31,30,30,30,30,30,30,30,30,28,26,28,30,29,24,29,29,28,30,30,29,29,31,30,30,30,31,31,31,30,31,30,30,30,29,30,29,28,29,28,29,28,28,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,29,29,29,29,28,29,29,29,28,29,28,28,29,29,28,28,27,28,29,27,27,28,28,28,28,28,27,28,29,28,29,29,30,30,30,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,30,31,31,30,30,30,31,30,30,30,30,30,29,28,29,30,28,28,28,28,29,28,26,29,28,26,27,28,25,21,26,26,23,24,25,23,23,22,24,22,22,22,20,22,21,20,21,19,19,15,16,17,15,11,11,7,6,6,6,4,2,0,1,3,4,5,5,7,10,12,13,15,16,17,18,18,20,20,20,21,22,21,21,24,25,25,24,25,26,26,28,26,26,28,27,28,27,28,29,27,29,30,30,30,31,30,30,30,30,31,30,30,30,30,29,29,30,30,27,28,30,29,26,28,30,28,30,29,30,30,30,30,30,30,30,30,31,30,30,28,29,28,30,30,30,29,31,31,30,30,30,30,31,30,31,31,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,29,30,31,30,30,30,31,30,30,30,30,30,31,31,29,30,31,30,30,29,30,31,30,30,31,31,30,30,31,30,30,31,30,30,30,30,30,31,30,30,31,30,30,30,30,29,30,30,29,29,25,27,30,29,24,29,29,27,30,30,29,28,30,30,30,30,31,31,31,30,30,30,30,30,29,30,29,27,29,27,29,29,28,30,30,30,30,29,30,30,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,29,30,29,29,28,29,29,29,28,29,28,28,29,29,28,28,27,28,28,27,27,27,27,28,28,28,27,28,29,28,28,29,30,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,31,30,30,30,30,30,30,28,29,30,29,27,28,28,29,28,25,29,28,26,27,28,25,22,26,26,23,24,25,23,23,22,23,22,22,22,20,22,21,20,21,19,19,16,17,19,17,13,13,9,7,5,6,6,4,2,0,1,3,4,5,5,7,10,11,13,15,16,17,18,20,19,19,20,22,21,21,23,24,24,24,25,26,26,28,26,26,28,27,28,27,28,29,27,29,30,30,30,31,30,31,30,30,31,30,30,30,30,30,29,30,30,27,29,30,30,27,28,30,28,30,29,30,30,30,31,30,30,30,30,31,30,30,28,29,27,30,30,29,29,31,30,30,30,31,30,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,30,31,31,30,31,31,30,31,31,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,31,31,30,30,31,30,30,30,31,30,30,30,30,30,31,31,30,30,31,30,30,30,30,31,31,30,30,31,30,30,31,30,31,31,31,31,30,31,30,31,30,31,31,30,30,30,30,29,30,30,29,29,26,28,30,29,24,29,29,27,30,30,29,28,30,30,30,30,31,31,31,30,30,30,30,30,29,30,29,26,29,27,29,28,28,30,30,30,29,30,30,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,29,30,29,29,29,29,29,29,29,29,28,28,29,29,28,28,27,28,28,27,27,27,28,28,28,28,27,28,29,28,28,29,30,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,30,29,28,29,30,28,27,28,28,29,28,25,29,28,26,26,28,25,21,26,26,22,24,24,22,23,22,23,22,21,22,20,22,22,20,21,20,20,16,18,20,18,14,15,12,10,7,6,6,6,5,2,0,1,3,4,5,5,7,10,12,14,15,16,17,19,19,19,20,22,21,21,23,23,23,23,24,25,26,28,26,26,28,26,28,27,28,28,27,29,29,30,30,31,30,30,30,30,31,30,30,31,30,29,29,30,30,27,29,30,30,27,28,30,29,30,29,30,30,30,31,30,30,30,30,31,30,30,27,29,27,29,30,29,29,30,30,30,30,30,30,31,31,31,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,31,30,30,30,31,30,30,30,30,30,31,31,30,30,31,30,30,29,30,31,30,30,31,31,30,30,31,30,31,31,31,31,30,31,30,31,30,31,31,30,30,30,30,29,30,30,30,28,26,27,30,29,23,29,29,27,29,30,29,28,30,30,30,30,31,31,31,30,30,30,30,30,29,30,29,27,29,27,29,29,29,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,30,30,30,30,30,30,29,30,30,29,30,30,28,30,29,30,30,29,28,29,29,29,29,29,29,28,29,29,29,28,27,28,28,27,27,28,28,28,28,28,28,28,29,28,28,28,29,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,30,30,29,28,29,29,29,26,28,28,29,28,26,29,28,26,27,28,25,22,27,26,23,24,25,23,24,22,24,21,21,23,20,22,21,21,22,20,20,17,18,20,20,15,15,13,11,9,7,5,6,6,5,2,0,1,3,4,5,5,7,10,12,13,15,15,18,18,18,20,21,20,21,22,23,23,23,24,25,25,28,26,26,28,27,28,28,29,29,27,29,30,30,30,30,30,31,30,30,31,30,30,30,31,29,29,30,30,28,29,30,30,27,28,30,30,30,30,31,31,31,31,30,30,31,30,31,30,30,28,30,28,30,30,29,29,30,30,30,30,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,30,31,31,31,31,30,31,30,30,31,30,30,31,31,30,30,31,30,30,29,30,31,31,30,31,31,30,30,31,30,31,31,31,31,30,31,30,31,30,31,31,30,30,30,30,30,30,31,30,29,27,28,30,29,24,29,29,27,29,30,29,28,30,30,30,30,31,31,31,30,30,30,30,30,30,30,29,27,29,28,30,29,29,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,31,30,30,31,30,30,31,30,30,30,30,29,30,30,29,30,30,30,29,29,29,29,29,28,29,29,28,28,29,29,28,28,27,28,28,26,27,28,28,28,28,29,27,28,29,29,29,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,29,28,29,29,28,26,28,28,29,27,25,28,28,25,26,28,24,21,26,26,22,24,24,22,24,21,24,21,21,23,21,22,22,21,22,21,22,17,19,21,21,17,16,15,14,12,10,7,5,6,6,5,2,0,1,3,4,5,6,7,11,13,14,15,17,17,18,19,21,20,21,22,23,23,23,24,25,26,27,25,26,28,26,27,27,28,28,27,29,29,30,30,30,30,31,30,30,31,30,29,31,30,30,29,30,30,28,29,31,30,27,28,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,28,30,27,29,30,29,29,30,30,30,30,31,30,31,31,31,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,31,30,30,31,31,30,30,30,31,30,30,31,30,30,31,31,30,31,31,30,30,30,30,31,30,30,30,31,30,30,31,30,31,31,31,31,30,31,30,31,30,30,31,30,30,30,30,30,30,31,30,29,27,28,30,29,24,29,29,26,29,30,29,28,30,30,30,30,31,31,31,30,31,30,30,30,30,30,29,27,29,28,30,29,29,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,30,31,30,30,31,30,30,30,30,29,30,30,29,30,30,30,29,29,29,29,29,29,29,29,28,28,29,28,28,28,27,28,28,27,27,27,28,28,28,28,27,28,29,29,29,28,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,29,30,29,28,28,29,28,26,28,28,29,27,25,29,28,25,26,28,24,22,25,25,22,24,24,22,24,22,23,21,22,23,21,23,22,21,23,22,22,18,21,22,22,18,18,16,15,13,12,10,7,6,6,6,5,2,0,1,3,4,5,6,7,10,12,14,15,15,16,19,20,20,20,21,23,23,22,23,24,25,27,25,26,28,26,27,27,28,28,26,29,29,30,30,30,30,31,30,30,31,30,29,31,31,29,29,30,30,28,29,31,30,27,28,30,30,30,30,30,31,30,31,30,31,30,30,30,30,30,28,30,27,29,30,29,29,31,30,30,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,30,31,31,30,30,31,31,30,30,31,30,30,31,31,30,30,31,30,30,30,30,31,30,30,30,31,30,30,31,30,31,30,31,31,30,31,30,31,30,31,31,30,30,30,30,30,30,30,30,29,27,28,30,29,24,29,29,26,29,30,29,27,30,30,30,29,31,31,31,30,31,30,30,30,30,30,29,26,29,28,30,29,29,30,30,31,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,31,30,30,31,30,30,31,30,29,30,30,29,30,30,29,30,30,30,29,29,29,29,29,28,29,29,29,28,29,28,28,28,27,28,28,26,27,27,28,27,27,28,27,27,29,28,28,28,29,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,29,28,28,29,28,25,27,27,28,27,24,28,27,23,25,27,23,21,25,24,21,23,23,22,23,21,23,21,21,22,20,21,21,20,22,21,21,18,21,22,22,18,18,17,16,14,13,12,10,7,6,6,5,5,2,0,1,3,4,5,6,7,10,12,13,14,16,17,19,19,20,21,22,22,21,22,23,24,26,24,25,28,25,27,27,27,28,26,29,29,30,30,30,30,31,30,30,31,30,29,31,30,29,29,30,30,28,29,31,30,27,28,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,28,29,27,29,30,28,29,30,30,29,30,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,31,30,30,31,31,30,30,30,31,30,30,30,30,30,31,30,30,30,31,30,30,29,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,29,27,28,30,29,25,29,29,25,29,30,28,26,30,30,29,29,31,30,31,30,31,30,30,30,30,30,29,27,29,28,30,29,29,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,29,30,30,29,30,30,30,30,30,29,30,29,29,29,30,29,29,30,29,29,29,28,29,29,28,28,29,29,28,28,28,27,28,29,28,28,28,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,29,30,29,28,28,29,28,25,28,28,29,27,26,28,27,25,26,28,24,22,26,25,23,23,23,21,23,22,22,21,21,22,20,22,23,22,23,22,23,19,22,24,25,20,20,19,17,16,15,14,12,10,8,6,6,6,5,2,0,1,3,5,6,7,8,11,13,14,15,17,18,19,19,21,21,21,21,22,23,23,25,25,25,27,25,27,27,27,28,27,30,29,30,30,30,30,31,30,30,31,31,30,30,30,29,28,30,30,28,28,30,30,28,29,30,30,30,30,31,31,31,31,30,30,30,30,30,30,30,28,30,27,30,30,29,29,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,29,30,31,30,29,31,30,30,31,31,30,31,30,31,31,30,31,30,31,30,31,31,30,30,31,30,30,30,30,30,29,28,29,31,29,26,29,29,27,29,30,28,27,30,30,29,29,31,31,31,29,31,30,30,30,30,30,29,27,29,29,30,30,30,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,31,30,29,30,30,29,30,30,29,30,29,28,29,29,29,30,29,29,29,29,28,29,29,28,28,29,28,28,28,28,28,28,28,27,28,27,27,27,27,28,27,27,27,26,28,27,27,28,29,29,29,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,29,28,28,28,28,28,25,28,28,28,26,25,28,27,24,25,27,23,22,25,24,22,23,22,21,22,20,23,20,21,22,21,22,21,20,23,22,22,19,22,24,25,20,19,19,17,17,16,14,13,13,11,7,6,6,7,5,2,0,1,3,5,5,6,8,10,12,13,15,16,17,19,19,20,21,20,21,22,22,24,24,24,26,24,27,27,27,29,25,29,30,30,30,30,29,30,30,30,31,30,29,30,30,30,28,30,30,29,29,30,30,27,28,30,30,30,30,30,31,31,31,30,30,30,30,30,30,30,29,29,26,29,30,28,29,30,31,29,30,31,30,30,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,30,31,31,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,30,31,31,31,31,30,30,31,31,30,30,30,31,30,30,31,30,30,31,31,30,30,30,31,30,30,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,28,30,29,26,29,29,26,28,29,29,27,30,30,29,28,30,30,31,30,30,30,30,30,30,30,29,28,29,29,30,29,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,29,29,29,30,29,29,29,28,29,28,28,28,29,28,28,28,29,29,29,29,28,28,28,28,27,28,29,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,30,30,30,30,30,29,30,29,28,27,29,28,25,29,28,29,28,26,29,28,25,26,27,25,23,26,26,23,24,23,21,22,21,21,22,21,22,20,22,23,21,22,22,23,21,24,25,25,22,22,21,20,19,18,17,16,15,13,11,8,6,7,6,5,2,0,1,3,4,6,7,8,11,13,15,14,17,17,19,20,20,19,22,22,23,24,24,25,26,26,26,26,26,28,26,28,28,30,30,30,30,31,30,31,31,31,30,30,30,30,28,30,30,29,28,30,30,28,29,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,29,29,28,29,30,29,29,30,30,29,30,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,30,31,31,30,30,30,31,30,31,31,31,30,31,31,30,31,30,31,30,30,31,30,30,31,30,30,31,31,31,30,29,30,31,30,30,31,30,30,30,31,30,30,30,31,30,30,30,31,30,29,31,30,30,30,30,30,29,30,30,30,30,29,30,30,29,27,30,29,27,28,29,28,28,29,30,28,29,30,31,31,30,31,30,30,30,30,30,28,27,30,29,30,30,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,30,31,30,30,31,30,29,30,30,29,30,30,29,30,30,30,30,29,29,29,29,29,29,29,29,28,29,28,28,28,27,27,28,26,26,27,27,27,26,28,25,26,27,26,27,26,28,29,29,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,30,30,30,30,29,29,29,29,27,27,28,27,25,26,27,28,26,24,28,25,23,25,26,23,21,24,24,22,23,23,21,22,20,22,20,21,21,20,21,20,20,21,21,21,19,23,23,24,20,22,20,20,18,18,17,15,14,13,12,10,7,6,6,5,5,2,0,1,3,4,6,6,7,10,13,13,14,16,17,19,20,18,19,21,22,23,23,22,25,23,25,24,25,27,24,29,29,30,30,30,29,30,30,30,31,30,29,30,30,29,29,30,30,28,29,31,29,27,29,30,30,30,29,31,30,30,31,30,30,30,30,30,30,30,29,29,28,29,30,28,29,30,30,29,30,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,31,31,30,31,31,31,31,31,30,31,30,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,30,31,30,31,30,30,30,30,30,30,30,30,29,29,28,27,30,29,25,28,29,26,28,29,29,27,30,30,29,28,30,30,31,29,30,30,30,30,29,30,28,27,29,28,30,28,29,30,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,30,30,31,30,30,30,30,29,30,30,29,30,30,30,29,30,29,29,29,29,29,29,28,29,29,28,28,28,27,27,28,27,27,27,28,27,28,27,26,26,27,27,27,26,29,29,29,30,30,30,30,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,30,30,30,29,29,29,28,27,28,28,25,27,28,27,25,26,27,26,25,26,26,24,23,25,24,22,23,23,21,22,21,21,21,22,22,20,23,23,21,23,23,23,21,24,24,25,22,22,22,21,20,20,18,17,16,15,14,13,11,8,6,6,5,3,2,0,1,3,4,5,6,8,11,12,13,15,16,17,18,18,19,21,21,23,22,23,24,23,26,25,26,27,25,29,29,29,30,30,29,30,30,31,31,31,30,30,31,30,29,30,30,29,29,31,30,28,29,30,30,30,30,31,31,31,31,30,30,31,30,30,30,30,29,29,27,29,30,28,29,31,30,29,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,30,31,30,31,30,30,31,31,31,31,30,31,31,30,30,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,29,30,29,27,29,29,28,28,29,29,27,29,30,29,28,30,30,31,29,31,30,30,30,30,30,29,29,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,29,29,29,29,29,29,29,28,29,28,28,28,28,27,27,28,27,27,27,27,26,26,28,27,27,26,28,29,29,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,29,30,31,30,30,30,30,30,30,30,28,29,28,27,26,27,26,25,27,27,28,24,25,28,25,25,24,25,24,22,25,24,23,22,22,22,22,21,19,22,21,22,19,22,24,21,22,22,23,21,25,24,25,23,23,22,22,20,21,19,18,18,17,16,15,14,12,8,6,6,6,5,2,0,1,3,5,5,6,8,10,13,14,14,17,16,16,18,20,20,22,23,22,24,23,24,24,24,27,25,28,28,29,30,30,29,30,30,30,31,30,29,30,30,29,29,30,30,27,29,30,29,28,29,30,30,30,30,30,30,31,31,30,30,30,30,30,29,30,28,29,27,29,29,28,28,30,30,29,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,30,31,30,31,30,30,31,31,31,30,30,31,31,30,31,30,31,30,31,31,31,30,31,31,31,31,31,31,30,30,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,31,30,29,30,30,30,30,30,30,30,29,30,30,30,30,31,30,30,30,30,30,30,30,30,29,29,29,29,30,29,27,28,28,27,28,29,29,27,29,30,29,28,30,30,30,29,30,30,30,29,29,30,29,28,29,29,30,29,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,30,31,30,30,30,30,29,30,30,29,30,30,28,30,29,30,29,29,29,28,29,28,28,28,28,28,28,27,28,28,26,27,27,26,25,27,27,26,26,26,25,24,26,26,25,25,28,28,28,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,29,28,27,25,27,27,23,26,26,25,24,23,25,24,22,24,24,22,21,23,22,20,21,20,20,21,19,21,19,21,20,19,20,20,19,22,22,22,21,24,24,25,22,22,23,22,21,22,21,20,19,17,16,16,14,13,10,7,6,6,5,4,2,0,1,3,5,6,7,8,11,13,13,15,17,16,19,19,20,22,22,22,23,21,25,24,24,27,24,28,28,29,30,30,29,30,30,30,31,31,30,30,31,30,29,30,30,29,29,30,30,29,29,30,30,30,30,31,31,31,31,30,30,30,30,30,30,30,29,29,28,30,30,29,29,31,30,29,30,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,30,30,30,31,29,31,30,30,31,30,31,30,30,31,31,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,30,31,30,30,31,31,30,30,31,30,30,30,29,30,30,29,30,30,30,29,30,29,30,30,30,30,29,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,29,28,30,29,27,28,28,27,28,29,29,26,29,30,29,28,30,30,31,30,30,30,30,30,30,30,29,28,29,29,30,29,30,30,31,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,31,30,30,30,30,29,29,29,29,29,30,29,29,29,29,29,29,27,28,29,28,27,28,28,28,27,28,26,26,27,27,27,26,28,29,29,29,30,30,30,30,31,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,30,30,30,30,30,30,28,28,28,27,25,27,27,25,26,27,28,26,25,27,26,25,25,27,23,22,25,23,21,24,22,21,22,21,20,22,20,22,20,21,22,21,22,22,23,23,25,25,26,25,24,24,24,23,22,22,21,20,19,19,17,16,15,13,9,8,7,6,4,4,2,0,1,3,4,6,6,8,11,13,14,14,17,17,19,19,22,21,21,23,22,25,24,24,27,25,28,27,29,30,29,29,30,30,30,31,31,30,30,30,30,29,29,30,29,28,30,30,29,29,30,30,30,30,30,31,31,30,30,30,30,30,30,30,29,29,28,28,29,29,29,29,30,30,28,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,30,31,30,30,29,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,30,30,30,31,31,30,29,30,31,30,29,30,30,30,30,31,31,29,31,31,30,30,31,31,30,30,31,30,30,31,30,30,31,31,31,30,30,30,30,30,29,30,30,29,29,30,29,30,29,30,30,29,29,30,30,29,30,30,29,30,30,30,29,30,30,30,29,30,29,30,29,27,29,28,26,27,28,28,27,28,29,28,28,29,30,30,29,30,30,30,29,29,30,28,28,30,29,30,30,30,30,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,29,29,29,30,29,29,29,28,29,28,27,27,28,26,26,28,27,27,26,27,27,26,27,27,26,25,28,29,29,30,29,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,29,30,30,30,30,30,29,29,28,28,28,25,28,27,25,28,28,28,26,26,27,25,24,25,26,23,23,25,24,23,23,23,22,22,21,22,22,21,22,20,22,23,21,23,23,23,23,25,25,26,24,25,24,24,22,23,22,21,21,20,19,18,18,16,15,13,11,8,7,6,5,4,1,0,1,3,5,5,7,8,12,13,15,14,17,18,18,21,21,21,22,21,23,24,23,26,24,28,28,29,30,29,29,30,30,30,30,30,29,30,30,29,28,30,30,29,29,30,30,29,29,30,30,30,30,31,31,31,30,30,30,30,30,30,30,30,29,29,28,29,30,28,29,30,30,29,30,30,30,30,30,30,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,29,30,31,31,31,30,30,30,31,30,30,30,31,30,30,31,31,30,31,31,30,30,30,30,30,30,31,30,31,31,31,30,30,31,30,30,30,30,30,30,29,30,30,29,29,30,29,30,29,30,30,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,29,29,28,30,29,27,27,28,28,27,28,28,26,28,29,28,28,30,30,30,30,29,29,29,29,29,30,29,28,29,30,30,30,30,30,31,30,31,30,30,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,30,31,30,30,31,30,29,30,30,29,30,30,29,30,30,30,29,29,29,29,29,28,29,29,29,28,28,28,28,28,27,27,28,27,26,27,27,27,26,27,25,26,26,26,25,25,27,28,28,29,29,30,30,30,30,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,30,30,30,30,30,30,28,28,28,27,25,28,27,25,26,27,27,25,24,26,25,24,24,24,23,22,24,22,21,23,22,20,21,20,20,21,21,21,19,22,23,20,23,23,24,22,25,25,26,25,24,24,24,22,23,21,21,21,20,20,18,17,16,16,13,12,11,8,7,6,5,4,2,0,1,4,5,5,6,9,10,12,13,14,16,17,19,19,20,23,20,24,24,23,27,23,28,28,29,30,29,29,30,30,30,31,31,30,30,31,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,31,31,31,30,30,30,30,30,30,30,29,29,29,30,29,29,29,30,30,29,30,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,29,30,30,30,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,30,30,30,30,29,30,29,30,30,30,31,30,30,30,31,30,30,30,30,30,30,31,30,29,31,31,31,30,31,31,31,30,31,30,31,31,30,30,30,31,30,30,30,30,30,30,29,30,30,29,29,30,28,29,29,30,30,29,30,30,30,29,31,30,30,30,30,30,29,30,30,30,29,29,29,30,29,28,29,28,27,28,29,29,26,28,29,29,27,29,30,30,29,30,29,30,30,30,30,29,29,30,30,30,30,30,30,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,29,29,29,29,29,29,30,29,29,29,28,29,28,27,28,28,27,26,28,27,26,26,28,26,26,26,27,25,24,27,27,28,29,30,30,30,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,30,30,30,30,29,28,27,28,26,26,27,26,26,26,28,27,25,26,27,25,23,23,25,23,22,25,24,22,24,24,22,24,21,22,22,21,22,19,22,24,22,22,23,24,22,26,24,26,24,24,24,24,22,23,22,21,21,20,20,20,19,18,17,16,14,13,12,8,6,6,5,4,2,0,1,4,5,6,8,8,11,11,14,16,16,19,19,19,22,20,23,22,23,26,24,28,29,29,30,29,30,30,30,30,31,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,29,30,31,31,31,30,30,30,29,30,30,30,28,29,28,29,29,28,29,30,29,29,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,31,30,30,31,30,30,29,31,30,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,30,31,31,30,30,30,30,29,30,29,30,30,31,31,30,30,30,30,30,30,30,30,30,30,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,29,29,28,28,28,28,29,28,28,30,29,28,29,30,30,30,30,30,30,30,30,30,28,29,29,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,30,31,31,30,31,30,30,30,30,30,30,30,29,30,30,28,30,29,30,29,30,29,29,29,29,29,29,28,28,28,28,28,28,26,27,28,27,25,26,28,26,26,27,26,27,27,26,24,25,27,27,28,29,29,30,29,30,30,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,30,29,29,30,29,29,27,27,26,24,26,26,23,26,27,26,25,24,27,26,24,25,26,24,23,26,24,22,25,24,22,23,21,22,22,21,22,20,22,23,22,22,23,24,23,25,24,26,24,24,24,24,23,23,22,22,23,22,21,20,20,18,18,17,16,15,14,12,9,7,7,5,4,2,0,1,3,5,7,7,8,10,12,15,15,18,18,19,22,19,22,22,22,26,24,28,29,29,30,29,29,30,30,30,31,30,29,30,30,30,29,30,30,29,29,30,30,29,29,30,30,30,30,31,31,30,31,30,30,30,29,30,30,30,29,28,28,29,29,28,29,30,29,29,30,30,30,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,29,30,30,30,30,30,31,31,30,31,30,30,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,31,30,30,31,30,29,30,30,29,30,28,30,30,30,31,30,29,30,30,30,30,30,30,30,30,31,30,30,31,31,31,30,31,31,31,30,31,30,31,31,31,30,31,31,30,30,30,30,30,30,29,30,30,29,29,30,28,29,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,27,28,28,28,27,28,28,25,28,30,29,27,29,30,30,29,30,30,30,30,30,30,29,29,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,30,31,30,30,31,30,30,30,30,29,30,30,29,30,30,30,29,29,29,29,29,29,29,29,29,29,29,28,29,29,27,27,28,27,26,27,27,27,25,27,26,26,26,27,25,25,27,27,27,28,29,30,30,30,30,31,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,29,30,30,29,30,29,28,27,28,26,25,28,26,25,26,27,26,25,26,27,25,24,25,26,24,24,26,24,23,24,24,22,24,23,23,24,22,23,22,23,25,23,23,24,25,23,27,26,27,25,25,24,24,24,24,22,22,22,22,22,22,22,20,19,18,17,17,16,14,11,7,8,6,5,4,2,0,1,3,5,6,8,9,11,13,14,16,17,18,22,18,22,22,22,25,23,28,28,28,30,30,29,30,30,30,31,30,30,30,31,30,30,30,30,29,29,31,30,30,30,30,30,30,30,30,31,31,31,30,30,30,29,30,30,30,29,29,28,30,29,28,29,30,30,30,30,31,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,31,30,31,31,30,31,31,31,31,31,31,30,31,31,31,31,30,30,31,30,29,30,30,29,30,27,29,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,29,31,30,30,30,31,31,31,31,31,30,31,31,30,31,30,31,31,30,30,30,30,30,29,30,29,29,29,30,28,29,28,30,30,28,30,30,30,29,30,30,29,30,30,30,30,30,31,30,30,30,29,30,29,29,29,29,29,28,28,29,27,27,29,29,27,29,30,30,30,30,30,31,30,30,30,29,30,30,30,30,30,31,30,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,29,30,29,29,29,29,28,29,28,27,28,28,26,27,28,27,25,26,27,27,25,28,27,27,27,26,25,24,27,27,27,29,29,30,29,30,30,30,30,30,30,30,30,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,31,31,30,31,31,31,30,31,31,30,31,30,30,30,29,30,30,29,29,29,29,29,29,28,28,25,27,25,25,27,26,26,27,28,28,25,26,28,25,24,25,25,24,24,27,25,23,24,24,23,24,23,23,24,22,24,21,23,26,24,24,24,26,24,26,25,27,25,25,25,25,24,24,24,23,24,23,23,22,22,21,20,18,18,17,17,15,14,12,8,7,7,5,5,2,0,1,4,5,7,7,8,13,12,14,16,17,20,17,21,21,21,25,23,27,29,28,29,29,29,30,30,30,31,30,29,30,30,29,29,30,30,28,29,30,30,29,29,30,30,30,30,30,30,31,31,30,30,30,29,30,30,30,28,27,28,29,29,28,29,30,29,28,30,30,29,29,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,29,29,30,30,30,29,30,30,31,30,31,30,30,31,30,31,31,30,31,31,31,30,31,31,30,31,31,31,31,30,30,31,30,30,30,30,29,30,28,30,30,30,31,29,29,30,30,30,30,30,30,30,30,31,30,29,31,31,31,30,30,31,30,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,29,30,30,29,29,30,28,28,29,30,29,28,30,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,29,30,29,29,29,27,28,28,28,29,27,28,30,29,27,29,30,30,29,30,29,30,30,29,30,29,29,30,30,30,30,30,30,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,30,30,30,30,29,30,30,29,29,29,29,29,30,28,29,29,30,29,29,29,29,29,28,29,28,28,28,28,28,28,27,26,26,27,26,24,26,26,25,25,26,25,26,26,25,24,24,26,26,26,28,28,29,29,29,30,30,30,30,30,30,30,29,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,30,30,31,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,30,30,29,30,28,28,29,29,28,28,28,28,25,26,26,24,26,26,25,25,25,25,25,23,25,25,24,24,24,23,23,25,23,22,24,23,21,23,22,23,23,22,24,21,22,24,23,23,23,24,24,26,26,26,25,25,25,25,24,23,23,23,23,23,23,21,22,21,21,19,19,18,17,16,15,13,11,8,7,7,6,4,2,0,1,3,5,6,7,9,10,12,13,14,19,16,19,21,21,25,24,28,28,28,29,29,29,30,30,30,31,30,30,30,30,30,29,30,30,29,29,30,30,30,29,30,30,30,30,30,31,31,31,30,30,30,29,30,29,30,29,29,28,30,29,28,29,30,29,29,30,30,30,29,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,31,31,30,30,31,30,30,31,30,30,30,30,30,30,30,31,30,30,31,31,31,30,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,30,30,31,30,30,30,30,29,29,29,29,30,30,30,30,30,30,30,30,29,30,31,30,31,31,30,31,31,30,30,31,30,30,30,30,31,31,30,29,30,29,29,29,29,28,29,28,29,30,29,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,31,30,31,31,30,30,31,31,30,30,30,30,29,29,29,29,29,29,29,29,28,29,29,30,29,29,30,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,29,29,30,28,27,27,27,27,29,29,26,28,29,28,27,29,30,30,29,30,30,30,30,30,30,29,28,30,30,30,30,31,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,31,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,29,28,26,28,27,27,26,28,27,26,26,26,24,23,27,26,26,28,28,30,30,29,30,29,30,29,29,30,30,29,29,30,30,29,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,31,30,30,30,30,30,30,29,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,30,30,30,30,30,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,31,30,30,31,30,31,30,29,30,30,30,30,30,31,30,30,31,30,30,30,31,30,30,30,31,30,30,30,30,30,29,29,29,29,28,28,27,26,24,25,25,23,26,26,25,27,27,28,25,25,27,26,24,26,26,24,24,27,25,23,26,25,23,25,23,24,24,23,25,23,23,25,24,24,24,24,24,27,26,27,25,25,25,25,24,24,24,24,24,23,23,23,23,22,21,20,21,19,19,18,17,15,14,11,9,8,7,6,5,3,0,1,3,4,6,8,8,11,13,14,17,18,19,21,21,24,23,27,25,27,29,29,29,30,30,30,30,30,29,29,30,30,29,29,30,28,29,29,30,30,30,29,30,30,30,29,31,31,30,30,30,29,29,29,29,29,30,28,29,29,28,28,29,30,29,29,30,30,29,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,30,31,30,30,30,30,30,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,30,31,31,30,30,31,30,29,30,30,30,29,30,30,29,29,30,30,28,30,30,30,30,31,31,30,30,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,31,30,31,30,31,31,30,30,31,30,29,30,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,31,30,31,31,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,28,29,30,29,30,29,28,29,30,29,28,29,30,29,29,30,30,29,30,30,30,30,30,31,30,30,31,30,30,31,30,30,31,31,30,30,30,30,30,29,29,29,29,28,29,29,28,28,28,29,29,27,29,29,29,28,30,30,29,29,30,30,29,30,31,29,30,30,29,30,29,29,29,28,28,27,27,29,28,27,29,28,27,28,29,29,28,30,30,30,29,30,30,28,29,30,30,30,30,31,30,30,31,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,29,29,29,29,29,29,29,28,29,28,27,28,28,27,26,27,26,26,26,26,26,26,26,26,26,26,25,24,23,26,26,25,28,26,29,29,29,30,30,30,29,29,30,30,29,30,30,30,29,30,30,30,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,31,30,30,30,29,29,30,30,30,29,30,31,30,30,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,30,30,30,30,30,30,30,29,30,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,31,31,30,30,31,30,31,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,29,28,29,28,27,26,27,23,26,26,24,26,26,25,25,26,26,24,24,26,25,23,26,25,23,24,27,24,22,24,25,22,24,24,23,24,24,24,23,23,24,24,24,24,24,24,26,26,26,26,25,25,25,24,24,24,23,23,23,23,23,24,23,23,22,21,20,19,19,17,16,14,13,12,9,7,6,5,3,1,0,1,3,4,6,7,9,11,11,15,14,18,18,20,23,22,26,27,27,28,28,29,29,30,30,30,30,29,30,30,29,29,29,30,28,28,30,30,29,29,29,30,29,30,30,30,30,30,30,30,29,28,29,29,29,28,28,28,29,29,27,29,29,28,28,29,30,29,29,29,30,30,30,30,30,30,30,31,30,30,31,30,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,31,31,31,30,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,29,30,31,30,30,31,31,28,30,31,30,29,30,31,30,30,31,30,29,30,30,30,30,31,31,30,30,30,31,31,30,31,30,31,31,31,30,31,31,30,31,31,31,30,31,31,31,31,30,30,30,30,29,30,31,29,29,29,29,30,30,29,30,30,30,30,30,29,30,30,29,30,30,29,30,31,30,30,30,30,30,30,30,30,30,29,29,30,29,28,29,29,28,29,28,30,29,29,30,29,29,29,30,29,29,30,30,29,29,30,30,29,30,30,30,30,30,31,30,30,31,30,31,31,30,30,31,31,30,30,30,30,30,29,29,29,29,29,28,29,28,28,28,29,29,28,29,29,29,28,29,29,29,30,30,30,29,30,30,29,29,29,29,29,29,29,28,28,28,27,28,28,25,27,29,27,26,28,29,29,28,29,29,29,29,29,29,28,28,29,29,30,30,30,30,31,30,30,30,30,31,30,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,30,30,31,30,30,30,29,30,30,30,30,30,29,29,30,29,29,29,28,29,29,29,29,29,29,29,28,29,29,28,28,28,28,28,27,27,26,25,26,25,25,25,24,24,24,23,24,24,25,24,24,24,23,25,24,27,25,28,27,27,29,29,29,28,28,29,29,29,30,30,29,30,30,30,30,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,29,31,30,29,30,29,28,29,30,30,29,30,30,30,30,30,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,29,30,30,30,29,30,29,29,29,30,31,30,30,30,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,31,29,30,31,30,30,30,28,28,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,28,27,29,27,27,28,27,26,26,26,26,23,25,25,23,25,25,24,24,24,24,24,24,24,23,25,24,24,23,24,25,24,24,23,24,23,24,24,23,24,24,24,23,23,24,24,25,24,24,24,26,26,27,25,25,25,25,24,25,24,23,23,24,23,23,24,23,23,22,22,21,20,19,18,16,15,15,13,11,8,7,5,4,3,1,0,1,3,5,5,7,10,10,14,13,16,16,19,22,22,26,27,26,27,28,28,29,30,30,30,30,29,30,30,29,29,30,30,29,29,30,30,29,29,30,30,30,29,30,30,31,30,29,30,30,29,29,29,30,29,28,28,29,28,28,29,30,29,28,30,30,29,29,30,29,30,30,30,30,30,30,31,30,31,31,30,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,29,30,30,30,30,30,31,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,30,29,31,31,30,30,31,30,29,30,30,29,30,30,30,28,29,30,30,29,30,30,29,29,30,30,28,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,31,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,28,29,30,28,28,27,28,28,28,28,29,29,29,29,30,29,29,30,29,30,30,29,30,30,30,29,30,30,29,30,29,30,30,28,28,29,28,28,28,28,28,28,27,29,29,27,29,28,27,28,29,29,28,28,30,29,29,30,30,29,30,30,30,30,29,31,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,28,28,28,28,26,28,26,27,26,28,28,27,28,28,28,28,29,29,29,30,29,30,29,30,29,29,29,29,28,28,29,28,27,28,28,26,27,27,27,27,28,27,26,27,28,29,29,29,29,29,29,29,29,28,28,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,31,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,28,28,28,28,28,27,27,27,27,26,27,26,26,26,26,24,24,26,25,24,27,25,28,28,28,29,29,29,28,28,29,29,29,29,30,29,29,30,30,30,30,31,31,30,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,29,30,30,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,29,30,29,31,30,30,29,29,28,29,30,30,28,29,30,30,29,30,30,30,30,30,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,30,31,31,30,30,30,30,29,30,30,29,28,30,29,29,29,30,30,30,30,30,30,31,31,30,30,31,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,30,31,31,30,30,31,31,30,29,30,30,29,30,30,30,28,30,30,30,30,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,28,29,28,28,28,28,26,26,25,26,22,24,26,23,26,26,25,27,28,27,26,26,28,27,24,26,27,25,26,27,27,25,26,26,24,26,24,25,25,24,25,24,24,26,25,25,25,25,26,27,27,27,26,26,26,26,25,26,25,25,25,25,25,25,25,24,24,24,23,22,21,19,19,17,16,16,14,13,10,7,6,6,4,3,1,0,1,3,4,6,9,10,13,12,16,16,18,22,19,24,25,25,28,28,29,29,30,30,30,30,29,30,30,29,29,29,30,29,29,30,30,29,29,29,30,30,30,29,30,30,30,30,30,30,29,29,28,29,29,28,28,29,29,27,29,29,29,28,29,30,29,28,30,30,30,30,30,30,30,31,31,30,31,31,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,31,30,30,31,31,30,31,31,31,31,31,31,31,30,31,31,30,30,31,31,29,30,30,30,29,30,30,30,30,30,31,31,30,31,31,31,30,30,31,30,30,31,31,31,31,31,31,31,31,31,30,31,31,30,30,31,30,30,30,31,30,29,30,30,28,30,30,30,28,30,30,29,28,30,30,28,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,29,29,29,30,29,30,29,30,28,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,31,29,29,30,29,29,29,29,28,29,26,29,29,28,29,29,28,28,29,28,27,29,30,29,28,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,28,29,29,28,28,28,26,26,26,29,28,27,28,29,28,27,29,30,29,29,30,30,29,30,30,30,30,30,30,30,29,29,29,28,28,27,28,29,26,27,28,27,26,27,28,29,28,29,29,30,29,30,29,28,29,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,29,29,30,29,29,29,28,29,28,28,27,27,27,26,26,26,27,26,26,26,26,27,25,24,24,26,24,25,26,24,27,27,28,28,29,29,28,28,29,29,29,29,30,29,29,30,30,31,30,31,30,30,31,31,29,31,31,30,30,31,31,30,31,31,31,30,31,31,31,31,31,31,31,30,31,30,30,31,31,30,31,31,30,31,31,31,30,31,31,31,31,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,31,30,30,29,30,29,31,30,30,30,29,29,28,30,30,29,29,30,30,30,30,30,30,30,31,31,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,30,31,31,30,30,31,31,30,30,30,30,29,30,30,30,28,30,29,28,29,30,30,30,30,30,30,30,31,30,30,31,30,30,31,31,30,30,30,31,31,31,31,31,31,30,31,30,31,31,30,30,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,30,30,31,30,30,29,30,30,29,30,31,30,29,30,30,30,30,29,28,28,30,29,29,29,30,30,29,30,30,30,29,30,30,29,30,29,28,28,27,26,27,27,27,26,26,26,25,23,25,22,24,25,23,25,26,25,25,27,27,24,24,27,26,23,25,26,23,25,27,25,23,25,25,23,25,24,24,25,24,25,23,24,25,25,25,25,25,25,27,27,28,26,26,26,26,25,26,25,25,25,25,25,24,25,24,25,23,23,22,23,23,20,19,17,16,15,14,13,11,8,7,5,4,4,2,0,1,3,5,7,7,9,10,12,15,16,19,19,22,25,25,27,25,27,28,29,29,29,30,28,29,29,29,28,29,29,29,28,29,29,29,29,29,30,29,30,29,30,30,30,29,29,29,28,28,29,29,27,28,27,29,28,26,28,29,28,26,29,29,26,27,29,29,29,29,30,29,30,30,30,30,30,31,30,30,30,31,31,30,30,31,30,30,31,31,31,31,30,31,31,31,30,30,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,29,30,30,30,30,30,30,30,31,30,31,30,30,31,31,31,30,31,31,31,30,31,31,31,31,31,31,31,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,28,29,30,30,28,30,30,29,28,30,30,28,29,30,30,29,30,30,30,29,30,30,30,30,31,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,28,30,30,29,29,29,29,29,28,29,30,29,30,30,30,29,29,30,29,30,30,29,30,30,30,29,30,30,29,30,30,30,31,29,29,30,29,29,28,29,27,28,27,28,28,28,29,28,28,28,29,29,28,29,30,29,28,30,30,28,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,28,28,28,27,26,26,25,28,27,27,27,28,28,28,28,29,29,29,29,30,29,30,30,29,29,29,29,29,29,28,29,28,27,26,28,28,25,26,28,26,24,25,28,28,27,28,28,29,28,29,28,27,28,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,31,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,27,27,26,26,26,25,26,25,25,25,25,26,26,25,24,24,24,23,24,25,23,27,26,27,26,29,29,27,28,28,29,27,29,29,29,29,30,30,30,29,31,30,30,31,31,29,31,31,30,30,31,31,31,31,31,31,30,31,31,31,31,31,31,31,30,30,29,30,31,31,30,31,31,30,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,29,30,30,29,30,29,28,28,29,29,28,29,30,29,29,30,30,30,30,30,30,30,31,31,31,31,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,30,30,29,29,30,29,28,29,29,28,29,30,30,30,30,29,30,30,31,29,30,31,30,30,31,31,30,30,30,31,31,31,31,31,31,30,30,30,31,31,30,31,31,31,30,30,31,31,30,30,31,30,31,31,30,31,30,31,30,30,31,30,29,30,30,29,30,30,30,29,29,30,30,30,29,28,27,29,29,29,29,30,30,28,30,30,30,30,30,30,30,30,29,28,28,26,26,27,26,25,25,26,25,24,24,25,21,23,23,23,25,26,25,25,26,25,25,25,26,25,24,26,26,24,26,26,26,25,25,26,24,25,24,24,25,24,25,24,25,26,24,25,25,25,25,28,26,28,26,27,27,27,25,26,26,26,25,25,25,24,25,24,24,23,22,21,23,21,21,19,19,17,16,15,15,13,11,8,8,5,5,3,2,0,1,3,5,6,8,10,11,15,15,19,21,23,26,23,26,26,27,28,29,29,30,30,29,29,30,30,29,29,30,29,29,30,30,29,29,30,30,29,30,30,30,30,30,29,30,30,29,29,29,29,29,29,28,29,28,27,29,29,28,28,29,29,28,27,29,28,29,29,30,29,30,30,30,30,30,31,30,30,30,31,30,30,30,31,30,30,30,31,31,31,31,31,30,31,30,30,30,30,30,30,30,31,31,31,31,30,30,31,30,30,31,31,31,31,30,31,31,31,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,31,31,30,30,31,31,31,31,31,30,31,31,30,30,31,31,30,30,31,30,29,30,30,29,30,30,30,28,29,30,30,28,29,30,29,28,30,30,28,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,31,30,30,30,30,30,29,30,30,30,29,29,29,28,28,27,28,29,27,27,29,28,29,28,29,28,29,30,28,30,29,29,30,30,30,29,30,30,29,30,30,30,30,29,28,29,28,27,28,28,27,28,26,27,28,27,29,28,26,27,29,28,27,28,29,29,28,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,28,28,28,26,26,25,25,25,27,26,27,26,27,28,28,29,29,29,29,29,30,29,30,29,29,29,29,29,29,30,29,29,28,29,25,27,28,26,25,28,26,25,25,28,28,28,28,29,29,29,29,28,28,28,29,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,31,30,31,30,31,30,31,31,31,30,31,30,30,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,29,30,30,29,29,30,29,29,29,29,29,28,28,27,28,28,27,27,27,27,26,27,26,27,27,26,25,25,23,22,23,25,21,26,25,26,28,28,29,27,27,28,29,28,28,30,29,28,30,30,30,30,30,30,30,31,31,29,30,31,30,30,31,30,30,30,31,31,30,30,31,31,30,30,30,30,30,30,29,29,30,30,30,30,30,30,31,30,30,30,31,31,30,31,31,31,30,30,30,31,30,31,31,31,31,31,31,31,31,31,30,31,30,30,30,30,30,29,30,29,30,30,29,29,28,28,27,29,30,27,29,30,30,29,29,30,29,30,30,30,30,30,30,31,30,30,31,31,30,30,31,31,30,31,31,31,30,31,30,31,31,30,30,31,31,30,31,31,31,31,30,31,31,30,31,31,30,31,31,31,30,31,31,30,30,30,30,29,30,30,30,28,29,30,29,28,29,28,28,28,29,30,29,30,29,29,30,30,29,29,30,30,29,30,30,29,30,30,31,30,30,31,31,31,30,30,30,30,31,30,30,31,30,29,31,31,30,30,30,31,30,30,31,31,30,30,30,30,30,30,30,29,30,30,27,30,30,30,28,29,30,29,29,29,26,27,29,28,28,28,29,29,28,29,29,29,29,29,29,29,29,28,28,27,26,25,26,26,26,24,25,24,22,21,23,21,24,25,24,25,26,26,26,26,27,26,26,28,27,25,26,27,26,26,27,26,25,26,26,25,25,26,25,26,25,25,24,26,27,25,26,25,25,26,27,27,28,28,26,27,27,26,26,26,26,26,26,26,25,25,26,25,24,24,23,24,23,23,22,20,20,18,17,17,15,12,11,9,7,6,5,3,2,0,1,4,5,7,9,10,12,15,17,19,20,24,22,26,25,25,27,27,28,29,29,27,28,29,29,27,29,29,28,28,29,29,29,29,29,30,29,29,29,30,30,30,29,29,29,29,28,29,28,28,28,27,28,27,25,27,28,27,25,28,28,27,26,28,28,29,28,29,29,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,31,30,31,31,30,30,31,31,30,30,31,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,31,31,31,30,30,31,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,28,29,30,30,28,30,30,29,28,30,30,28,29,29,29,28,29,29,29,28,29,30,30,30,30,28,30,30,30,29,30,30,29,29,30,30,30,30,30,30,30,29,30,30,30,28,30,30,30,29,29,30,29,28,28,29,29,30,28,30,28,29,30,28,30,30,28,30,30,30,29,30,30,30,30,30,30,30,29,29,30,29,29,29,28,27,27,25,27,28,26,29,28,27,27,29,28,27,29,30,29,28,30,30,29,30,29,30,28,29,30,30,30,30,29,30,30,29,30,30,30,30,29,30,30,30,29,29,29,28,28,28,27,26,25,24,26,27,27,26,28,28,28,29,29,29,29,29,29,29,30,30,29,29,29,29,29,29,29,29,28,28,27,28,29,25,27,28,26,25,26,27,27,27,28,28,28,27,28,29,28,28,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,31,30,31,31,30,30,30,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,30,31,30,30,30,30,30,30,30,29,30,30,29,30,30,30,29,30,30,29,30,29,30,29,28,29,29,29,29,28,28,27,27,27,26,26,26,26,26,26,25,25,26,25,25,24,25,24,24,26,22,26,25,26,27,28,28,28,27,28,28,28,28,30,29,28,29,30,30,29,30,30,30,31,30,29,30,31,30,30,31,30,30,30,31,30,30,31,31,31,30,31,30,30,30,30,29,30,30,31,30,30,31,30,31,30,30,30,31,31,30,30,31,30,30,30,30,30,30,31,31,31,31,31,31,30,30,31,30,30,30,30,30,30,30,29,30,29,30,30,29,30,28,28,28,29,29,28,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,29,30,31,30,30,31,31,30,30,31,30,30,31,31,31,31,31,30,31,31,30,31,31,31,31,30,30,30,30,30,31,30,31,31,30,30,31,31,30,30,30,30,29,30,30,30,28,29,30,29,28,29,29,27,28,29,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,29,30,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,28,29,30,29,28,29,30,29,29,28,27,26,28,28,27,28,29,29,28,29,29,28,29,29,29,29,29,28,27,27,25,24,26,25,24,23,23,24,22,20,23,20,23,22,23,24,25,24,24,25,25,25,24,26,25,24,26,26,25,25,26,26,25,25,26,25,24,24,25,24,25,25,24,25,25,24,25,26,25,25,28,27,28,26,26,27,27,26,26,26,26,26,25,25,25,26,25,25,24,24,23,23,23,21,22,21,20,20,18,17,16,14,13,11,7,8,6,4,3,1,0,1,3,6,6,8,11,12,15,17,20,22,21,24,24,25,26,28,28,29,29,28,28,29,29,28,28,29,28,28,30,29,28,28,29,29,29,29,29,30,30,29,28,29,29,28,28,29,28,28,28,27,28,27,26,27,28,27,25,28,28,26,26,28,27,28,28,29,29,29,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,29,30,31,31,31,31,30,31,31,30,30,31,30,30,30,30,30,29,30,30,29,29,30,30,28,29,30,29,28,29,30,29,28,30,30,28,28,30,30,28,29,30,29,29,29,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,29,30,30,30,28,30,30,29,28,29,29,28,28,27,28,28,28,28,28,28,29,28,29,28,29,30,28,29,29,29,29,30,29,29,30,29,29,30,30,30,30,29,28,29,29,28,27,27,27,27,26,28,27,26,29,27,27,26,29,28,27,27,29,28,27,29,29,28,29,30,29,29,28,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,29,27,27,26,25,25,25,23,24,26,26,25,27,27,26,27,28,28,29,29,29,29,29,29,29,29,28,28,29,29,28,28,28,27,26,27,27,24,24,27,25,23,24,26,26,27,27,27,27,27,28,27,27,27,28,29,29,29,29,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,31,31,31,30,30,31,31,31,31,30,31,30,31,31,31,30,31,31,31,31,31,31,31,31,30,30,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,28,28,28,28,28,27,28,27,27,26,26,27,27,26,25,25,25,24,24,25,22,26,25,26,26,28,27,25,27,27,28,26,28,29,28,28,30,30,30,30,31,30,30,30,30,29,30,31,30,30,31,31,31,30,31,31,30,31,31,31,30,31,31,30,30,30,30,30,30,30,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,29,30,29,30,29,29,30,28,27,28,29,30,27,28,30,30,29,29,30,30,30,30,30,30,30,31,31,30,30,30,31,31,31,31,31,31,31,31,30,31,31,31,31,30,30,31,31,31,31,31,31,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,30,31,31,30,30,30,30,28,29,30,29,27,28,28,28,28,29,30,30,30,29,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,31,30,30,31,30,30,30,31,31,30,30,31,31,30,31,31,30,30,30,30,30,30,31,31,31,30,31,30,30,30,30,29,30,30,28,29,30,30,28,29,30,29,29,28,26,26,28,27,26,27,30,28,27,29,30,28,28,29,29,29,29,28,27,27,24,23,25,25,23,23,22,22,21,19,22,21,22,23,25,25,26,26,26,27,28,26,26,27,27,26,27,27,26,27,28,27,26,26,28,26,26,26,27,26,26,26,24,26,27,25,26,26,26,26,29,27,29,27,28,28,28,27,28,27,27,27,27,27,26,27,26,26,25,25,24,25,24,23,22,22,22,21,21,21,18,17,17,15,11,10,10,7,5,5,2,0,1,4,5,7,10,11,14,17,20,22,20,24,24,24,26,27,28,29,29,27,28,29,29,27,29,29,28,28,29,29,29,28,30,30,29,29,29,30,30,29,28,29,29,28,28,29,29,28,28,28,28,28,26,27,28,27,25,27,27,26,25,28,26,29,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,30,30,30,31,30,31,31,30,30,30,31,29,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,31,31,30,30,31,30,31,30,31,30,31,31,30,30,31,31,30,30,31,30,29,30,30,30,29,30,30,27,29,30,30,27,29,30,29,27,30,30,26,28,30,30,28,29,29,29,29,29,30,30,30,30,28,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,29,30,30,30,28,29,30,29,29,28,29,29,27,28,29,28,29,28,29,27,29,30,28,30,29,27,30,30,29,29,30,30,29,29,30,30,30,29,28,30,29,28,28,27,26,26,26,26,28,26,28,28,26,25,29,28,26,27,29,27,26,29,29,27,29,29,30,29,29,30,29,30,30,29,30,30,29,30,30,30,30,29,29,29,29,28,29,29,27,27,27,26,25,24,22,24,27,26,24,26,28,26,27,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,27,28,28,25,25,27,25,25,24,27,26,26,27,27,27,27,28,27,27,28,29,29,29,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,31,30,30,30,30,31,30,30,31,30,31,31,30,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,31,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,29,30,29,28,28,28,28,27,27,27,27,27,27,26,26,28,27,27,24,25,24,24,24,21,25,23,25,24,27,27,26,26,28,28,28,28,30,29,28,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,31,31,30,30,30,30,30,31,31,31,31,31,31,30,30,31,30,30,30,30,31,30,30,30,30,30,31,30,29,30,29,29,28,30,30,28,29,30,30,29,30,30,30,30,30,30,30,31,31,31,30,30,30,31,30,30,31,31,30,30,31,30,30,31,30,30,31,30,30,30,30,30,30,30,31,31,30,30,30,30,30,31,30,31,31,30,30,31,30,30,30,30,30,29,30,30,30,29,30,30,29,27,28,28,27,29,29,30,29,30,30,28,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,28,29,30,30,28,29,30,29,29,28,26,25,28,27,25,27,29,28,26,29,29,28,28,29,29,28,28,28,26,25,23,22,24,23,23,21,21,20,20,16,20,19,23,23,24,25,25,26,26,27,27,26,26,28,26,26,27,27,25,26,27,26,25,26,27,25,25,25,25,25,25,25,24,26,26,26,26,26,26,27,29,28,29,28,28,28,28,28,28,27,27,27,27,26,27,27,27,26,25,25,24,25,25,24,24,23,23,22,21,22,20,18,18,17,14,13,10,8,8,6,5,2,0,1,4,5,8,10,11,14,17,20,19,22,21,24,25,27,27,28,28,26,27,29,28,27,28,29,27,28,29,29,28,28,28,29,28,29,29,30,30,29,28,29,28,28,28,29,28,27,27,26,28,27,25,27,27,25,24,27,28,25,24,26,26,28,27,28,28,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,29,30,30,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,28,29,30,28,28,30,30,27,28,29,29,27,29,29,28,28,29,30,29,30,30,28,29,29,30,28,30,30,29,30,30,30,30,30,30,30,30,29,30,30,30,28,30,30,29,29,29,30,29,27,28,29,29,30,28,30,28,29,30,28,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,29,30,30,29,29,27,27,27,26,27,27,26,29,27,26,26,28,28,27,27,29,27,26,29,29,27,29,29,29,27,28,29,29,29,30,29,30,30,29,30,30,30,30,29,29,30,30,27,29,29,27,27,28,26,25,24,22,23,25,26,23,26,27,26,27,28,28,27,27,29,29,29,29,29,30,29,28,29,29,28,28,28,28,26,28,28,24,25,26,23,22,22,25,24,24,25,26,27,26,27,28,26,27,28,28,29,30,29,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,28,27,27,26,27,28,27,25,27,27,25,24,25,24,24,23,24,22,26,24,24,26,27,27,27,28,28,28,27,28,29,29,28,29,30,29,29,30,30,30,30,30,29,30,30,30,30,31,30,31,31,31,31,31,30,30,30,30,30,30,30,30,31,30,30,30,31,30,30,30,30,31,30,30,30,31,31,30,31,30,30,30,30,30,30,30,30,30,30,31,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,29,30,29,28,28,30,30,29,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,29,29,29,29,27,29,30,30,29,30,30,29,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,29,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,28,29,30,29,28,29,30,29,29,28,26,26,28,26,25,28,29,27,27,29,29,28,28,29,29,29,28,27,25,25,22,21,22,22,21,21,19,20,20,16,19,18,21,20,22,22,24,24,24,26,26,26,26,27,26,26,26,27,26,26,28,27,26,27,27,26,26,26,26,26,26,27,24,25,26,25,26,26,27,27,29,26,29,28,28,29,29,27,28,28,27,28,27,27,27,28,27,27,25,25,24,26,26,24,23,24,22,23,23,24,22,20,20,19,17,16,13,10,8,9,6,4,2,0,1,3,5,8,9,12,16,18,16,22,21,21,24,26,27,28,28,26,27,28,27,26,28,29,27,27,29,29,28,28,29,29,29,28,28,30,29,29,27,28,28,27,28,29,28,27,27,26,26,27,26,25,27,26,24,25,27,24,24,27,26,28,27,29,28,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,29,30,30,29,29,30,30,29,30,30,30,28,30,30,29,28,28,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,27,29,29,28,27,29,29,28,27,29,29,27,28,29,29,28,29,30,29,28,29,30,29,30,30,28,29,29,30,28,30,30,29,29,30,30,29,28,28,29,29,27,29,29,29,27,28,29,28,27,27,29,28,26,26,28,28,29,28,29,27,29,29,28,30,29,29,30,30,30,29,29,30,29,30,29,29,30,29,29,29,29,28,28,26,27,26,25,27,27,26,28,26,25,26,28,26,25,27,28,26,26,28,28,25,28,29,28,27,27,29,28,29,29,28,29,29,28,29,29,29,29,28,28,28,28,26,28,28,26,25,26,25,23,23,21,23,26,23,21,25,25,24,25,27,27,25,26,28,28,28,28,28,28,28,27,29,28,27,27,27,27,25,25,26,23,23,24,23,20,21,23,24,22,25,25,25,25,26,27,26,26,27,27,28,28,29,29,29,29,30,29,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,30,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,30,31,31,31,30,31,30,30,30,31,30,30,30,30,30,29,29,29,29,28,27,29,28,28,27,28,27,28,28,27,26,26,25,25,22,24,22,24,24,25,26,26,27,25,27,28,29,28,28,29,29,29,30,30,30,30,30,30,30,31,30,30,30,31,30,30,31,30,31,30,31,31,31,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,31,30,30,31,31,30,31,31,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,29,30,29,29,28,29,30,28,28,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,31,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,31,31,31,30,30,31,31,30,30,30,30,28,30,30,28,27,28,29,27,29,29,29,29,29,30,28,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,28,29,30,30,28,29,30,29,28,27,26,26,27,26,26,26,28,27,26,28,28,27,27,28,28,28,28,27,25,25,21,21,23,22,21,20,18,20,20,16,19,16,20,21,23,24,24,25,26,28,27,25,26,28,27,26,27,28,27,27,28,27,27,27,28,27,27,27,28,27,27,27,26,27,28,26,27,27,27,28,29,28,30,28,29,29,29,27,28,29,28,28,28,28,28,28,27,28,27,26,26,27,26,26,26,25,24,25,24,24,23,21,22,22,20,18,15,14,11,11,8,7,5,2,0,1,4,6,7,10,14,16,15,20,19,20,24,25,26,27,28,24,27,28,27,25,27,28,27,25,28,28,27,27,28,29,29,28,28,29,29,28,27,28,28,26,27,28,26,27,28,26,26,27,25,25,26,25,23,25,27,23,22,26,24,28,26,28,28,28,29,29,29,29,30,30,30,30,30,29,30,30,30,30,29,30,30,30,30,30,30,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,29,30,30,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,28,29,30,29,28,29,30,28,28,30,29,26,28,29,29,26,28,29,28,27,29,29,29,29,30,28,29,29,30,28,30,30,29,29,30,30,29,30,29,30,30,29,29,30,29,27,29,30,29,28,28,29,29,27,28,29,29,29,29,30,28,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,29,30,30,29,29,28,28,27,26,26,28,26,28,27,26,25,28,27,25,27,28,26,25,29,29,25,28,29,29,26,28,29,29,29,30,29,30,30,29,29,29,30,30,28,28,29,29,27,28,29,27,26,28,26,24,23,21,22,25,24,21,24,26,25,25,27,27,25,28,28,27,28,28,28,29,28,29,29,28,27,28,27,28,25,27,26,23,24,25,21,20,20,23,23,22,24,24,25,24,26,26,25,27,27,28,29,29,29,28,30,29,30,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,30,31,31,30,31,31,30,31,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,29,29,29,29,29,28,28,29,28,28,27,28,27,27,26,25,26,26,23,25,23,24,26,25,27,27,27,26,27,29,29,27,27,30,28,27,29,30,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,28,28,29,28,29,29,30,30,30,29,29,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,28,29,30,29,28,29,30,29,28,28,26,28,28,27,25,29,29,27,27,28,28,27,28,29,28,28,27,26,26,25,21,21,21,23,23,19,19,22,21,12,18,18,21,20,23,25,26,26,26,28,27,26,26,28,27,26,27,27,27,27,28,28,27,28,28,27,27,27,28,27,27,28,25,25,28,27,26,27,28,29,30,28,30,29,29,30,30,29,29,29,29,29,29,29,29,29,28,28,27,27,26,27,27,26,26,26,25,25,25,26,24,22,25,21,20,21,17,16,15,11,9,9,7,5,2,0,1,4,6,8,12,15,15,19,19,20,24,24,26,26,28,26,26,28,27,25,26,28,27,26,27,28,26,27,28,29,28,28,28,29,28,28,27,27,28,26,27,28,26,26,27,25,26,25,25,25,26,25,23,25,26,23,22,26,25,27,26,28,28,28,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,29,29,28,29,29,29,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,30,29,28,29,29,28,28,29,29,28,28,30,29,27,28,30,29,26,29,29,28,28,29,30,29,29,30,29,29,30,30,29,30,30,29,29,30,29,29,30,29,29,29,29,29,30,29,27,29,29,29,28,27,29,28,26,27,28,28,29,27,29,28,28,29,29,30,30,29,30,30,30,29,30,30,30,30,29,30,30,30,29,29,29,29,29,27,28,27,26,26,27,26,28,27,25,25,28,27,25,27,28,25,25,29,28,24,28,29,29,26,27,29,28,29,29,29,29,30,29,29,29,29,29,28,28,29,28,26,28,29,26,25,27,25,24,24,20,24,25,23,22,26,25,23,24,26,26,25,26,28,27,27,28,28,29,28,28,28,27,27,28,26,26,25,26,26,22,23,24,21,19,20,23,21,22,24,24,24,24,25,26,25,27,27,27,28,29,29,28,30,29,29,29,28,29,29,29,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,31,31,31,31,30,30,30],[31,31,31,31,31,31,31,31,31,31,31,30,31,30,31,30,31,31,30,31,31,30,30,31,30,30,30,30,30,31,30,30,31,31,30,31,30,31,31,31,31,30,30,30,31,30,30,29,30,29,29,28,28,28,27,28,28,27,27,28,28,26,25,25,25,26,23,24,22,25,22,22,24,25,26,26,25,27,28,27,26,28,28,28,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,29,30,29,29,29,30,29,29,29,28,28,27,29,29,28,28,29,29,28,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,29,26,27,27,28,27,28,28,29,28,29,29,28,28,29,29,28,30,29,28,28,29,29,29,29,30,30,30,30,30,30,29,29,28,30,30,29,29,30,30,29,30,30,30,30,29,30,29,30,30,30,30,30,30,29,29,30,29,28,29,29,27,28,29,28,27,28,28,27,27,26,24,24,26,25,24,26,27,25,25,27,27,26,28,28,28,27,26,24,24,23,18,19,21,20,20,18,17,18,18,15,17,18,20,20,23,24,24,25,25,26,27,26,26,27,27,26,27,26,26,27,27,27,26,27,28,28,28,26,28,27,27,28,26,26,27,26,26,26,27,28,29,28,29,28,29,29,29,29,29,29,29,29,28,28,28,28,28,28,27,27,26,27,26,26,25,25,24,25,24,26,24,23,25,22,21,21,18,18,16,14,11,10,9,7,5,2,0,1,3,6,8,11,12,15,15,16,21,22,25,26,26,25,25,27,26,24,26,27,25,25,27,27,26,26,27,28,28,27,27,28,28,27,26,28,27,26,27,28,26,26,27,24,25,26,24,25,25,24,22,23,26,22,20,24,24,27,25,27,26,27,28,29,28,28,29,28,28,28,29,29,29,29,29,29,29,30,29,29,29,29,29,28,29,28,28,28,28,29,28,28,30,30,29,29,30,29,29,29,30,29,29,29,29,28,29,29,29,28,29,29,28,27,28,28,28,29,29,29,30,30,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,28,28,29,29,27,28,29,28,27,28,28,27,26,28,28,24,27,28,27,25,27,27,26,26,27,28,27,28,28,27,27,28,29,27,28,29,28,28,29,29,28,28,27,28,28,27,28,28,28,26,28,28,28,27,27,28,28,25,27,28,28,28,27,29,28,29,30,28,29,29,29,29,29,30,29,29,30,30,29,30,29,30,29,29,29,29,29,29,27,27,26,27,26,26,24,27,26,24,24,27,27,22,25,27,24,23,27,27,22,27,27,27,24,26,27,27,27,28,26,28,28,27,28,28,28,28,27,26,27,27,25,26,28,26,24,26,25,24,22,20,21,24,22,19,23,24,21,23,25,25,22,25,27,25,25,27,27,27,26,27,28,26,26,27,25,26,25,25,24,22,21,22,17,16,18,20,19,17,23,21,24,23,23,24,23,25,25,26,26,27,28,26,29,27,29,27,27,28,29,28,28,29,28,28,30,29,29,29,29,29,29,29,29,30,30,30,30,30,29,29,30,29,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,31,30,31,31,31,31,30,31,30,30,30,31,31,30,31,30,30,30,30,30,31,30,30,30,30,30,31,30,30,30,30,30],[31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,30,30,31,30,30,30,30,30,30,29,29,29,29,29,28,29,28,28,28,29,27,28,28,28,27,27,26,26,21,24,21,24,21,23,25,25,27,26,26,28,28,26,27,29,28,27,28,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,29,30,29,28,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,31,30,30,30,30,31,30,30,30,30,30,29,30,29,30,29,30,29,29,29,28,29,27,29,29,28,28,29,29,29,29,30,29,29,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,29,28,29,30,28,27,27,28,27,28,29,28,27,29,29,27,29,30,28,28,29,29,28,30,29,29,28,29,30,29,30,30,30,30,29,29,28,30,30,29,29,30,30,28,30,30,30,29,30,30,30,29,30,30,29,30,30,29,29,29,29,29,29,29,27,29,29,28,28,28,29,28,28,27,25,24,26,25,22,25,28,26,23,27,27,25,26,27,27,25,25,22,22,22,17,16,21,20,20,17,15,18,19,12,16,14,20,18,21,24,24,25,24,26,26,27,26,28,27,26,27,27,27,26,27,27,26,27,27,27,27,27,27,27,27,27,26,26,27,26,27,27,26,27,29,28,29,28,28,29,29,28,29,28,28,28,28,28,28,28,28,28,27,27,26,26,27,25,26,25,25,25,24,27,24,23,25,24,23,23,20,19,18,15,13,11,9,9,6,4,2,0,1,5,6,9,12,14,13,16,19,22,23,25,26,24,25,26,24,24,25,26,25,24,26,26,24,26,26,28,27,26,26,28,27,26,25,26,25,24,25,27,25,24,25,24,25,24,22,23,24,23,20,23,24,19,17,24,21,25,24,26,27,26,27,29,27,28,29,29,29,28,29,29,29,28,29,29,28,29,29,29,29,29,29,29,30,27,29,28,29,29,29,28,29,29,28,29,30,29,28,29,30,29,28,30,29,28,28,30,29,27,29,29,28,27,29,28,28,29,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,28,28,29,29,27,28,28,28,27,28,28,27,27,29,29,27,27,29,28,27,28,29,27,28,28,28,28,28,29,29,28,28,29,28,29,29,28,28,29,29,28,28,28,29,29,28,28,29,28,28,28,29,28,28,27,29,28,27,28,28,28,28,27,29,28,29,30,29,29,30,29,30,30,29,29,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,28,27,27,27,26,28,26,26,25,27,27,24,25,28,25,25,28,27,23,27,27,27,24,26,28,27,28,28,27,29,29,28,28,28,29,28,28,27,28,28,26,27,28,26,24,26,25,23,23,18,22,25,22,19,23,25,21,22,25,25,23,25,27,25,25,27,26,28,26,27,27,26,26,27,25,26,25,25,24,19,21,20,16,14,17,19,17,17,22,18,23,23,24,23,22,25,25,26,27,27,29,27,29,28,29,28,28,29,28,28,28,29,28,28,29,29,29,29,29,29,28,29,29,29,29,29,30,30,29,30,30,29,30,30,29,30,30,30,30,30,30,30,31,30,30,30,31,30,31,30,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,31,30,30,31,31,31,31,30,30,30,31,30,30,30,30],[31,31,30,30,31,31,31,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,31,30,30,30,30,30,30,29,29,28,28,28,28,27,27,28,27,26,26,26,26,24,24,23,23,24,22,22,22,23,22,21,23,23,23,24,25,26,26,25,24,27,27,24,27,27,28,28,28,29,29,29,29,29,29,30,29,29,30,30,30,29,30,29,30,29,30,29,29,29,29,29,29,30,29,29,29,28,29,29,29,29,30,29,30,30,30,30,29,30,29,29,29,29,29,29,30,30,30,30,30,29,30,30,30,30,30,30,29,29,30,29,29,28,28,28,29,28,28,28,27,26,27,27,28,27,27,28,28,28,28,29,28,28,29,29,28,29,29,29,29,28,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,28,29,29,29,29,29,29,30,29,30,30,29,29,30,29,27,28,28,27,25,27,27,25,26,26,27,26,27,27,27,27,27,27,27,28,28,27,27,28,27,26,28,27,26,27,28,28,28,28,29,29,29,27,28,26,29,29,28,27,29,29,27,29,29,28,29,29,28,29,29,29,29,29,28,29,27,28,28,27,26,27,27,25,26,27,26,26,26,26,25,25,24,22,23,24,23,21,23,25,23,23,25,25,23,25,26,25,26,24,22,21,20,17,15,19,19,19,17,15,18,18,14,16,15,20,18,21,21,23,22,22,24,24,24,24,26,24,24,26,26,24,25,26,27,25,26,28,27,27,26,28,26,25,26,24,25,25,26,25,25,25,26,28,27,28,28,28,28,29,28,29,29,28,28,28,28,28,28,28,28,27,26,26,26,26,25,25,25,25,25,24,26,24,24,25,24,23,22,20,20,19,17,15,14,11,9,9,5,3,1,0,1,4,7,10,13,13,13,17,19,22,25,24,22,24,24,24,23,25,24,23,22,26,25,24,24,26,26,26,25,26,26,25,26,24,26,26,24,27,26,25,23,25,23,23,25,21,22,24,22,18,22,24,18,17,23,20,25,24,25,24,25,27,26,27,26,28,26,26,27,27,27,28,27,27,28,27,27,28,28,27,28,27,27,28,26,27,25,27,28,27,26,28,28,27,27,28,28,27,28,28,28,26,28,28,26,27,27,28,25,27,27,27,25,26,27,26,27,27,27,28,29,28,29,28,28,29,29,29,29,29,29,29,29,30,29,29,28,29,29,29,28,29,29,29,28,28,28,28,27,27,28,27,24,27,27,26,25,26,27,25,24,27,26,24,25,27,25,23,26,25,24,24,26,27,26,26,27,26,25,26,27,25,27,27,26,26,27,27,26,26,25,26,26,25,27,26,26,25,25,25,26,26,25,26,25,24,25,25,26,26,27,27,27,28,28,27,28,28,28,28,28,28,28,28,29,28,28,29,28,28,28,27,28,27,28,27,26,26,25,24,23,25,24,25,24,22,24,25,24,20,24,26,23,22,25,25,21,24,25,25,22,25,25,26,26,26,26,27,27,26,26,25,26,25,26,24,25,25,23,25,25,23,21,24,23,22,21,18,20,23,21,19,22,23,18,20,23,23,19,23,25,22,23,24,24,24,25,24,25,24,23,23,23,23,22,22,20,16,19,18,13,13,15,17,17,14,20,16,22,21,22,20,19,23,23,24,24,25,25,25,26,25,27,25,25,26,26,26,26,28,27,26,27,27,26,27,28,28,27,28,28,28,27,28,28,29,28,28,28,29,29,28,28,29,28,29,29,29,29,29,30,30,29,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30],[30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,28,28,28,27,28,27,28,27,27,26,26,25,25,25,24,23,22,22,22,19,20,20,20,19,19,21,23,24,22,22,24,25,24,24,25,25,26,26,27,28,28,28,29,28,28,28,29,28,29,28,28,29,29,29,29,29,28,29,29,29,29,28,29,29,29,28,29,29,28,28,28,29,29,29,28,29,28,28,29,29,29,29,29,28,29,28,28,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,29,27,27,28,28,27,27,27,27,26,26,26,27,25,25,27,26,26,27,28,27,27,28,28,27,28,28,28,28,28,28,28,28,28,29,29,28,28,28,28,29,28,28,28,28,28,28,28,28,28,27,28,28,28,29,28,28,29,28,28,28,29,28,29,29,29,28,28,28,29,28,27,27,27,26,25,26,25,23,24,23,25,23,25,25,25,25,27,26,25,25,26,25,24,26,26,25,25,26,25,26,26,27,27,27,27,27,28,26,27,26,27,28,27,26,27,28,27,27,27,28,27,27,27,27,28,28,27,28,28,28,26,27,27,26,26,25,25,24,25,25,24,23,24,24,23,23,24,20,21,22,21,20,21,22,21,20,21,21,22,22,21,21,21,21,19,19,18,13,13,16,15,16,15,13,15,16,11,13,13,18,16,18,19,19,21,21,23,23,22,23,24,24,22,25,25,24,24,25,26,25,26,27,26,26,25,27,26,25,26,25,24,24,25,26,24,26,26,27,27,28,27,28,28,28,28,29,29,28,28,28,29,28,28,28,28,27,27,26,27,26,25,26,24,25,25,24,25,24,24,25,22,24,23,21,22,21,19,18,17,15,11,10,9,6,4,2,0,1,4,7,8,9,10,13,14,17,21,19,18,19,21,19,18,20,21,20,18,22,22,22,21,23,24,24,22,23,23,23,22,20,22,23,20,23,23,20,20,22,20,20,22,18,18,20,20,17,18,20,16,14,19,16,22,19,21,21,21,21,23,22,22,24,24,23,24,25,25,25,24,26,25,25,25,27,27,26,25,26,25,26,23,24,23,25,26,24,25,27,27,25,25,26,26,25,25,26,25,24,27,26,25,25,26,27,23,25,26,25,23,24,25,25,26,26,25,27,27,26,27,27,27,28,28,27,28,28,28,29,29,29,28,28,29,28,28,28,28,28,28,28,27,26,27,28,26,26,26,26,23,25,25,23,23,24,24,22,22,24,23,21,22,22,22,19,22,22,21,21,22,22,21,23,24,23,23,23,25,23,24,24,23,23,25,26,23,24,21,24,24,22,23,23,23,21,22,24,24,23,23,25,23,22,23,24,24,25,25,27,25,27,28,26,27,26,27,28,28,27,27,28,27,27,28,28,27,28,28,26,26,26,26,26,24,24,23,23,22,22,21,23,22,19,21,22,22,18,21,22,18,19,22,21,17,22,21,22,19,20,22,21,22,23,20,24,24,21,22,23,24,23,22,19,23,23,19,21,23,21,18,22,21,19,18,16,16,21,16,14,18,20,15,17,18,20,15,18,21,20,18,21,21,22,22,22,22,20,23,23,19,20,19,19,17,15,14,14,11,10,11,12,12,10,14,14,17,15,18,17,16,20,20,21,21,22,24,22,24,22,26,23,23,24,24,23,24,24,23,23,25,25,24,25,25,25,24,25,26,26,25,27,26,27,26,26,27,26,27,26,27,28,27,28,28,27,27,29,29,29,28,29,29,29,30,29,29,30,29,30,29,30,30,30,29,30,30,29,30,30,30,29,29,30,30,29,29,29,29,29,30,29,29,29,29,29],[30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,29,28,29,29,28,29,29,28,29,29,29,29,29,28,29,29,30,29,30,29,29,29,29,29,29,28,28,29,28,28,26,27,25,25,27,26,26,24,25,24,23,23,22,22,20,18,16,15,14,13,12,13,12,12,11,13,13,16,14,15,17,18,15,16,19,18,16,19,20,21,21,22,23,22,24,23,23,25,24,23,23,26,25,26,25,25,25,25,26,26,26,25,25,25,25,24,24,24,24,23,25,23,25,25,22,23,25,26,24,25,25,26,24,25,26,24,23,25,25,26,25,25,26,26,24,26,26,25,26,25,24,23,24,24,22,23,21,23,22,24,22,20,22,21,19,20,21,21,18,19,21,20,19,21,23,20,21,24,23,19,22,23,23,24,20,24,24,23,22,24,25,23,23,24,23,23,24,24,24,25,24,24,24,24,24,23,23,23,23,22,23,23,22,24,24,22,25,24,23,23,24,24,21,22,23,21,18,21,22,18,16,20,20,16,16,18,18,20,21,20,19,19,20,19,18,20,21,19,19,20,21,16,19,19,18,18,20,21,21,22,22,22,20,19,20,17,20,21,19,17,22,22,17,21,21,22,20,21,21,22,23,22,22,21,21,19,17,19,19,17,17,19,17,14,16,19,16,14,18,18,15,16,15,11,14,16,13,10,15,16,11,14,15,16,14,18,16,15,17,14,15,15,10,9,7,9,8,8,9,7,8,8,7,8,9,10,11,13,15,15,16,17,20,19,18,18,19,18,19,20,19,20,21,23,23,22,23,24,24,26,23,25,24,23,24,23,21,23,25,24,23,24,24,25,25,27,26,28,28,28,28,29,29,28,28,28,28,28,28,28,27,26,26,25,26,25,24,24,22,24,24,22,24,23,23,24,22,22,23,20,21,20,19,19,17,15,13,11,10,8,6,3,3,0,1,2,4,5,7,7,10,10,13,14,12,12,16,16,14,15,16,16,17,19,17,17,19,20,20,20,19,19,18,16,18,15,17,18,17,19,19,16,16,16,14,16,16,13,14,15,13,14,14,14,13,10,13,11,15,14,14,15,14,16,16,17,18,17,17,18,20,19,18,20,20,20,20,21,20,22,21,18,20,19,19,20,17,18,14,18,21,17,16,20,21,17,18,20,19,16,18,19,18,14,19,20,16,15,19,19,14,18,19,17,14,16,17,18,18,19,18,20,20,20,22,23,20,21,23,21,20,23,24,23,22,23,23,23,24,23,23,23,22,22,22,22,21,20,21,21,18,18,21,18,14,17,19,16,15,17,17,14,14,17,15,11,14,16,12,10,16,17,13,13,15,17,15,17,17,16,16,17,16,15,16,18,15,14,18,18,17,16,13,17,17,13,14,16,16,13,15,16,16,13,14,16,16,13,15,18,17,18,19,21,20,21,22,19,22,21,21,22,23,21,22,22,22,22,23,24,23,22,22,21,21,19,20,19,18,17,15,15,14,16,14,15,15,12,12,16,13,11,12,14,11,11,14,11,10,12,14,12,11,13,15,15,16,14,12,15,16,12,14,16,17,15,14,13,15,15,12,13,15,12,11,13,12,11,9,9,9,10,8,7,10,11,7,9,13,11,9,12,13,11,12,15,12,15,15,14,14,12,15,14,12,16,13,13,12,10,9,8,7,5,5,6,5,6,9,9,12,9,11,9,11,14,14,14,15,14,17,15,17,15,18,18,16,17,18,17,15,19,18,16,17,19,18,16,19,20,18,19,20,21,19,20,22,22,22,21,22,21,23,22,22,23,24,24,25,26,25,27,27,29,27,27,27,27,29,27,28,29,28,28,28,29,28,28,28,29,28,29,29,29,28,28,26,28,28,28,27,28,28,25,27,27,26,27,27,26],[30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,28,29,29,28,29,28,27,29,29,28,28,29,28,29,29,28,29,30,30,29,30,29,29,29,29,29,29,28,29,28,28,28,27,27,26,26,26,26,25,24,25,24,24,23,22,20,18,15,12,11,10,9,8,8,7,7,7,7,7,9,8,9,11,11,10,10,13,12,11,13,14,15,15,16,16,17,18,17,17,17,17,17,17,19,19,19,19,19,19,19,20,19,19,19,19,20,17,18,17,17,18,16,18,17,17,18,17,18,17,18,17,17,19,19,18,18,20,17,18,17,18,17,19,19,19,19,19,20,19,17,18,18,18,15,16,17,15,15,16,15,16,16,16,16,15,16,13,15,15,15,13,15,15,15,14,15,14,15,15,16,15,14,16,16,15,16,15,15,17,17,15,17,16,16,16,16,17,16,16,16,17,18,17,17,18,17,16,18,18,18,18,18,17,16,17,17,18,15,18,18,16,15,17,16,13,14,16,15,12,14,15,12,11,13,13,10,10,12,12,12,14,13,14,15,15,14,13,14,14,13,13,14,15,11,13,13,12,11,13,13,14,15,15,13,14,13,14,11,13,15,12,12,15,15,13,14,15,15,14,14,15,16,15,15,16,14,13,13,12,14,13,11,11,12,11,9,10,12,9,9,10,10,8,9,9,6,7,8,7,6,7,8,6,6,8,8,7,9,9,8,10,7,7,6,5,5,4,5,4,5,5,3,4,5,4,4,6,6,6,9,9,10,11,14,18,18,14,15,20,17,15,19,19,18,18,21,22,21,22,24,24,25,23,25,23,22,25,22,21,23,24,23,22,24,25,25,26,27,27,27,27,28,28,28,28,28,28,28,28,27,28,27,27,26,27,25,27,25,25,25,23,26,24,24,26,23,23,25,22,23,24,21,22,22,20,20,19,17,15,13,12,9,7,5,3,1,0,1,2,3,3,4,5,6,8,8,6,7,8,8,7,8,9,9,9,10,10,9,10,12,13,12,11,11,12,10,10,10,10,9,9,10,11,9,9,9,6,7,8,7,6,7,7,6,6,7,6,5,6,6,8,7,8,8,8,9,11,10,10,10,10,12,13,12,13,14,13,14,14,15,14,16,15,13,14,12,13,13,12,11,9,11,13,12,11,14,14,11,11,13,12,11,12,13,11,10,12,13,10,11,13,12,11,12,13,10,10,11,12,12,14,13,15,15,14,15,14,14,13,14,16,14,14,16,16,18,17,16,16,17,16,16,17,16,15,16,16,15,16,15,14,15,13,12,14,13,10,11,11,9,9,9,10,8,8,10,9,8,8,9,7,7,8,9,8,7,9,10,9,10,11,9,9,10,10,8,11,10,10,10,12,12,10,11,9,11,11,9,9,11,11,10,9,10,10,9,9,10,10,10,9,10,12,12,12,14,14,15,15,13,15,15,15,15,16,16,16,14,17,16,16,17,16,16,16,15,15,15,15,13,12,11,9,10,9,9,8,9,10,9,8,9,9,7,8,9,9,7,8,9,7,7,9,8,7,7,9,8,10,10,8,10,11,10,9,11,10,10,10,9,9,9,8,8,10,9,7,10,7,7,6,6,6,6,7,5,7,8,6,7,9,8,5,7,9,6,8,9,8,10,7,9,8,5,7,8,7,5,7,6,6,4,5,5,2,2,3,3,3,3,5,4,5,5,5,5,5,6,7,8,9,9,12,10,12,10,11,12,9,11,12,10,10,12,11,10,11,13,10,11,12,13,12,11,13,14,12,13,14,15,15,16,16,17,18,18,18,18,19,20,20,23,21,25,25,24,23,25,23,24,27,25,26,28,24,28,27,27,26,27,26,27,28,27,26,26,27,27,24,24,28,27,24,28,25,26,26,27,24,24,26,24],[29,29,29,29,29,30,29,29,29,29,29,28,29,28,29,28,29,29,28,29,29,28,29,29,28,29,29,29,29,29,28,29,29,30,29,29,29,29,29,29,29,28,28,28,28,28,27,26,27,26,25,25,25,24,24,24,23,22,22,21,19,17,15,10,9,7,8,7,7,7,6,6,7,6,7,7,8,9,10,9,9,10,11,9,10,12,12,14,14,13,14,14,13,15,14,14,14,14,15,15,15,16,15,14,16,16,15,15,15,15,15,14,14,14,15,14,14,14,14,14,14,13,13,14,15,14,13,15,14,14,14,14,14,13,14,15,15,15,14,15,14,14,15,14,13,13,14,13,14,14,14,13,13,14,14,14,14,13,15,13,13,12,11,13,12,11,12,14,12,12,12,12,12,12,13,13,12,13,12,13,13,12,12,12,13,12,13,13,13,12,13,13,13,13,13,15,15,15,14,15,15,15,15,15,15,15,15,14,13,15,14,14,13,14,14,13,13,13,12,11,12,13,10,10,11,10,9,8,10,10,8,8,9,9,10,11,12,11,11,12,11,10,10,12,10,10,11,11,8,10,11,9,10,11,11,12,12,12,11,10,10,10,9,10,11,10,9,12,12,10,11,12,12,12,12,13,13,13,12,12,12,12,10,10,10,9,9,9,9,9,7,8,8,8,7,8,8,7,7,7,6,7,6,7,5,6,7,5,5,6,6,5,7,7,6,7,5,5,5,4,4,4,4,5,5,6,3,4,6,4,3,5,5,6,7,8,10,11,14,17,18,15,15,18,17,16,18,18,18,17,18,21,20,21,23,23,24,22,25,22,20,22,21,19,21,22,22,21,22,23,26,25,26,25,25,26,27,26,27,27,26,26,26,26,26,27,27,27,25,26,26,26,25,25,26,23,25,25,24,25,24,24,25,23,23,24,21,22,21,19,19,18,17,15,14,13,10,9,6,3,2,1,0,1,2,3,4,5,5,6,6,6,6,7,7,7,8,8,8,9,9,10,9,9,11,11,11,9,10,9,8,8,8,8,9,9,10,11,10,10,9,9,8,8,7,6,6,6,6,6,5,5,4,4,4,6,6,6,7,7,7,8,8,8,8,9,10,9,9,10,10,11,11,12,12,12,12,11,10,10,10,9,10,8,9,8,9,10,9,10,11,11,9,10,10,10,9,9,10,10,9,10,9,9,10,9,10,9,10,11,11,9,10,10,10,11,13,13,13,13,12,12,12,12,13,13,12,13,14,14,14,13,14,14,14,14,16,16,14,13,14,14,13,13,13,12,11,11,11,11,9,9,10,9,8,8,9,8,8,7,8,8,7,7,8,6,5,7,8,6,6,7,8,7,9,9,8,8,9,9,9,9,9,8,9,9,9,8,9,8,9,9,8,8,8,8,8,9,9,8,8,8,9,8,7,8,9,10,10,10,13,11,13,13,11,12,13,14,14,13,13,13,13,14,14,13,15,13,14,13,14,13,12,12,12,11,9,8,8,8,8,8,7,8,7,7,7,8,7,7,6,7,6,7,8,6,6,7,7,5,6,7,7,9,8,8,10,10,8,9,8,9,8,8,7,8,8,6,6,7,6,7,7,7,6,6,4,5,5,5,4,6,5,5,4,6,6,5,6,7,6,6,8,7,8,6,7,7,5,5,6,7,6,5,5,4,4,5,4,3,2,2,4,3,3,4,4,5,4,5,5,4,6,7,7,8,8,9,8,9,9,10,10,9,9,10,9,9,10,10,9,10,10,10,10,10,11,11,10,10,11,10,10,12,13,12,15,14,15,15,16,16,16,17,18,20,20,20,23,23,23,22,23,22,21,24,23,25,26,24,26,26,26,26,25,25,27,26,26,26,26,26,25,23,25,27,26,24,26,24,25,25,26,23,22,24,23],[29,29,29,29,29,30,30,29,29,29,29,29,29,28,29,28,29,29,28,29,29,28,29,29,29,29,29,29,29,29,28,29,29,30,29,29,29,29,30,29,29,29,29,29,29,29,28,27,28,27,26,26,26,25,25,25,23,23,22,21,19,16,13,11,9,8,6,5,5,5,4,5,5,6,7,7,7,7,8,7,7,8,9,8,9,10,11,11,12,11,12,13,11,12,13,13,12,13,14,13,13,14,13,13,15,15,14,14,13,14,14,13,13,13,13,12,12,13,12,12,13,12,12,14,13,13,12,14,13,12,14,13,12,14,13,14,13,15,14,14,13,13,14,14,12,12,13,12,12,11,12,11,11,11,12,11,12,11,11,11,11,10,10,11,11,9,10,11,11,10,10,11,11,10,11,11,11,11,11,11,12,11,12,12,12,12,12,12,12,12,13,11,13,13,13,14,14,14,14,15,15,13,14,14,14,14,13,13,13,12,13,13,12,13,13,11,11,12,11,11,10,12,10,9,10,9,10,8,9,9,7,7,8,8,9,9,10,10,10,10,9,9,9,10,9,9,10,9,8,9,9,9,9,9,11,11,11,12,11,10,11,9,10,10,10,10,11,10,10,12,11,10,10,11,12,12,12,12,12,11,11,11,10,9,8,9,10,8,8,10,8,7,8,8,7,8,9,7,7,7,5,5,5,5,5,5,6,6,5,6,6,5,5,6,6,5,5,4,5,3,3,2,3,2,3,4,1,2,4,4,4,4,4,5,7,8,9,12,14,17,17,17,16,17,17,16,18,17,18,19,20,21,21,21,23,23,24,22,24,23,21,23,20,20,22,23,22,22,23,24,26,26,27,26,27,28,28,27,28,28,28,28,28,28,27,28,28,28,27,27,26,27,27,26,27,24,27,26,25,26,24,24,26,24,24,24,22,22,22,19,20,18,17,15,13,11,9,8,7,4,2,1,2,0,1,2,2,3,4,4,5,4,4,5,5,4,5,5,6,6,7,7,6,7,8,8,8,7,7,7,7,6,5,5,6,6,6,7,6,7,5,6,5,5,5,4,4,4,4,4,3,3,3,3,3,4,5,5,6,5,6,7,6,6,7,7,7,7,7,8,8,9,11,11,11,11,10,10,9,9,9,8,9,7,9,7,8,8,9,8,9,9,10,10,10,9,10,9,9,9,9,9,9,10,10,8,9,10,10,10,10,10,9,10,10,10,12,12,12,12,12,11,11,11,11,13,10,11,12,12,12,12,13,12,13,14,12,12,12,12,12,12,11,11,11,10,11,9,9,9,8,7,9,9,8,7,8,9,7,7,8,7,6,6,7,6,6,6,7,7,7,7,7,7,7,7,7,6,7,7,7,7,8,7,7,8,9,7,8,7,8,8,7,7,7,7,7,7,7,7,6,6,7,7,7,7,8,8,9,9,10,9,10,11,10,10,11,10,12,11,11,11,11,12,12,11,13,12,12,12,12,11,12,11,10,9,8,7,7,7,7,6,7,7,6,6,7,6,5,6,5,6,6,6,6,6,6,6,6,4,5,6,5,7,6,6,7,7,7,6,7,7,7,7,6,7,7,6,5,6,6,5,5,6,5,5,3,4,5,4,3,5,5,4,3,5,5,4,6,5,6,5,5,6,6,6,6,6,6,5,6,6,7,5,5,4,4,3,3,3,3,3,2,2,3,4,3,4,4,4,4,5,5,7,6,6,7,7,7,7,8,8,8,7,8,7,7,7,8,7,8,8,8,8,9,8,8,8,9,9,8,8,9,10,12,13,13,13,14,14,14,14,15,17,17,17,20,19,24,22,23,20,22,23,21,25,22,24,27,24,26,26,26,26,26,26,28,27,26,26,27,26,25,23,25,27,27,24,26,26,25,27,26,24,23,25,23],[28,28,28,28,28,28,28,28,28,27,26,26,27,26,26,26,26,27,25,26,26,26,26,26,26,26,27,26,26,26,26,27,27,28,26,27,27,27,27,27,27,26,26,27,27,26,25,25,24,24,24,24,23,22,21,22,21,21,20,18,16,15,12,10,8,7,7,6,6,6,5,5,5,5,6,7,6,8,8,8,7,8,10,8,9,10,10,10,10,11,11,11,11,12,12,12,11,11,13,12,13,13,13,12,13,14,14,14,13,14,14,12,11,12,12,12,11,11,12,12,12,11,11,12,12,12,11,13,12,11,13,12,11,12,12,13,13,13,13,13,14,12,13,12,12,12,12,11,10,12,12,10,11,10,10,11,11,11,10,10,10,10,9,10,10,10,10,10,10,10,10,10,10,10,11,10,10,10,10,10,10,10,11,11,10,10,11,11,11,10,11,10,11,12,11,12,13,12,12,13,13,12,12,12,12,12,11,11,11,12,11,11,11,11,12,11,11,11,11,10,9,10,10,9,9,9,8,8,9,8,8,7,8,8,8,9,10,9,10,9,9,9,9,10,10,8,8,9,9,8,8,9,8,9,9,10,11,10,10,9,9,9,8,9,9,9,8,9,9,9,10,9,10,10,10,9,10,10,10,10,10,9,9,9,8,9,8,8,7,8,8,8,7,7,7,8,8,7,6,6,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,3,4,4,4,3,3,4,4,3,3,3,4,3,3,4,6,6,8,11,12,12,14,15,15,16,16,15,15,14,16,16,16,17,18,20,19,20,22,21,22,20,23,21,19,21,20,18,20,21,20,19,21,22,24,24,25,24,25,26,26,26,26,26,26,26,26,26,26,26,26,26,25,26,24,25,25,24,25,23,25,24,23,24,22,22,24,23,22,23,22,21,21,20,20,19,17,15,14,12,11,9,6,5,3,2,1,1,0,1,1,2,2,3,3,3,3,4,4,3,5,5,4,5,6,6,6,6,7,7,7,6,6,5,5,5,4,4,6,5,6,7,5,6,5,4,4,5,5,4,3,4,3,3,3,3,2,2,3,3,4,4,4,4,5,5,5,5,5,7,6,7,7,7,7,8,9,9,9,10,9,8,8,8,8,8,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7,8,8,8,8,8,8,7,8,8,8,7,8,8,8,9,10,10,10,10,9,9,9,10,10,10,10,10,11,12,12,11,12,12,12,11,11,12,10,10,10,11,11,10,9,10,9,9,9,9,8,8,8,9,8,7,7,8,7,7,7,7,6,6,7,6,6,6,7,6,6,6,6,6,7,7,7,6,7,8,7,7,7,8,7,8,8,7,8,6,8,7,7,7,7,8,7,7,7,7,7,6,7,8,7,7,8,8,8,9,9,9,10,10,10,11,11,11,11,11,11,11,11,11,11,12,13,11,11,11,10,12,11,10,10,9,8,7,7,7,7,6,7,7,6,6,7,6,6,6,6,6,6,6,6,5,5,6,5,4,4,5,4,5,6,5,6,7,6,6,7,7,6,6,6,6,7,6,6,6,6,5,6,6,5,5,3,3,5,4,4,4,5,4,4,5,6,4,4,5,5,4,6,6,6,6,6,6,5,6,5,6,6,5,5,5,4,4,4,3,3,2,3,2,2,2,2,3,3,3,3,4,4,5,5,6,6,7,6,7,7,8,7,6,7,6,6,6,7,6,6,7,7,7,8,8,7,8,8,8,8,9,9,9,10,10,12,11,12,12,12,13,12,14,14,16,17,18,21,20,19,18,20,20,18,21,19,21,22,21,23,23,24,23,22,23,25,25,23,24,23,23,23,21,23,24,23,20,23,21,20,23,22,20,20,22,20],[29,29,28,29,29,29,29,28,28,27,27,26,28,27,27,27,27,27,27,28,27,26,28,28,27,27,28,27,28,29,27,28,29,29,27,29,28,28,29,29,29,28,27,28,28,27,27,26,26,25,25,24,24,23,23,22,21,22,20,18,16,14,11,9,8,7,6,6,6,6,5,5,5,6,7,6,6,7,8,8,8,9,9,8,9,9,10,10,10,11,11,11,11,11,12,12,11,12,13,13,13,14,14,13,14,15,15,15,14,15,15,14,12,12,12,12,12,12,12,11,13,11,11,12,13,11,11,13,12,11,12,12,11,12,13,13,13,12,13,13,12,12,13,12,11,12,12,11,10,11,11,10,11,10,11,11,11,11,11,10,10,10,9,10,10,10,9,10,10,10,10,10,10,10,10,10,9,9,10,9,10,9,9,10,10,9,10,10,9,9,10,10,10,10,11,12,13,12,11,12,13,12,12,12,13,12,12,11,10,11,11,11,10,11,11,9,10,10,9,9,9,10,9,8,9,9,8,8,8,8,7,7,7,8,8,9,9,9,9,9,9,8,8,10,9,8,8,9,7,8,8,8,7,8,8,9,9,9,8,8,8,8,7,7,8,8,7,8,9,8,8,9,9,8,8,8,9,10,9,9,9,9,8,8,8,8,7,8,7,7,6,7,7,6,6,7,7,6,6,6,5,5,5,5,5,4,5,4,4,5,4,4,4,5,4,4,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,5,5,7,7,10,11,12,15,17,16,17,15,16,16,16,18,17,17,17,18,19,20,21,23,21,23,21,24,22,20,24,21,19,21,22,22,20,23,24,24,25,25,25,26,27,27,27,27,27,27,27,27,27,27,28,27,27,26,26,26,26,26,25,27,23,26,25,25,26,25,24,26,23,24,25,24,23,24,22,22,21,18,17,15,12,10,10,7,5,3,2,2,1,1,0,1,1,2,2,3,2,2,3,3,3,4,4,5,4,4,5,5,5,6,6,6,5,5,5,5,4,4,4,5,4,6,6,4,5,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,3,3,4,3,4,4,4,4,5,5,5,5,5,6,6,7,7,8,8,8,8,8,6,7,6,7,7,6,7,6,6,7,7,6,7,7,7,6,7,7,6,6,7,7,6,6,7,6,6,7,7,6,7,8,8,7,7,7,8,9,9,9,9,9,8,8,8,9,9,10,9,9,10,11,12,11,12,11,12,11,11,11,11,10,10,10,10,9,9,9,9,8,9,8,8,7,8,7,7,6,6,6,5,6,6,5,5,6,6,5,5,5,5,4,4,5,5,4,5,6,5,5,6,6,5,5,5,5,5,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,6,7,7,8,8,9,9,10,10,10,10,10,10,11,12,11,11,11,10,12,10,11,12,11,11,11,11,10,10,10,9,9,8,7,7,6,7,6,6,7,6,6,6,5,5,5,6,4,5,5,4,5,4,5,4,4,4,4,4,5,4,4,5,5,5,6,6,6,6,5,6,6,6,5,6,5,6,5,5,5,5,5,4,5,4,4,3,4,5,4,4,5,4,4,4,5,4,4,5,5,6,5,5,5,4,5,5,5,5,5,6,4,4,5,3,3,3,3,3,1,2,2,2,3,4,4,3,4,4,5,5,5,6,6,6,6,6,7,6,6,6,5,5,5,5,5,5,5,5,5,6,6,6,5,7,7,6,6,7,7,9,10,10,10,11,13,11,11,13,14,14,16,16,18,20,20,20,17,19,20,19,23,19,22,22,21,25,24,22,23,24,23,24,25,23,22,22,24,23,19,21,24,24,20,23,22,22,22,22,20,21,22,19],[29,29,29,29,29,29,29,29,29,28,28,27,28,27,28,27,27,28,26,28,28,27,28,28,27,28,28,28,28,28,27,28,29,29,27,29,28,28,29,28,28,28,28,28,28,27,26,25,27,25,25,25,25,24,22,23,21,21,21,20,17,15,12,10,9,7,7,7,7,6,6,6,6,6,8,8,7,8,8,8,9,8,8,8,8,10,10,11,10,10,10,11,10,11,11,10,10,11,12,11,11,12,12,12,13,13,12,13,12,13,13,12,11,11,12,12,11,12,12,11,11,11,11,12,11,11,11,12,10,11,12,11,10,12,11,13,11,12,11,11,12,10,11,11,10,10,11,10,10,10,10,10,10,10,11,10,11,11,11,11,11,10,10,9,9,10,10,9,10,10,10,9,10,9,10,9,10,9,9,10,10,10,10,10,9,10,10,9,10,10,9,9,10,10,10,11,11,11,11,12,11,11,11,12,11,11,11,11,11,11,11,10,10,10,10,9,10,9,9,9,8,9,9,9,8,8,9,8,8,8,8,8,8,8,9,9,8,9,9,9,8,9,9,9,9,8,8,8,9,8,7,8,8,8,8,9,9,9,8,8,9,8,9,8,8,8,8,7,8,8,8,8,8,8,9,8,8,9,9,9,9,8,7,8,7,8,8,8,7,8,7,7,8,7,7,8,9,6,6,6,6,5,5,5,4,5,5,5,4,5,4,4,5,6,4,4,3,3,3,3,3,3,4,3,4,4,3,4,5,5,4,5,6,7,8,12,13,13,15,16,16,16,17,17,16,16,17,17,18,17,20,21,21,20,23,22,23,21,24,21,19,21,20,20,20,22,23,21,22,24,24,26,27,25,26,27,26,26,27,27,27,27,27,27,26,27,26,26,25,26,26,26,26,25,26,24,25,25,25,26,24,24,25,24,21,23,25,21,22,22,21,21,20,17,16,14,11,9,8,6,4,2,3,2,1,1,0,1,1,2,2,2,2,2,2,2,3,4,3,4,4,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,5,5,5,5,5,4,4,4,3,3,2,3,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,5,5,5,5,5,5,6,7,7,7,8,8,7,7,6,7,7,7,7,6,8,6,6,8,7,7,7,7,7,7,7,7,7,7,7,8,7,7,7,8,8,7,7,8,7,8,8,8,7,8,8,8,10,10,9,9,9,9,8,9,9,10,8,10,10,11,11,11,10,11,12,11,10,11,10,10,9,10,9,9,9,8,9,8,8,7,7,8,8,7,8,8,8,7,6,7,6,6,5,5,5,5,5,5,5,5,4,5,5,4,5,6,5,6,6,6,6,6,6,6,7,6,7,5,7,6,6,7,7,6,6,7,7,6,6,6,7,7,7,8,8,7,8,8,8,9,9,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,12,12,11,11,11,10,10,10,10,9,8,8,7,8,7,7,7,7,7,6,7,6,6,5,5,6,6,5,5,5,5,5,4,5,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,7,5,6,6,6,5,6,6,6,5,5,4,4,5,3,4,5,4,5,4,4,4,3,4,4,4,5,5,5,6,5,5,5,5,5,5,5,4,5,4,4,4,3,3,3,3,3,1,2,1,2,2,3,3,3,4,4,4,5,5,7,6,6,6,6,7,6,5,6,5,5,5,6,5,5,6,5,5,5,5,6,5,6,6,6,7,7,7,8,9,10,10,11,11,11,12,11,13,14,15,17,17,20,19,19,17,18,18,18,22,19,21,22,22,26,25,24,24,24,23,26,25,24,23,23,24,22,20,21,24,24,20,23,22,22,24,23,20,20,23,20],[29,29,28,28,28,29,28,28,28,27,27,26,27,26,26,26,27,26,26,27,26,26,27,27,26,26,27,26,27,27,26,27,28,28,27,28,27,27,28,27,28,27,27,27,27,27,26,25,26,25,25,24,24,23,22,22,20,21,20,19,16,15,12,9,8,7,6,6,6,6,5,5,5,5,7,6,6,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,10,11,11,10,10,11,12,11,12,12,12,12,13,13,13,13,13,14,14,13,12,13,12,13,11,12,10,11,12,10,10,11,12,11,10,12,11,11,11,11,10,10,11,12,11,11,11,11,10,10,11,11,10,11,11,10,9,11,10,9,10,9,10,10,11,11,10,11,9,9,9,9,9,9,8,10,10,9,8,9,9,9,9,9,9,8,9,8,8,9,8,9,8,8,8,9,9,8,9,9,9,8,9,10,11,10,10,11,11,11,11,10,10,10,10,10,10,10,10,10,9,10,10,9,9,9,8,8,8,8,8,8,8,8,8,8,7,7,7,7,8,7,8,8,8,8,8,9,9,8,7,8,8,7,7,7,7,7,7,7,7,7,7,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,9,8,8,8,7,7,7,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,6,6,7,10,10,10,14,16,15,15,16,16,16,16,18,17,17,18,19,21,21,22,23,22,23,21,24,21,20,22,21,19,20,22,21,20,22,24,24,25,26,25,26,27,27,27,26,27,27,27,27,27,26,27,27,27,26,26,26,26,26,26,26,25,25,26,25,25,24,25,26,23,22,23,24,21,22,22,21,21,20,19,16,14,13,11,8,6,4,3,3,2,2,1,1,0,1,1,1,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,2,1,2,2,1,1,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,6,5,6,7,7,7,6,6,6,5,6,6,5,6,6,6,6,6,6,6,7,7,7,6,6,6,5,6,6,6,6,7,6,6,6,7,6,7,7,7,7,7,7,8,8,9,9,9,9,8,8,8,8,8,9,8,9,9,10,11,11,10,11,11,10,11,10,10,10,10,10,9,9,9,9,8,8,8,7,7,7,7,7,6,6,7,6,6,5,6,5,4,5,5,5,4,4,5,5,4,4,4,4,4,5,5,4,5,5,5,5,5,6,5,5,6,6,6,5,5,6,5,5,6,6,5,6,6,6,6,6,7,7,6,7,7,7,8,8,9,9,10,9,9,9,9,9,10,10,10,10,11,11,11,11,12,11,11,11,11,10,10,9,9,9,8,7,7,7,7,6,7,6,5,6,6,5,5,5,6,4,4,5,4,4,4,4,5,3,3,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,6,5,5,5,5,5,5,6,5,5,4,4,5,4,3,4,4,4,3,4,4,3,3,4,4,4,4,4,5,5,5,5,4,5,5,5,5,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,3,3,3,3,4,4,5,4,6,6,5,6,6,7,6,5,5,5,5,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,7,6,7,8,9,8,9,11,10,10,11,12,12,14,14,15,18,19,19,16,18,18,17,21,18,22,20,20,24,22,21,23,23,21,23,23,22,22,21,22,21,18,21,22,22,18,22,20,19,21,21,18,18,20,17],[29,29,29,29,29,29,29,29,28,28,28,28,28,28,28,27,28,28,28,28,29,28,28,29,28,28,29,29,28,29,28,29,29,29,28,29,29,28,29,29,29,28,28,28,28,28,27,26,27,26,25,26,26,25,24,24,22,21,20,21,18,15,13,11,9,8,7,8,7,7,6,6,7,6,8,8,7,8,10,9,8,9,10,9,9,11,10,11,11,11,12,12,11,12,12,12,11,12,13,13,13,13,14,12,14,14,14,13,13,14,14,14,12,13,12,13,13,13,12,12,13,11,11,12,13,11,11,12,11,11,12,11,10,12,11,13,12,12,12,12,11,11,12,12,10,11,12,11,10,11,11,10,10,10,11,11,12,12,12,11,10,10,11,11,11,9,10,10,10,9,10,10,10,10,10,10,9,9,10,10,10,9,9,10,10,9,10,10,9,10,10,9,10,10,10,11,11,11,11,11,11,11,11,12,11,12,12,11,10,11,11,11,10,11,11,10,10,10,10,9,9,10,9,8,9,9,8,8,9,8,7,7,8,8,9,9,9,9,9,9,9,9,8,9,8,8,8,8,8,8,8,8,8,8,8,9,9,9,8,8,8,8,8,8,8,8,8,8,8,9,8,8,8,8,8,9,9,10,9,10,9,9,9,8,8,8,8,8,7,8,7,7,7,7,7,7,8,6,6,6,5,5,6,5,5,5,5,4,5,5,4,4,5,5,4,4,3,3,4,3,3,4,4,4,5,5,4,4,5,5,5,6,7,7,8,10,11,11,13,15,16,15,15,16,18,17,19,20,19,20,21,24,22,23,24,24,24,23,24,21,21,23,21,20,20,21,23,22,23,24,24,25,26,26,26,27,27,27,27,27,27,27,28,27,27,28,27,27,26,27,26,26,27,26,26,25,25,26,24,26,25,24,24,24,23,24,24,23,22,23,20,21,20,19,17,15,15,12,9,6,4,3,4,2,2,2,1,1,0,1,2,1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,4,4,4,4,5,5,5,6,6,7,8,7,7,7,6,7,6,6,6,6,7,6,6,7,7,7,7,7,8,7,7,7,7,7,7,8,7,8,7,8,8,7,7,8,8,8,8,8,8,8,8,9,10,10,10,10,9,9,9,9,9,10,10,10,11,11,12,12,12,11,13,12,12,12,12,11,11,11,10,10,10,9,10,8,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,5,4,5,5,4,5,5,5,4,4,5,4,4,5,6,5,5,6,7,7,6,7,7,7,7,6,7,7,6,6,7,7,7,7,7,7,7,8,7,7,8,8,9,9,9,11,10,11,11,10,11,10,11,12,11,11,12,12,12,12,12,12,13,12,13,11,11,11,11,10,10,9,9,8,8,8,7,8,7,7,7,7,6,6,6,6,6,5,6,5,5,4,4,4,4,4,4,4,5,4,5,6,6,7,6,6,6,6,7,6,6,7,6,5,6,6,5,6,7,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,4,4,4,4,4,4,4,3,2,2,2,2,3,3,3,3,4,4,5,5,6,6,6,6,6,6,7,6,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,6,6,6,6,6,6,8,8,9,9,9,11,10,10,11,12,13,14,17,17,19,19,18,17,19,19,17,22,19,21,22,21,25,23,24,24,23,24,25,24,23,22,23,24,22,20,20,24,23,19,23,21,21,23,22,18,19,22,18],[28,28,28,28,28,28,28,28,28,27,27,26,27,26,27,26,27,26,27,27,27,27,27,28,27,27,28,28,27,27,27,27,28,28,27,28,27,28,28,28,28,28,27,27,27,27,26,25,26,25,25,24,24,23,23,23,22,22,20,20,18,16,14,11,10,9,7,8,7,7,6,6,6,6,7,7,7,8,9,8,7,8,9,8,8,9,9,10,10,10,11,11,11,11,11,11,11,11,12,12,12,13,12,12,13,13,13,13,13,13,14,13,12,12,12,12,11,11,10,11,11,10,10,11,11,11,10,12,11,10,11,11,10,11,11,12,12,11,12,11,12,10,12,11,11,11,12,10,10,11,11,9,10,9,10,10,11,11,10,11,10,9,9,9,9,9,9,10,9,8,9,9,9,9,10,10,9,9,9,9,9,9,9,10,9,8,9,10,9,8,10,9,9,9,10,11,11,11,10,11,11,11,11,11,11,11,11,10,10,10,11,10,9,11,10,9,10,10,9,8,8,9,9,8,8,9,7,7,8,8,7,7,8,8,9,9,8,9,8,9,9,8,8,8,8,7,7,8,7,7,7,7,7,7,8,8,9,8,8,7,7,7,7,7,8,7,6,7,8,7,7,8,8,7,8,8,8,9,9,9,8,8,8,8,8,8,7,7,7,7,6,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,5,4,4,4,4,3,4,5,4,3,3,3,3,3,4,4,4,4,4,5,4,5,5,5,5,6,7,7,9,10,11,12,14,15,17,15,15,17,17,17,19,19,18,18,20,21,21,21,23,22,24,21,23,20,19,20,19,18,19,20,20,20,21,22,24,23,25,23,26,25,25,26,25,26,26,26,26,26,26,26,25,26,24,25,24,24,26,24,25,24,23,24,23,25,24,23,25,24,23,24,24,23,22,23,20,20,19,18,17,16,13,13,9,7,5,4,4,3,3,2,1,1,1,0,1,1,1,1,1,2,2,2,2,3,2,3,3,3,3,3,4,3,3,4,4,3,2,3,3,3,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,3,5,4,5,6,6,8,7,7,7,7,6,6,5,6,6,6,6,6,5,6,6,6,7,6,6,7,7,7,7,6,6,6,6,7,7,7,6,7,7,7,7,8,7,7,7,7,8,8,10,9,9,9,8,8,8,8,9,9,9,9,10,11,11,12,12,11,12,12,11,12,11,11,11,11,10,9,10,9,9,8,8,8,8,7,8,8,6,7,7,7,6,6,6,5,5,5,5,5,4,5,5,4,4,4,5,4,4,5,5,5,5,6,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,7,6,7,7,7,7,8,8,8,8,9,10,9,11,10,9,10,9,10,11,11,11,11,12,12,12,13,13,13,12,12,12,11,11,10,10,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,6,5,4,5,5,4,4,4,4,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,5,6,6,5,6,6,6,5,6,6,6,6,5,5,6,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,6,6,6,5,5,6,5,5,5,5,5,5,5,4,4,4,4,3,3,3,2,2,3,3,3,3,4,4,5,5,5,6,6,5,6,6,6,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,5,6,7,7,8,9,9,9,10,10,10,11,12,13,14,16,17,19,20,18,17,20,20,18,22,19,20,22,19,23,23,22,23,24,23,23,24,23,21,23,23,22,20,21,23,23,20,22,19,21,21,22,19,18,21,20],[28,28,28,28,29,28,29,28,28,28,27,27,27,26,26,27,27,27,27,27,28,26,28,28,27,28,28,27,28,28,27,28,29,29,28,29,27,28,28,28,28,27,27,28,28,27,27,25,26,25,24,25,24,23,21,22,21,20,19,20,17,14,13,11,10,9,8,9,8,8,7,7,7,6,8,8,8,9,9,9,9,9,9,9,10,11,10,11,11,12,11,12,12,12,12,12,12,12,13,13,13,14,14,13,14,15,14,14,14,15,15,15,13,14,13,14,13,13,12,12,12,12,11,12,13,12,11,13,12,10,12,12,11,11,11,12,12,11,11,12,11,11,12,12,10,12,12,11,11,13,12,10,11,10,11,12,12,12,12,12,12,11,11,11,11,10,10,11,10,9,10,10,9,10,11,10,9,9,10,9,10,9,8,10,10,9,9,10,10,9,10,10,9,10,10,11,11,11,11,11,11,11,11,12,11,12,11,11,11,11,11,11,10,12,11,10,10,10,10,9,9,10,9,9,9,9,8,9,9,8,7,8,8,9,9,9,9,9,9,9,9,8,8,9,8,7,8,8,7,7,8,8,7,7,7,8,9,9,7,7,7,8,8,7,8,8,8,7,9,8,8,8,9,8,8,9,9,9,9,10,9,10,9,9,9,8,8,8,8,8,7,7,7,7,7,7,7,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,4,3,4,4,5,5,5,5,5,6,6,6,6,7,7,8,9,11,11,12,13,15,16,14,15,16,17,16,16,18,18,18,19,21,21,22,22,22,23,21,22,21,19,20,20,19,19,21,22,21,21,23,23,25,26,25,26,26,25,26,27,26,26,26,26,26,26,27,26,26,25,26,25,25,26,24,26,24,25,25,24,25,24,23,25,23,23,24,24,22,22,22,20,21,19,17,16,14,13,12,10,7,6,5,5,4,3,3,2,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,3,3,4,3,4,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,4,4,5,5,5,6,6,7,7,7,7,7,6,6,5,6,6,5,6,6,5,6,7,6,6,6,7,6,7,7,7,7,7,7,7,7,7,8,7,7,8,8,8,8,8,7,8,8,8,9,10,10,10,10,9,9,9,9,10,10,10,11,11,12,12,12,12,12,13,13,12,12,12,11,11,11,11,10,10,10,10,9,9,9,8,9,9,8,8,8,7,7,7,7,7,6,6,6,6,5,5,5,5,4,5,5,5,4,4,5,5,4,5,6,6,5,6,6,6,5,7,6,7,6,6,7,7,6,7,8,8,7,7,7,8,8,8,8,7,9,8,9,9,9,11,11,11,11,11,11,12,12,12,12,12,13,13,13,13,14,13,14,12,13,12,12,12,11,11,10,10,9,9,9,8,8,8,7,8,7,7,8,7,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,5,6,6,6,6,6,6,7,6,6,6,7,6,6,7,7,7,7,7,7,6,6,6,6,6,5,5,6,5,5,5,5,5,4,5,5,5,4,5,5,5,6,5,5,5,6,6,6,6,6,5,5,6,5,5,5,5,4,3,3,3,2,3,3,3,4,5,4,5,5,5,6,6,5,6,5,7,6,5,6,4,4,4,6,4,5,5,6,4,5,5,5,6,5,6,6,6,6,6,7,8,9,8,9,10,10,10,10,12,12,14,16,16,20,20,17,17,20,19,17,21,19,20,21,21,25,24,22,22,24,23,25,24,24,22,23,23,22,20,20,23,22,18,22,20,20,22,22,18,18,21,19],[29,29,29,29,29,29,29,29,28,28,28,27,28,27,27,27,28,28,28,28,28,27,28,28,27,28,28,27,28,28,27,28,29,29,28,28,28,28,29,28,29,28,28,28,28,28,27,25,26,26,25,24,24,23,23,22,21,21,20,18,16,15,12,10,9,8,8,8,7,8,7,6,7,6,7,7,8,8,9,9,8,8,9,8,8,10,9,10,11,10,11,12,11,11,12,11,11,11,13,12,12,13,13,13,13,14,14,14,14,14,14,14,13,13,12,13,12,13,12,12,13,12,11,12,12,11,10,13,12,11,12,12,11,11,11,12,12,12,12,12,12,11,12,12,11,11,11,11,10,11,11,10,11,10,10,11,12,12,11,11,10,10,10,10,10,8,9,10,10,9,10,10,9,9,10,10,8,9,10,9,10,8,8,9,9,8,9,10,8,8,9,10,8,9,9,10,11,11,10,10,10,11,10,11,11,11,11,10,10,10,11,10,9,10,10,9,10,10,10,8,9,10,9,8,8,9,7,7,8,8,7,7,8,8,9,9,9,9,8,8,9,8,8,8,8,7,7,8,7,7,7,7,6,6,7,8,8,8,7,6,6,7,7,6,7,7,6,7,8,7,7,8,8,7,7,8,9,8,8,9,8,9,8,8,8,7,7,7,7,7,6,7,6,6,6,6,6,5,6,6,5,5,5,4,4,5,4,3,4,4,4,3,4,4,3,4,3,4,4,3,4,4,4,4,5,5,5,5,6,6,5,6,7,7,8,10,11,10,13,14,14,15,14,17,16,16,18,18,17,18,20,21,21,21,22,22,24,22,25,21,21,22,20,19,19,20,21,19,21,22,23,23,27,25,26,25,26,26,27,27,26,26,27,26,26,27,27,26,26,26,26,26,26,25,26,25,26,26,25,26,25,25,26,25,24,26,25,23,23,23,22,21,20,18,17,15,14,12,9,7,5,4,4,3,3,2,2,2,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,3,2,2,2,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,6,6,6,7,7,7,6,5,6,5,6,5,5,6,5,5,6,6,5,6,6,6,5,6,6,6,5,6,6,6,6,6,6,6,6,7,7,6,7,7,6,7,7,8,9,9,10,9,9,8,8,9,8,9,9,9,10,10,11,10,11,11,11,11,11,12,11,11,10,10,11,10,10,9,9,9,8,8,8,8,7,8,7,7,7,6,6,6,6,6,5,5,6,5,4,4,5,5,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,6,5,5,6,6,5,6,7,7,7,7,7,7,7,8,7,8,8,8,9,9,9,10,9,11,11,10,10,10,10,12,11,11,12,11,11,11,11,11,11,11,11,10,11,11,10,10,10,9,9,8,9,8,7,8,7,7,7,7,7,6,6,6,5,5,5,5,4,4,4,4,3,3,3,4,4,5,5,4,5,5,5,5,5,5,6,5,6,6,6,5,6,7,5,6,6,7,6,5,5,6,5,4,5,5,5,4,5,5,4,4,5,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,2,3,3,3,3,4,4,4,5,5,5,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,7,8,8,8,9,10,10,10,11,12,13,15,16,17,20,19,19,17,20,19,19,22,19,22,22,21,24,23,22,24,23,23,24,25,24,23,23,24,22,20,22,24,24,20,22,21,20,22,22,18,20,22,19],[29,29,29,29,29,29,29,29,28,28,28,27,28,27,27,27,27,27,27,27,27,27,27,28,27,27,28,27,27,28,26,28,28,29,27,28,28,28,28,28,29,28,27,28,28,28,27,25,26,25,25,24,24,23,23,23,21,21,20,19,17,16,13,10,10,8,8,8,7,7,6,5,6,5,7,7,7,8,8,8,8,8,8,8,8,9,9,10,10,11,11,11,11,12,11,11,11,12,12,12,12,12,12,12,13,14,13,14,14,14,14,14,13,14,13,12,12,11,10,11,13,11,10,11,12,11,10,12,12,11,11,12,11,11,11,12,11,12,11,12,12,10,12,11,11,11,12,11,10,11,11,9,11,10,11,11,12,12,12,11,10,10,10,10,10,8,9,11,9,8,9,10,9,8,10,10,8,9,10,9,10,8,8,9,9,8,8,9,9,8,9,9,8,9,9,10,11,11,10,10,11,10,10,11,11,10,10,10,10,11,11,10,9,10,10,9,10,10,9,8,9,10,8,8,8,8,7,7,7,8,7,7,7,8,9,9,8,9,8,9,9,9,8,8,8,8,7,7,7,7,7,7,6,7,7,8,8,8,7,7,7,7,6,6,7,7,6,7,7,7,7,7,7,7,7,7,8,9,8,9,8,8,8,7,7,7,6,7,7,6,5,6,6,6,6,6,6,5,5,5,4,5,5,4,4,5,4,3,4,4,4,3,4,4,4,3,3,3,3,3,4,4,4,4,5,5,4,4,5,5,5,6,7,6,7,9,11,11,13,16,16,14,15,17,17,17,19,19,18,19,20,22,23,22,23,23,24,23,24,21,21,22,20,20,20,22,21,21,22,23,24,23,26,25,25,26,26,26,27,26,26,27,27,27,27,27,27,27,26,27,26,27,27,26,27,25,26,27,25,26,26,25,27,25,24,25,25,23,24,24,22,22,21,19,18,16,14,13,9,7,5,4,4,3,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,2,2,2,3,3,3,3,3,3,3,3,4,4,4,5,5,5,6,6,7,7,7,7,6,6,6,6,6,5,5,5,5,5,6,6,5,6,6,6,5,6,6,6,5,5,6,5,6,6,6,5,6,7,6,6,7,6,6,7,7,7,8,9,9,9,8,8,8,8,8,9,9,9,9,10,11,12,11,11,11,12,12,10,11,11,10,9,11,10,9,9,9,8,7,8,8,8,7,7,7,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,3,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,7,7,8,8,8,10,9,11,10,9,10,10,9,11,11,11,12,12,12,11,13,13,12,11,11,11,11,10,10,10,9,9,8,8,7,7,7,6,6,6,6,6,5,5,5,5,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,5,4,5,5,5,5,5,4,5,5,4,5,6,5,5,6,6,6,5,5,5,5,5,4,4,5,4,3,4,4,3,4,4,4,4,4,5,5,5,5,5,4,5,5,5,5,5,4,4,4,4,4,3,4,4,3,2,2,2,2,2,3,3,3,4,4,4,5,5,6,6,5,6,5,6,5,5,5,5,5,4,5,5,4,5,5,5,4,5,5,5,5,6,6,5,6,6,7,8,9,9,10,11,10,11,11,12,13,14,15,17,19,20,18,18,20,19,19,23,20,22,22,21,24,24,23,24,24,23,24,24,24,23,23,23,23,20,22,23,23,20,22,21,20,21,22,20,20,21,19],[29,29,28,29,29,29,29,29,28,28,28,27,28,27,27,27,28,27,27,28,27,27,28,28,27,28,28,28,28,28,27,28,29,29,29,29,28,29,29,29,29,28,28,28,28,28,27,26,27,26,26,25,25,25,22,24,22,22,21,20,18,16,14,11,11,9,8,8,7,8,7,7,7,6,7,8,8,8,9,9,9,9,10,10,10,11,11,12,12,13,13,13,14,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,14,16,14,14,14,12,12,12,13,12,12,12,14,12,11,14,13,11,12,13,12,12,12,13,12,13,13,13,14,13,14,13,13,13,13,12,12,13,13,11,12,12,12,13,13,13,13,12,12,12,11,11,11,10,11,12,11,10,11,11,10,10,11,11,9,10,11,10,11,9,9,10,10,9,10,10,9,9,10,11,9,10,10,11,12,12,10,12,12,11,11,13,12,12,12,11,11,11,13,11,10,12,11,10,11,11,10,9,10,10,10,9,10,10,9,9,9,8,7,8,8,9,9,10,9,9,9,9,9,9,8,9,9,8,8,8,7,8,8,8,8,7,8,8,9,9,8,7,7,8,7,7,8,8,7,8,8,8,8,8,9,8,8,9,9,10,9,10,9,9,9,9,9,8,8,8,7,8,7,7,7,7,7,7,6,7,6,6,6,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,3,3,4,3,4,4,4,4,5,5,5,5,6,5,6,7,8,8,9,11,12,12,14,15,16,15,15,17,17,17,17,19,19,18,20,21,23,22,23,23,24,21,23,21,20,22,20,19,19,20,21,20,21,23,23,22,25,24,25,25,26,26,26,27,26,27,27,27,26,27,27,26,26,26,25,26,26,24,26,23,25,26,24,25,25,25,26,25,23,25,25,23,22,24,22,21,20,18,18,15,13,13,8,6,5,4,4,3,3,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,2,2,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,6,7,7,7,7,7,6,6,6,6,6,6,6,7,6,6,7,7,7,6,7,7,6,6,7,7,6,7,7,7,7,7,7,7,7,7,7,8,8,8,7,8,9,9,10,10,10,10,9,9,9,9,10,10,10,11,11,12,13,12,13,13,13,13,12,13,12,12,12,12,12,10,11,11,10,9,9,9,9,9,9,8,8,8,7,7,6,6,6,6,5,5,6,5,4,5,5,4,4,5,4,4,5,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,7,7,6,7,7,7,7,7,7,7,8,8,8,9,9,10,9,10,11,11,12,12,11,12,12,12,13,13,12,13,13,14,13,14,14,13,13,13,13,13,12,11,12,11,10,9,8,9,8,8,8,8,8,7,7,7,6,6,6,6,5,6,5,4,4,5,5,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,6,6,5,6,5,5,5,6,5,4,5,5,4,4,4,5,5,5,5,5,6,6,6,6,5,6,6,5,5,5,5,5,5,5,4,4,4,4,3,3,2,2,3,3,3,4,4,4,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,8,10,9,9,11,10,10,11,12,13,15,15,15,18,18,17,17,18,18,18,21,20,19,22,20,22,22,22,22,23,22,23,22,22,22,22,23,22,18,20,22,23,20,23,20,19,22,22,19,19,22,19],[29,28,27,28,29,28,28,28,28,27,27,27,28,27,27,27,28,26,27,28,27,27,28,28,27,28,29,27,28,28,27,29,28,29,28,29,28,29,29,28,29,28,27,28,28,27,27,26,26,25,24,24,24,23,22,22,21,20,19,18,16,15,13,11,10,9,9,8,8,8,7,7,7,7,7,8,8,8,9,9,9,9,9,9,9,11,10,12,12,12,12,13,13,12,13,14,12,13,15,14,14,15,15,15,15,15,15,15,15,15,16,16,14,15,13,14,14,13,12,12,14,12,12,13,14,13,12,14,13,11,12,13,11,12,12,13,13,13,14,14,13,12,14,14,13,14,13,12,12,13,13,11,13,11,12,12,13,13,12,12,11,11,11,11,11,10,11,12,11,11,11,11,10,10,11,11,10,10,11,10,10,9,9,10,10,8,10,11,9,9,11,10,9,10,10,11,12,11,10,11,11,11,11,12,12,12,12,11,11,11,12,12,9,12,11,10,11,11,11,9,10,11,10,9,9,10,8,9,9,9,7,8,8,9,9,9,9,9,8,9,9,8,8,9,9,8,8,8,7,8,8,8,7,7,7,8,9,9,8,7,7,8,7,7,9,8,7,7,9,8,8,9,9,8,8,9,9,9,9,10,9,9,9,9,9,8,8,8,8,7,7,7,7,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,3,4,4,4,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,10,11,12,13,15,15,14,14,17,17,17,18,18,18,18,19,21,22,21,23,22,24,22,24,22,20,21,19,19,19,21,20,19,20,23,22,22,24,25,25,25,25,26,26,27,26,27,27,27,26,26,27,26,25,26,25,26,27,25,26,24,25,26,25,26,25,25,26,25,25,26,25,24,24,24,22,21,20,18,17,15,13,12,9,7,6,4,5,4,4,3,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,2,2,2,3,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,4,4,4,4,4,5,5,6,5,6,7,6,6,6,5,6,5,6,6,6,6,6,6,6,7,6,6,7,7,6,7,7,7,6,7,7,7,7,7,7,7,7,8,7,8,8,8,7,8,8,9,9,10,10,10,10,9,9,9,9,10,10,10,10,11,12,12,12,13,12,12,13,12,12,12,10,12,11,11,10,10,10,10,9,9,9,9,8,9,8,7,8,7,7,7,7,6,6,6,6,6,5,5,5,5,4,4,5,4,4,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,6,6,6,7,6,7,7,8,7,7,7,7,8,8,8,8,9,9,9,9,10,11,11,12,11,11,12,11,12,12,12,12,13,13,13,12,13,13,12,12,12,11,12,11,11,11,10,9,9,8,9,8,8,8,8,7,7,7,7,7,6,6,5,5,6,5,5,5,5,5,4,4,4,4,5,5,5,6,6,6,5,6,6,6,6,5,6,6,6,6,7,7,6,7,7,7,6,6,6,6,6,5,5,6,5,4,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,6,5,6,6,5,5,5,6,5,4,5,5,4,4,3,3,3,3,3,3,4,4,4,5,5,4,7,6,5,6,5,6,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,7,8,9,9,9,10,9,9,10,12,11,14,15,15,18,19,19,15,18,19,18,22,18,22,21,20,24,23,21,24,24,23,23,24,23,21,22,22,21,18,20,22,22,18,21,20,19,21,21,18,19,21,18],[29,29,28,28,29,29,29,28,28,27,27,26,28,26,27,27,27,27,26,27,27,25,27,28,26,27,28,26,27,28,26,27,28,28,26,28,27,27,28,27,28,27,27,27,27,27,26,25,26,25,24,24,23,23,22,22,20,20,19,18,15,15,12,11,9,9,8,8,8,7,7,6,6,6,7,7,8,8,9,8,7,9,9,8,8,10,10,11,11,11,12,13,11,12,12,12,12,12,14,12,13,14,14,13,14,14,14,13,14,15,15,14,14,14,14,14,13,13,11,13,14,12,11,13,13,12,11,14,13,12,12,12,11,11,12,13,13,12,13,13,12,12,13,12,12,12,13,12,11,12,12,10,11,10,12,12,13,13,12,13,11,10,10,11,10,9,10,11,10,9,10,11,9,9,11,11,8,10,10,9,10,9,9,10,10,8,10,10,9,9,10,10,9,9,10,10,12,11,10,11,12,11,10,12,12,11,11,10,11,11,12,11,9,12,11,10,11,11,10,8,10,10,9,8,9,9,7,7,8,7,7,7,8,8,9,9,8,10,8,9,8,8,8,9,8,8,7,8,7,7,7,7,7,7,7,8,9,8,7,7,7,7,6,7,7,7,6,7,8,7,7,8,8,7,8,8,8,9,9,10,8,9,8,8,8,7,7,7,7,7,6,6,7,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,5,4,3,4,4,3,4,3,4,4,4,4,4,4,4,5,5,5,5,6,6,5,6,7,7,8,10,11,11,13,16,15,14,15,16,15,16,18,17,16,17,18,19,20,20,22,22,23,22,23,22,20,22,19,19,19,21,20,19,20,23,21,21,24,23,25,25,25,25,26,26,26,27,27,27,26,27,27,27,25,26,26,26,26,24,26,24,25,26,25,26,25,24,26,25,23,24,24,21,22,22,21,21,19,19,16,14,14,12,9,6,5,4,4,4,3,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,6,6,7,7,7,7,6,6,6,5,6,5,6,6,5,5,6,6,5,6,6,6,5,6,6,5,5,6,6,5,6,6,6,6,6,7,6,7,7,7,7,7,7,8,9,9,9,9,9,8,8,9,8,10,10,9,10,11,11,12,12,12,12,13,12,12,12,12,10,11,11,10,9,9,9,9,8,8,8,8,7,8,8,6,7,6,6,6,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,5,5,5,4,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,8,7,7,8,8,9,8,9,10,10,11,11,9,10,11,10,11,12,11,12,12,12,12,12,13,12,12,12,12,11,11,11,10,10,9,8,9,8,8,7,7,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,4,4,4,4,4,5,5,4,5,5,5,6,5,5,6,5,5,5,6,6,5,6,6,7,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,4,5,5,4,5,5,5,5,5,5,5,5,5,4,4,5,4,4,3,3,3,2,3,3,3,3,3,4,4,4,4,5,6,5,5,5,6,6,5,5,5,4,4,5,4,4,5,5,4,4,5,5,5,5,5,5,5,6,6,7,8,9,9,9,11,11,11,11,12,14,15,16,17,19,19,19,18,20,18,19,22,20,21,22,21,24,24,22,24,24,22,24,24,23,22,22,23,22,20,21,23,23,20,22,20,19,22,21,20,20,21,19],[29,29,29,28,29,29,29,29,29,28,28,27,28,27,28,28,27,27,27,27,27,27,27,27,27,27,27,27,27,28,26,28,28,28,28,28,28,28,28,28,29,28,28,28,28,28,27,26,26,26,25,25,25,24,24,23,21,23,21,19,17,16,14,11,11,9,8,8,8,8,7,7,7,7,8,8,9,9,11,9,10,11,11,10,11,12,12,13,14,14,14,15,15,14,15,15,15,15,16,16,15,15,15,16,16,16,16,16,16,16,16,17,16,17,15,16,15,15,14,14,15,14,13,14,16,15,13,15,15,13,14,15,13,14,13,14,13,14,14,15,15,14,15,16,15,14,15,15,13,15,15,13,13,13,14,14,15,16,15,14,14,13,13,14,12,10,12,13,12,10,12,13,11,11,13,12,10,12,12,11,12,11,10,12,12,10,11,12,11,11,11,12,11,11,12,12,14,13,12,12,13,13,12,13,14,13,13,13,13,13,15,14,12,14,13,12,13,13,12,11,11,13,11,10,11,11,9,9,9,9,8,9,8,9,9,11,10,11,9,11,10,9,9,10,9,9,9,9,9,9,9,9,8,8,9,9,9,10,9,9,8,8,8,8,9,8,8,8,9,9,9,9,10,9,9,9,10,11,11,12,10,10,10,10,10,10,8,8,8,8,8,8,8,7,7,8,8,7,7,6,6,6,6,6,5,5,5,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,5,4,5,6,5,5,6,6,6,7,8,7,9,11,13,12,14,16,17,16,16,17,17,16,17,18,18,18,19,22,22,20,23,23,23,22,23,22,21,23,19,19,21,22,21,21,22,23,24,22,24,24,24,26,26,26,27,27,27,27,27,27,26,28,28,28,26,27,26,27,27,26,27,25,26,26,26,27,26,26,26,24,24,26,25,23,24,24,22,22,21,19,18,15,14,13,9,7,5,5,4,3,3,3,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,7,8,8,8,8,8,7,7,7,7,7,7,7,6,7,7,7,6,8,7,8,7,7,7,7,7,7,7,7,8,8,7,7,8,9,8,8,9,8,8,8,8,9,9,11,10,10,10,10,10,10,11,12,12,12,12,12,13,14,14,13,14,14,14,13,14,14,12,13,15,13,11,12,12,11,10,10,10,10,9,9,9,8,8,8,8,6,6,7,6,6,6,6,5,5,6,5,4,5,5,5,4,5,6,5,5,6,6,5,5,6,6,6,6,7,7,6,6,7,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,9,11,11,11,12,12,13,13,12,13,13,13,14,14,14,14,15,15,14,15,16,14,14,14,14,14,13,12,12,12,11,10,9,8,8,8,8,8,8,7,7,7,6,6,6,6,5,5,5,5,4,5,5,4,4,4,5,5,5,5,6,6,5,6,6,6,7,6,6,6,6,5,6,7,7,6,7,7,7,6,6,5,6,6,5,4,5,5,4,5,5,4,4,5,4,4,5,5,6,6,6,6,5,6,6,6,5,6,5,5,5,5,4,4,4,4,4,3,3,3,2,3,3,3,4,4,4,5,5,5,6,6,5,6,6,7,7,5,6,6,5,5,5,5,5,5,6,5,5,6,6,6,6,7,7,6,7,7,8,9,10,10,11,12,11,11,11,13,13,15,15,17,19,19,18,17,18,19,19,22,20,21,21,22,25,24,22,23,23,23,23,24,23,22,22,23,22,20,20,22,22,20,22,20,20,22,22,20,19,21,20],[29,28,28,29,28,28,29,28,28,28,27,27,28,26,27,26,27,26,27,28,26,26,28,27,27,28,28,28,28,28,27,28,28,29,28,29,28,28,29,29,29,28,28,28,28,28,27,26,27,27,25,24,25,24,23,23,23,21,20,19,18,16,14,12,12,10,10,9,9,9,8,8,8,7,8,9,10,10,12,10,11,11,12,12,11,13,13,14,14,15,15,16,16,15,15,16,16,16,17,17,17,16,16,17,17,17,18,17,17,18,18,17,16,18,16,16,16,15,15,14,16,15,14,15,16,16,14,17,16,13,14,15,13,14,14,15,15,16,16,15,16,16,16,16,16,16,16,15,14,15,16,14,14,13,15,15,16,16,15,15,14,14,13,14,14,12,13,15,14,12,13,14,12,12,13,13,11,12,13,11,13,11,10,12,12,10,12,13,11,10,13,13,11,12,12,13,15,14,12,14,14,13,13,15,14,14,14,12,13,13,15,14,12,15,14,12,14,14,12,10,12,13,11,10,11,11,10,10,11,10,9,10,9,11,10,11,11,11,9,11,11,10,9,11,10,9,9,10,9,9,10,9,9,9,9,9,10,10,10,9,8,9,9,9,9,9,8,9,10,9,10,10,10,10,10,10,11,11,11,12,10,11,10,11,11,9,9,9,9,9,9,8,8,8,8,8,8,8,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,5,4,5,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,8,9,9,10,11,12,13,14,15,17,15,15,17,18,16,17,19,19,17,18,21,22,21,23,23,24,22,24,21,20,22,19,18,19,20,20,19,19,22,21,20,22,23,24,24,25,26,26,27,27,27,27,27,26,27,27,27,25,27,25,26,27,25,26,25,24,26,24,26,25,25,26,25,24,25,24,23,23,23,22,21,21,18,18,15,13,12,9,7,6,5,5,4,4,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,2,2,3,3,4,4,3,3,2,3,3,2,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,3,3,2,3,3,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,7,7,8,8,8,8,8,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,10,9,10,9,9,10,11,12,12,12,11,11,10,10,10,12,12,11,12,13,14,15,15,15,14,15,15,14,15,13,13,14,14,13,13,13,12,12,11,11,11,10,10,10,9,9,9,8,8,8,8,7,7,8,6,6,7,6,6,7,5,6,6,6,5,5,6,6,6,6,7,7,6,6,7,7,7,7,7,7,8,7,7,9,8,8,8,9,8,8,8,9,9,9,9,9,10,11,11,11,12,13,13,14,14,14,14,13,13,15,16,15,15,15,16,14,15,16,14,15,14,14,14,13,14,13,12,11,10,10,10,10,10,9,8,9,8,8,8,8,7,7,7,6,7,7,5,5,6,5,4,4,5,5,5,6,6,6,7,7,6,7,7,7,7,8,7,7,8,8,8,8,8,8,8,8,7,7,7,6,7,6,6,7,6,5,6,6,5,5,5,6,5,5,6,6,6,6,7,6,6,7,6,7,6,6,6,6,6,6,6,6,5,5,4,4,3,3,3,4,4,5,5,5,6,6,6,7,7,7,6,6,7,7,6,6,7,7,6,6,7,5,6,6,6,6,6,6,6,7,8,7,7,7,8,9,10,10,10,10,11,10,11,11,13,12,15,15,17,18,19,19,17,17,19,19,22,19,20,22,21,23,23,22,23,24,22,23,23,23,22,21,23,21,18,19,23,22,19,23,21,20,23,21,19,20,22,20],[29,28,28,28,28,28,28,28,28,27,27,26,27,26,27,27,27,26,27,27,27,26,27,27,26,27,28,27,28,28,26,28,28,28,27,28,27,28,28,28,28,27,26,27,27,27,26,25,25,25,24,24,23,23,22,21,21,20,19,19,18,16,14,13,11,10,10,10,9,10,9,8,8,8,8,9,9,10,12,10,10,12,12,10,12,14,13,14,15,15,16,16,17,17,16,17,16,16,16,16,17,17,17,17,19,18,17,17,17,17,17,17,17,19,17,16,17,15,15,15,16,16,15,15,17,17,15,17,16,14,15,16,14,15,14,15,15,16,16,16,16,17,17,16,16,17,17,16,15,16,16,14,15,14,15,16,16,16,14,15,13,14,13,14,14,13,13,16,14,14,14,14,13,14,14,15,12,13,13,13,15,13,12,14,14,11,12,14,12,12,13,14,10,13,13,13,15,15,12,14,15,13,13,15,15,13,14,13,14,15,15,14,12,16,14,13,15,15,14,11,13,15,12,11,12,12,10,10,11,11,9,10,9,10,10,11,11,11,10,12,12,10,10,12,11,10,10,11,9,9,10,9,8,9,9,10,11,11,9,9,8,10,9,8,11,9,8,9,11,9,9,11,10,10,10,11,11,12,11,13,12,12,10,11,11,10,9,10,9,9,9,9,9,8,8,8,8,7,8,7,7,7,7,7,7,6,6,5,6,6,5,5,6,5,4,5,4,5,5,5,5,6,6,6,6,6,7,6,7,7,7,8,8,8,10,11,11,14,15,16,17,14,15,16,17,17,16,17,17,17,19,20,20,20,21,20,23,21,21,20,18,20,20,20,20,21,20,19,19,20,20,20,22,24,24,24,24,26,26,26,26,26,25,26,24,25,25,25,24,26,25,25,26,24,26,24,25,26,24,26,25,25,27,25,23,26,25,23,24,22,21,21,19,19,17,14,13,12,9,7,6,5,6,4,4,4,3,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,2,2,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,5,5,5,5,7,6,7,8,7,8,7,6,7,6,7,7,7,7,6,7,7,8,7,7,8,7,7,8,8,7,7,8,8,7,8,8,8,7,8,9,8,9,10,9,9,9,10,10,11,11,12,12,12,11,10,11,10,12,12,12,12,14,14,15,15,15,14,15,15,14,15,14,12,14,14,13,13,12,13,11,11,11,11,10,9,10,10,9,9,8,8,7,8,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,6,6,5,6,6,6,5,6,6,6,7,7,7,7,7,7,7,8,7,8,8,8,8,8,9,9,10,10,10,9,10,10,11,10,11,13,13,14,15,13,15,14,14,15,15,15,16,15,16,14,15,16,15,14,15,14,14,14,13,13,12,12,10,10,10,9,9,9,9,9,9,8,8,8,7,7,6,7,6,6,5,6,5,5,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,6,8,7,7,7,8,7,7,8,8,8,7,8,7,7,7,7,6,7,6,5,6,6,5,4,5,6,5,5,5,6,6,6,6,6,6,7,6,6,7,6,6,6,6,5,5,6,6,5,4,4,3,3,4,4,4,5,5,4,5,6,6,7,7,7,7,6,7,7,6,6,6,6,5,6,5,5,6,6,5,6,6,6,6,6,7,7,7,7,7,8,9,10,10,10,11,10,11,11,13,13,15,16,16,19,21,19,17,19,20,20,23,20,22,23,21,24,24,23,24,25,22,24,24,23,23,23,23,22,19,21,23,22,21,21,22,18,23,21,20,21,21,19],[28,28,28,28,29,29,28,28,28,27,27,26,27,27,27,27,27,27,26,27,27,26,26,27,26,26,27,27,27,27,26,27,28,28,27,28,28,28,29,28,28,27,27,27,27,27,26,24,26,24,24,24,23,23,22,21,20,20,19,18,16,15,13,11,10,10,10,9,10,8,9,8,8,7,8,8,10,9,12,9,10,11,12,10,12,13,13,14,14,14,14,14,15,16,15,14,15,15,15,16,16,17,16,16,16,17,17,17,17,17,17,17,17,17,16,17,15,15,14,14,16,14,14,14,16,16,14,16,16,14,15,16,14,14,13,14,15,14,15,15,14,15,16,15,15,15,16,15,14,15,15,15,15,13,14,15,16,15,14,16,14,13,14,13,13,12,13,14,13,12,13,14,12,13,13,14,12,13,13,11,13,11,11,13,13,11,11,13,12,11,12,13,11,12,12,13,14,14,12,13,14,14,13,13,14,12,14,12,13,14,15,14,12,14,13,12,14,13,13,12,13,13,12,11,12,12,10,10,11,10,9,10,10,10,11,12,10,12,10,12,11,10,9,11,10,10,9,10,8,9,10,9,8,9,9,10,11,11,10,9,8,9,8,9,10,9,8,9,11,9,9,10,10,9,9,10,10,11,11,12,11,11,10,11,11,9,9,9,9,8,8,8,8,8,8,8,8,7,7,7,7,7,6,7,6,6,6,5,6,6,5,5,6,5,5,5,4,5,5,5,5,5,6,6,6,6,7,7,7,7,7,8,8,8,10,11,13,12,15,16,16,15,16,17,16,16,18,17,16,18,19,19,20,21,22,22,23,22,23,21,20,22,20,19,21,22,20,20,21,21,21,21,23,24,24,25,25,26,26,27,26,27,27,27,27,27,28,27,26,27,26,27,27,26,27,24,26,26,25,27,26,26,26,24,24,26,25,22,23,22,21,22,20,19,17,15,14,13,10,7,6,5,6,4,4,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,2,2,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,5,4,3,4,5,4,4,5,5,4,5,5,6,7,7,7,8,9,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,8,8,7,8,7,7,7,7,7,7,6,7,8,7,7,8,8,7,8,9,8,8,8,8,8,10,11,11,10,10,10,9,11,10,12,12,12,12,13,14,14,15,13,13,14,14,13,14,15,12,13,14,13,12,12,12,11,11,11,10,10,9,9,9,8,8,7,7,7,6,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,5,6,6,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,8,7,8,9,8,8,9,9,12,10,11,12,13,13,13,13,14,14,13,15,15,14,14,15,15,14,15,16,15,15,14,15,14,13,13,12,12,12,10,10,8,9,8,8,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,5,4,4,5,5,5,6,6,6,7,6,6,7,6,6,7,7,7,7,8,7,8,7,7,6,6,6,6,6,6,6,5,5,5,4,4,4,4,4,4,5,5,5,6,6,5,6,6,6,5,6,6,5,6,5,4,5,5,6,4,4,4,3,3,3,3,3,4,5,4,5,5,5,6,6,5,7,6,7,6,5,6,5,5,5,6,5,5,5,6,5,5,6,6,6,6,7,7,7,7,7,8,9,10,10,10,12,11,11,12,14,14,16,17,17,19,20,20,18,20,20,19,22,20,21,22,21,23,23,23,25,24,23,25,24,22,24,22,24,22,21,22,24,22,21,21,21,19,23,21,20,20,22,20],[29,29,28,29,29,29,29,28,29,28,27,27,27,27,27,27,27,26,27,27,26,26,27,27,27,26,27,27,27,27,26,28,28,28,28,28,28,27,29,28,29,28,28,27,28,27,27,26,26,25,25,24,24,23,24,23,22,22,21,20,18,17,14,13,12,10,9,10,9,8,8,8,7,7,8,9,10,10,12,11,11,12,12,11,12,13,14,13,14,13,14,14,14,15,15,15,15,14,15,15,15,15,16,16,15,16,16,17,16,17,17,17,15,17,16,16,15,15,15,15,16,14,14,14,16,15,13,15,15,15,14,14,14,15,13,15,14,15,15,15,15,14,15,15,15,13,15,15,14,14,15,14,14,13,14,15,15,15,15,15,13,14,14,14,13,13,13,13,14,12,13,12,12,12,13,13,12,13,13,13,13,11,12,13,13,12,12,13,12,12,12,12,12,12,12,13,14,13,13,13,14,13,13,14,15,13,14,14,12,15,15,13,12,14,13,13,14,13,13,12,12,13,12,11,12,11,10,10,11,10,9,9,10,11,11,12,11,11,10,13,11,10,10,11,10,10,10,10,9,9,10,9,9,9,9,10,11,11,10,9,8,9,8,9,10,9,9,9,10,9,10,10,10,10,10,10,11,11,11,11,11,11,10,11,11,10,10,9,10,9,8,8,9,8,8,8,8,8,7,7,7,7,6,7,6,6,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,9,10,11,12,13,15,15,17,16,15,18,18,18,19,20,20,19,20,22,23,22,23,25,25,23,24,22,22,22,19,20,20,20,21,21,21,22,22,22,23,23,24,25,25,25,27,27,27,27,27,27,27,27,27,27,27,27,26,27,27,26,27,24,26,26,26,26,26,26,27,25,23,26,24,24,25,23,22,22,21,19,18,16,13,12,8,7,6,5,5,4,4,3,3,2,3,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,2,1,2,3,3,3,3,3,3,2,3,2,3,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,5,5,4,5,5,5,4,6,6,5,6,6,7,6,7,7,8,8,8,8,9,8,8,8,7,8,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,7,7,8,8,8,9,8,9,8,9,10,9,9,9,9,10,11,12,12,11,12,11,10,11,11,12,12,12,13,14,14,15,15,14,13,14,14,15,15,15,12,13,14,13,13,13,12,11,12,12,11,11,10,11,10,9,8,8,8,8,7,7,8,7,6,7,6,6,6,6,6,6,5,6,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,6,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,11,10,12,11,12,13,13,14,14,13,14,13,13,14,15,14,15,15,17,14,16,18,15,15,15,16,15,15,14,15,13,12,12,11,9,10,9,9,9,9,8,8,8,7,6,7,7,5,6,7,5,5,6,6,5,4,4,5,5,5,5,6,6,6,6,7,6,7,7,7,7,7,6,7,8,7,7,8,7,8,7,7,6,7,6,6,5,6,6,5,5,6,4,4,5,5,5,5,6,6,6,7,6,6,6,7,6,6,6,6,6,6,5,5,5,5,5,4,4,3,3,3,3,4,4,4,5,5,5,5,5,6,7,6,7,6,8,7,6,6,6,5,6,6,6,5,6,7,5,6,7,7,7,7,8,8,7,8,8,9,10,11,11,11,12,12,13,13,13,14,15,14,17,18,20,18,18,19,20,19,23,21,22,22,21,25,23,23,23,24,22,23,24,23,22,21,23,22,20,21,22,22,22,21,21,22,22,22,22,21,23,21],[29,28,28,28,28,29,29,28,28,28,27,27,28,27,27,27,28,26,27,28,27,26,28,27,26,27,27,27,28,27,26,28,28,29,27,28,27,28,28,28,28,28,27,26,27,27,26,26,26,25,25,24,24,24,23,22,22,21,20,19,18,16,14,12,12,10,10,9,9,9,9,9,8,8,9,10,11,12,13,11,11,13,13,11,13,15,15,15,16,16,17,16,17,17,16,16,17,16,17,18,18,17,17,19,18,18,18,17,18,18,17,17,18,19,17,17,17,16,16,15,17,16,14,15,18,17,14,17,17,14,15,17,14,14,15,16,16,17,15,16,16,16,16,17,16,16,17,16,15,17,17,16,16,15,16,16,17,16,16,15,15,14,14,15,16,14,13,16,15,14,15,15,15,15,15,15,13,14,13,13,15,13,12,14,14,12,13,14,13,12,13,14,12,14,14,15,15,15,12,15,15,14,14,16,16,14,14,13,15,15,15,15,13,16,16,14,16,16,14,12,14,15,13,11,14,13,11,10,12,11,9,10,9,11,11,11,12,13,11,12,13,10,11,13,11,9,10,11,9,9,11,9,9,9,9,11,12,12,10,9,8,10,9,10,11,10,9,10,11,10,10,11,11,10,11,12,12,12,12,13,12,13,11,12,13,11,10,10,11,9,9,10,9,9,8,9,8,8,7,7,8,7,7,7,7,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,9,9,8,11,11,12,13,15,15,17,15,15,17,18,16,16,18,19,17,19,21,21,21,22,22,24,22,23,20,20,21,20,20,20,22,23,20,21,21,22,21,24,23,24,24,25,26,26,26,26,26,26,26,26,26,26,26,25,26,25,26,27,24,26,24,25,25,24,26,25,24,26,24,24,24,24,23,22,22,21,20,19,18,17,14,13,11,9,8,7,6,6,5,4,4,4,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,2,3,3,3,3,3,2,3,3,2,3,2,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,4,4,4,5,5,4,4,5,5,5,6,5,5,6,6,7,7,7,7,9,8,8,9,9,7,8,7,7,8,7,8,8,8,8,8,8,8,8,8,8,9,8,8,9,9,8,8,9,9,9,9,9,9,9,10,10,9,10,9,10,11,12,13,13,13,12,12,10,12,11,13,13,13,14,14,15,15,15,16,14,15,16,15,15,15,14,14,15,15,14,13,14,13,12,12,12,11,10,11,11,10,10,9,9,9,8,8,8,8,7,7,7,7,6,7,7,6,6,7,6,6,7,7,7,7,7,8,7,7,7,8,8,8,8,8,8,8,8,9,9,8,9,10,10,9,10,10,11,11,10,10,11,11,12,11,13,14,14,15,15,14,16,15,14,16,17,16,16,16,17,14,16,17,15,15,15,16,16,14,14,15,14,13,12,10,11,10,10,10,10,10,9,9,10,9,8,8,8,7,7,7,7,6,6,6,6,5,5,5,6,7,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,8,9,9,9,9,8,8,8,7,8,7,7,7,8,6,7,7,6,5,6,7,6,5,6,6,7,7,7,7,7,8,7,8,7,7,7,8,6,7,7,7,6,6,5,4,4,4,4,5,5,6,6,6,7,7,6,8,8,7,8,8,8,7,7,7,6,6,7,7,6,6,7,7,7,7,8,8,8,7,8,8,8,8,9,9,10,11,11,11,13,12,12,13,14,13,15,16,18,20,20,19,16,18,20,19,21,19,21,21,22,24,23,21,22,24,22,23,23,22,22,22,22,21,19,21,23,22,20,22,22,20,23,20,21,22,22,19],[27,27,27,27,27,28,28,27,27,26,25,26,26,25,26,26,26,25,25,26,26,25,26,26,24,26,26,26,26,26,25,27,26,28,26,27,26,27,27,27,27,26,25,26,26,26,25,24,24,24,23,23,22,22,21,20,20,20,18,18,16,15,14,13,11,11,11,11,10,10,10,10,8,9,10,11,11,12,15,12,12,14,15,13,14,17,16,16,16,16,17,17,17,16,17,17,17,17,17,17,17,18,18,18,18,18,17,18,18,17,18,18,18,18,18,17,17,17,16,17,18,18,16,16,17,18,16,17,17,16,16,17,16,15,15,15,16,16,17,17,16,17,17,18,18,17,17,18,16,17,17,17,17,15,17,16,17,16,17,16,16,15,14,15,16,14,14,16,17,15,15,16,15,15,15,16,14,15,15,13,17,13,13,15,16,13,14,15,14,14,13,15,13,14,14,14,16,16,15,14,15,15,14,15,15,15,16,15,15,17,17,16,14,18,17,15,16,17,16,14,16,16,15,14,15,14,12,12,14,12,10,11,10,12,11,13,12,12,11,14,13,11,11,13,12,11,11,12,10,10,12,10,10,10,10,12,13,13,11,10,9,11,10,10,13,11,9,11,13,10,11,13,12,11,11,12,12,14,14,15,13,15,12,13,14,12,10,11,12,10,9,10,11,9,9,10,9,8,8,8,8,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,5,6,6,6,7,7,7,7,7,8,8,7,8,8,8,10,10,9,11,11,13,14,14,15,16,15,16,18,17,17,17,17,17,17,18,20,20,20,22,21,23,22,23,22,20,21,19,19,21,21,19,20,21,20,20,20,20,23,22,24,25,25,26,26,26,26,26,26,25,26,26,26,24,25,24,25,26,23,25,22,25,26,24,25,24,25,26,22,22,25,23,21,24,21,21,22,19,18,16,15,14,12,10,9,7,6,7,5,6,4,5,4,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,3,3,2,3,3,3,3,4,5,4,4,5,4,5,5,6,5,5,5,5,5,5,6,5,6,7,6,7,8,8,9,9,8,9,8,7,8,8,8,8,8,8,8,8,9,8,8,9,10,8,8,9,9,8,8,9,9,8,10,10,9,9,10,11,9,10,11,10,10,10,10,10,12,13,12,11,12,11,11,13,12,14,14,14,14,15,16,16,16,16,16,16,16,17,16,16,14,15,16,15,15,15,15,14,12,13,13,11,11,12,11,10,9,10,9,9,8,8,8,8,8,7,7,7,7,7,7,6,6,7,6,7,7,7,6,7,7,6,6,7,7,6,8,8,8,7,7,8,8,8,8,9,9,9,9,9,10,10,11,11,10,10,11,12,13,13,13,15,15,17,16,15,16,16,15,18,18,16,16,16,18,16,17,17,17,16,16,16,15,15,14,14,14,14,12,12,11,12,10,11,10,9,9,9,9,9,7,8,7,7,7,7,7,6,6,6,6,5,5,5,6,6,6,7,7,7,6,8,7,9,7,8,8,8,8,9,9,8,8,10,9,10,9,9,8,8,8,7,7,7,7,6,6,7,5,5,6,6,5,5,6,6,6,8,7,6,7,7,7,7,8,7,6,7,7,6,6,7,6,6,6,4,5,4,3,5,5,6,5,5,6,6,6,7,7,7,6,7,8,6,6,6,6,5,6,6,6,6,7,7,6,7,7,7,7,7,8,8,8,8,8,9,10,10,11,11,12,11,12,13,13,14,17,17,18,19,19,20,17,18,20,19,22,21,21,21,20,24,23,22,23,24,21,23,24,21,23,23,23,21,20,20,23,21,20,20,21,19,22,20,20,21,21,19],[27,28,27,27,28,28,27,27,28,26,27,26,27,26,26,27,27,25,26,26,25,26,25,25,26,26,26,26,26,26,25,27,26,27,27,27,27,27,28,27,27,27,26,27,26,26,26,25,24,24,24,22,23,22,22,21,20,21,20,18,16,16,13,14,12,11,11,11,11,10,10,10,9,10,11,12,13,13,15,13,14,15,15,14,15,17,16,17,17,18,17,17,17,17,17,17,18,18,18,18,18,19,18,19,18,19,18,17,18,19,19,18,19,21,18,19,18,17,17,17,19,18,16,17,18,17,15,18,19,17,16,17,17,16,16,16,17,17,17,17,18,17,18,18,18,17,18,18,17,17,18,18,17,17,17,18,17,17,17,16,17,17,16,15,17,15,15,17,18,16,16,17,15,15,16,17,15,16,15,15,17,15,14,16,16,15,15,15,15,15,14,17,15,15,15,14,16,17,15,15,17,16,15,16,17,15,16,15,16,18,17,16,15,17,16,16,18,17,16,16,15,17,17,14,16,16,14,14,15,14,12,12,11,13,14,14,13,14,13,14,15,12,12,14,13,12,12,13,12,11,13,12,11,11,12,13,14,13,12,12,12,12,11,12,13,13,11,12,14,13,13,13,13,12,13,13,12,14,15,15,13,17,15,15,15,13,13,13,13,12,11,11,12,11,11,10,10,10,8,8,9,8,7,8,8,7,8,7,7,7,7,7,7,7,7,7,6,6,7,6,6,7,7,8,8,8,8,8,9,9,8,9,11,10,11,12,13,13,15,16,16,16,17,18,17,17,18,19,19,18,19,21,21,21,22,23,24,22,24,22,21,21,19,20,21,22,21,20,21,20,21,21,20,23,23,24,25,24,25,26,26,26,26,27,26,26,27,26,25,26,24,27,26,25,26,22,26,25,24,25,25,25,26,22,23,25,23,22,23,21,21,21,19,18,17,15,14,12,10,9,8,7,7,6,6,5,4,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,0,1,1,2,3,3,3,4,3,3,3,3,3,3,2,2,2,3,2,2,3,3,3,2,3,4,3,4,4,4,4,5,4,5,6,6,5,6,6,6,6,7,6,7,7,7,8,9,9,9,9,10,10,10,9,9,8,9,8,9,9,9,9,10,10,9,9,10,10,10,10,10,10,9,10,9,10,9,11,11,10,10,11,12,11,11,12,12,11,11,11,12,12,15,13,13,13,13,13,13,14,15,15,15,17,16,17,17,17,16,16,15,17,16,17,17,15,15,18,16,16,16,17,15,15,15,14,14,13,14,13,12,11,12,11,11,9,9,9,9,8,8,9,8,8,8,8,7,7,8,7,8,7,7,8,7,8,8,8,8,8,8,8,9,8,9,8,9,9,9,9,9,9,9,9,10,10,10,10,12,11,11,12,13,14,13,15,16,17,16,17,17,17,17,16,17,17,17,16,17,19,17,17,21,17,17,17,18,18,17,16,15,15,15,13,12,10,13,11,12,12,10,9,10,10,9,8,9,9,8,8,8,7,7,7,7,6,6,6,5,7,6,6,7,7,7,7,8,7,8,8,7,8,8,8,8,9,9,8,9,8,10,9,9,8,8,8,7,7,8,7,6,7,6,6,5,6,5,5,6,6,7,6,7,7,6,7,7,7,7,8,7,6,8,7,6,6,6,6,6,5,4,4,4,4,4,4,5,5,5,5,6,6,7,8,7,8,8,9,8,7,7,8,7,7,7,8,7,7,8,8,7,8,9,8,8,9,9,9,9,9,10,11,11,12,12,13,12,13,13,14,15,17,17,18,20,20,20,18,20,20,20,22,20,22,22,22,24,24,23,23,24,22,24,24,23,25,22,24,22,22,21,23,22,21,20,21,19,22,21,20,20,21,19],[28,28,28,28,28,29,28,27,28,27,26,27,27,27,27,27,26,25,26,26,25,26,26,26,26,26,27,26,27,27,26,27,27,28,27,28,28,27,28,27,27,27,27,27,27,26,26,25,25,25,25,23,23,23,22,23,22,22,20,20,19,18,17,15,15,14,14,14,14,14,14,13,14,14,16,16,18,18,19,18,20,19,18,21,20,20,21,20,19,21,21,20,21,21,20,20,21,21,21,21,21,21,21,21,21,22,21,20,21,21,21,21,22,22,22,21,21,21,21,20,22,21,20,20,21,20,19,21,21,19,19,21,20,19,18,19,21,21,20,20,21,20,20,21,20,20,21,21,20,20,21,21,20,20,21,21,21,21,21,20,21,20,21,20,20,20,19,21,21,20,19,20,19,20,19,20,18,19,19,20,20,19,18,18,20,19,18,19,19,19,17,20,20,20,18,18,19,19,19,18,19,18,18,18,19,18,18,19,18,20,20,19,19,21,20,19,21,20,19,19,19,20,20,19,19,20,18,18,19,18,17,17,16,17,17,18,17,17,16,18,19,17,16,17,16,16,17,18,15,16,17,16,15,15,15,16,17,17,16,15,15,16,14,16,17,16,15,16,18,16,18,17,18,17,17,17,17,18,18,18,18,18,18,20,18,17,17,17,17,15,16,16,16,14,15,15,14,15,13,13,13,11,11,11,11,10,11,9,10,10,10,9,10,10,10,10,8,8,8,8,8,9,9,10,10,10,10,11,12,12,11,12,13,13,13,15,15,15,18,16,19,17,16,19,19,17,17,19,19,18,19,22,21,20,22,23,23,22,23,22,21,21,20,19,20,21,21,20,21,22,22,22,22,23,24,24,25,25,26,26,26,26,26,26,26,26,26,26,24,25,24,26,26,24,26,24,24,25,24,26,25,25,26,24,23,25,23,22,22,22,22,20,20,18,18,15,16,14,12,10,9,9,9,8,7,6,6,6,5,5,5,5,4,4,4,3,4,4,3,3,3,2,1,1,0,1,4,5,5,5,6,5,4,5,5,4,4,3,2,3,4,3,3,3,4,4,4,5,6,5,5,7,6,6,7,7,9,8,10,9,9,9,10,9,10,11,10,10,11,11,10,10,11,13,13,12,12,12,12,12,12,12,13,13,13,12,13,14,13,13,14,15,14,14,14,14,12,15,14,13,13,15,15,14,15,15,16,15,15,16,17,17,16,16,15,16,18,16,18,18,17,17,17,19,18,18,19,19,18,18,20,20,17,19,20,19,17,18,20,17,17,20,19,19,19,20,18,19,20,19,18,19,19,18,17,16,16,14,15,15,14,14,14,12,13,13,12,12,12,12,10,11,11,11,11,11,11,12,11,11,12,12,11,12,13,13,13,13,13,12,14,13,14,14,13,14,15,14,15,15,15,16,16,15,15,17,17,18,19,19,20,20,19,19,20,21,20,19,19,20,19,20,21,21,18,21,22,20,19,19,19,20,20,18,20,19,18,17,16,16,16,17,17,16,14,14,14,14,13,12,13,13,12,12,12,11,9,10,12,9,8,10,9,11,10,10,11,10,11,12,12,11,12,11,12,12,12,12,12,14,13,12,13,13,13,12,12,11,12,12,10,10,11,11,9,10,10,9,9,10,9,8,9,10,11,9,11,10,9,11,11,10,11,10,10,10,10,9,9,9,9,8,9,7,6,6,5,5,6,6,7,7,7,7,8,8,10,10,9,11,11,12,11,10,11,10,9,12,12,10,11,11,13,10,12,12,12,11,12,13,12,12,12,14,13,13,13,13,13,15,14,15,15,16,16,17,17,18,17,21,19,18,19,21,19,22,20,22,22,21,25,24,22,22,25,22,22,23,22,22,21,23,22,20,21,22,21,20,22,20,20,22,22,19,19,21,19],[28,28,27,28,28,28,28,27,28,27,26,27,27,26,27,26,26,24,27,27,24,27,27,25,27,28,26,27,28,26,28,28,26,28,28,28,27,28,28,29,29,28,27,28,28,28,28,27,26,27,26,25,25,25,25,24,24,24,22,21,22,19,18,17,18,16,16,16,15,17,17,17,17,17,17,18,20,19,21,21,22,20,22,21,21,22,22,22,23,23,23,22,24,23,23,23,24,23,23,23,24,24,23,24,23,23,24,23,23,23,25,24,24,24,23,23,23,24,22,22,24,23,22,22,23,23,21,24,24,21,22,25,22,21,21,23,22,22,23,22,24,22,23,24,23,23,24,23,22,23,23,24,23,21,23,23,24,22,23,22,23,23,21,22,23,22,21,23,23,22,21,23,22,22,22,22,21,20,21,20,22,22,21,21,22,21,20,21,21,21,20,23,21,21,21,21,22,22,20,21,21,21,22,21,22,21,21,22,22,23,23,22,22,23,23,21,24,23,22,22,21,23,22,21,21,21,22,20,21,20,19,19,18,19,18,18,20,18,17,19,20,20,17,20,20,20,18,20,18,19,18,17,17,17,17,18,19,18,17,17,18,18,18,17,19,18,18,18,19,18,19,18,21,17,19,21,19,21,20,21,21,21,20,20,19,20,18,19,19,17,18,18,19,18,16,17,17,17,16,16,16,14,14,15,14,12,14,13,12,12,13,13,11,11,11,12,10,11,11,11,10,12,12,13,13,12,14,14,13,14,12,13,14,14,15,16,17,17,19,19,20,19,18,21,21,19,19,21,20,18,21,23,22,22,23,24,24,22,25,22,22,22,22,20,21,22,23,21,22,22,22,23,23,23,24,26,26,26,26,26,26,26,26,25,26,26,26,26,25,25,25,26,25,24,26,23,25,24,25,25,24,24,26,23,23,25,23,23,22,22,22,20,21,19,19,17,16,15,14,12,12,11,12,12,10,9,9,8,8,7,5,6,7,4,5,5,3,4,5,4,2,3,3,2,1,0,1,3,4,4,5,5,5,6,4,4,4,4,3,3,4,4,5,4,6,6,5,7,8,7,7,7,9,9,10,10,11,12,12,10,12,12,10,9,12,12,9,11,12,10,9,11,12,11,12,13,13,13,13,12,15,13,14,16,15,16,15,15,15,16,16,16,15,16,15,15,16,15,15,15,16,16,16,16,16,15,18,16,16,18,17,17,16,17,17,17,20,17,18,19,18,19,20,21,20,21,20,23,21,21,22,22,21,21,22,23,22,22,22,21,21,22,21,22,22,22,22,21,21,21,19,19,20,19,18,18,18,17,18,16,16,16,16,15,15,14,13,14,14,13,13,13,14,13,12,13,14,13,14,14,13,13,13,14,13,14,14,14,15,13,13,14,16,15,14,16,16,15,16,17,17,17,19,17,18,18,19,20,20,22,22,22,22,22,22,24,23,21,23,23,22,22,23,23,21,23,23,23,22,22,23,22,21,20,22,21,20,20,18,18,19,19,19,17,17,17,16,17,17,15,15,15,14,14,14,13,13,13,13,13,11,11,11,10,14,12,12,13,15,12,14,14,14,15,12,14,14,15,14,15,16,15,15,16,15,15,15,16,14,14,14,14,14,14,13,14,13,12,10,13,12,10,10,12,12,12,12,14,11,13,14,14,14,13,15,11,14,13,12,12,12,13,13,11,10,8,8,7,9,8,10,10,10,11,10,10,11,12,11,12,13,13,11,11,12,10,11,13,12,10,13,15,12,12,16,13,14,14,14,14,14,14,14,14,14,14,14,15,15,15,14,15,16,17,17,19,17,21,19,24,23,19,20,24,22,26,22,25,23,23,26,24,22,24,25,22,25,26,23,23,22,24,21,19,21,23,22,20,23,21,20,22,20,20,19,20,17],[28,28,28,28,28,29,29,28,28,28,27,27,27,27,27,27,27,26,27,27,26,27,28,27,28,28,28,28,28,28,28,29,28,29,29,29,28,29,29,29,29,29,29,29,29,29,28,28,28,28,27,27,27,27,26,26,25,26,25,24,23,22,20,20,20,18,19,19,18,18,18,17,18,17,20,20,21,21,23,21,22,22,23,22,23,24,24,23,24,24,25,23,24,24,24,24,25,24,24,24,24,25,24,25,25,24,25,24,25,25,25,25,25,26,25,25,25,24,24,24,25,24,23,23,24,24,21,23,24,23,22,24,23,23,23,24,23,24,24,24,24,24,24,24,24,24,24,24,25,24,24,25,25,23,25,24,25,24,24,24,23,25,22,23,24,23,21,24,24,23,22,24,23,22,23,23,22,22,22,23,24,22,21,22,23,21,21,23,23,22,20,23,22,22,21,21,22,23,22,22,22,23,23,22,23,22,22,23,22,24,24,22,23,24,24,23,24,24,23,23,23,24,22,22,23,21,21,21,23,20,19,20,18,20,19,20,20,20,19,20,22,19,20,20,21,18,19,21,18,17,19,19,17,17,17,19,20,19,17,17,17,19,17,16,20,20,16,19,20,19,19,19,21,19,20,21,20,21,21,22,22,22,20,22,22,21,20,21,21,18,18,20,19,16,17,19,18,15,16,16,16,14,14,13,13,13,13,11,12,12,10,10,12,11,9,10,9,10,11,10,11,12,11,12,13,14,14,14,15,15,14,15,17,16,16,19,19,19,21,19,21,21,19,22,22,22,21,22,22,22,24,25,25,24,26,25,26,24,25,24,22,23,22,21,22,22,22,22,23,23,24,23,23,24,24,25,26,26,26,26,26,26,26,26,26,26,26,26,25,26,24,26,26,25,26,24,25,25,26,26,25,25,26,24,24,24,23,24,24,24,24,22,23,20,20,18,18,16,15,13,13,12,12,11,10,11,8,8,6,6,5,5,5,4,5,4,3,4,5,4,2,3,4,4,2,1,0,1,3,3,4,5,4,6,7,6,6,5,6,6,8,7,6,7,7,6,6,7,8,7,7,8,8,8,8,8,9,10,10,9,9,9,9,8,9,10,10,11,10,10,10,10,11,11,11,11,12,13,10,12,12,13,14,14,15,13,13,14,15,13,14,16,15,13,15,15,13,14,15,15,13,15,17,15,15,17,19,16,17,19,19,19,18,19,19,19,21,20,20,21,20,20,19,22,22,22,22,23,23,22,23,23,23,22,23,24,24,24,23,22,22,24,23,23,22,24,22,22,24,22,21,20,22,21,20,19,19,18,17,17,16,14,14,14,14,12,12,13,13,11,12,11,11,10,10,12,12,11,11,13,12,11,13,13,12,12,14,14,14,12,15,15,15,14,16,17,16,16,17,18,18,18,20,19,19,20,21,22,22,23,22,23,23,23,24,24,23,23,24,25,24,24,23,24,21,25,25,23,24,23,24,24,22,23,23,22,21,21,19,19,21,21,20,19,19,18,18,18,17,15,16,15,12,14,14,12,10,11,13,12,10,10,11,10,12,12,12,11,12,13,12,13,14,14,13,15,15,14,14,16,17,15,17,18,17,16,16,15,15,15,13,12,14,14,11,12,13,12,10,11,14,11,12,12,12,13,13,14,13,14,14,13,14,14,14,12,14,13,13,14,13,13,12,11,12,8,8,8,9,9,11,11,11,11,11,11,12,12,12,12,12,13,12,11,11,12,12,12,11,10,10,12,11,10,12,12,11,10,13,13,12,12,13,15,14,14,14,14,14,16,15,15,16,18,16,19,18,19,19,23,22,21,21,24,22,24,23,24,24,23,26,26,25,24,25,24,26,25,25,25,24,24,23,21,23,24,24,22,22,23,20,24,20,20,22,21,18],[29,29,29,29,29,29,29,29,29,29,28,28,29,27,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,29,30,29,30,30,29,30,29,29,29,29,29,29,28,28,28,27,27,27,27,27,27,26,26,25,25,24,22,20,21,20,19,20,18,19,19,19,19,18,19,19,19,22,21,23,22,21,23,24,22,23,25,25,25,25,25,25,26,26,26,25,26,27,26,26,27,26,26,26,27,26,26,26,26,25,25,26,26,27,27,25,26,25,25,24,24,25,25,24,24,26,26,24,26,26,25,24,26,25,24,24,25,25,25,25,25,26,26,26,27,26,26,26,26,26,26,25,25,26,25,25,26,26,25,25,24,25,24,24,25,25,23,23,26,25,24,24,26,24,24,25,25,22,23,24,23,24,22,23,24,24,23,24,25,23,24,24,24,22,24,24,23,24,25,24,24,23,24,24,25,25,24,25,24,24,25,25,25,25,26,25,25,26,26,25,23,25,25,24,22,24,23,20,20,23,21,18,21,19,20,18,19,20,21,18,20,22,19,20,21,20,20,20,21,19,19,20,18,19,19,19,18,20,19,18,19,19,19,19,19,21,20,19,21,22,19,21,22,22,20,22,22,22,22,23,24,22,23,22,22,23,22,19,20,21,19,19,19,19,18,17,19,18,17,17,17,17,16,16,16,15,15,14,11,12,13,13,11,11,12,10,10,9,11,12,11,12,13,14,14,15,15,16,17,16,19,17,18,18,19,18,19,20,20,21,20,20,22,21,21,22,23,22,22,23,23,22,25,25,24,25,25,26,25,26,26,25,25,24,23,24,25,24,22,23,24,25,24,24,25,25,26,26,26,26,26,26,27,26,26,27,27,27,27,26,27,27,27,28,26,26,26,26,26,27,27,27,26,27,26,26,26,26,25,24,25,24,23,24,22,23,19,18,19,16,14,15,13,13,14,12,12,11,9,9,6,6,8,6,5,6,6,5,3,6,6,4,3,5,5,5,2,1,0,1,3,4,4,5,6,6,6,6,7,6,8,10,11,7,8,10,9,7,9,10,9,8,10,9,9,11,9,11,12,11,10,10,12,10,9,11,11,10,10,11,10,11,11,12,13,13,13,13,13,12,14,14,15,16,15,16,16,15,17,17,16,17,18,16,16,18,17,16,18,17,18,17,18,18,17,18,18,20,18,19,21,19,19,19,20,20,20,22,21,22,22,22,21,23,21,23,24,23,23,24,25,25,25,25,24,25,26,26,25,25,25,24,25,25,26,24,24,24,23,23,23,21,21,21,20,19,19,19,19,18,17,18,17,17,16,16,15,13,14,15,13,13,14,12,12,12,15,14,13,15,16,15,14,15,16,16,18,17,16,17,16,18,16,18,18,17,18,19,18,20,20,19,20,22,20,19,21,23,23,24,22,24,24,25,26,25,25,25,25,26,25,25,25,24,26,24,24,26,25,26,25,24,25,25,23,23,23,22,22,22,21,22,19,20,20,19,18,18,19,18,17,17,17,14,16,15,15,14,15,14,12,11,11,13,12,13,13,13,15,16,15,17,17,16,17,17,17,16,18,17,18,18,17,19,17,18,17,18,16,16,16,15,16,16,16,13,15,16,12,12,13,14,12,12,14,14,13,14,16,13,13,16,14,15,15,17,14,15,15,14,14,14,13,14,13,12,10,11,9,9,11,12,11,12,11,12,11,13,12,13,13,14,12,12,13,11,13,12,12,12,12,12,14,13,14,14,15,13,13,15,15,14,14,15,16,16,16,16,16,16,17,16,16,17,18,18,21,19,21,21,22,22,20,21,22,22,24,23,24,25,23,25,26,24,25,25,25,24,25,25,24,23,24,24,21,21,23,24,23,24,22,22,22,23,22,21,22,20],[28,28,28,29,28,29,29,28,28,28,27,27,27,27,28,27,28,27,28,28,27,27,28,28,28,28,28,28,28,29,28,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,28,29,28,28,28,28,28,27,27,26,27,26,26,24,23,22,22,21,20,21,20,20,20,20,19,19,18,20,21,22,23,24,23,22,25,24,24,24,25,26,26,25,26,26,26,26,26,26,26,27,27,27,26,27,27,27,26,26,27,27,26,26,26,26,26,26,27,26,26,26,26,26,25,26,26,26,24,27,26,24,26,27,25,25,26,26,25,23,24,25,26,26,26,27,26,26,27,27,27,27,27,26,27,26,26,26,26,26,26,27,26,26,25,25,26,25,25,26,24,24,26,26,25,24,26,25,24,25,25,23,24,24,24,25,24,23,24,25,22,24,24,24,24,22,25,22,23,24,22,23,24,24,23,23,24,24,23,24,22,24,25,24,25,25,25,25,26,26,25,26,26,26,25,25,26,25,23,24,24,22,22,23,22,20,21,21,22,21,22,22,22,20,23,23,20,20,22,21,19,20,22,19,18,20,20,19,19,19,19,20,20,18,18,19,21,18,19,20,22,18,20,22,20,20,22,23,21,21,21,21,23,24,25,24,24,24,24,24,23,21,23,23,20,20,21,21,18,18,19,19,17,18,18,17,16,16,15,15,14,14,13,13,13,12,12,12,12,11,12,11,12,13,12,14,14,13,14,16,15,15,16,17,17,17,18,18,19,18,20,21,20,21,22,22,23,22,23,23,23,23,24,24,24,25,25,26,26,27,26,26,25,26,25,25,24,22,21,23,23,22,22,23,24,24,24,25,24,25,26,26,26,27,28,27,28,28,28,27,28,28,28,27,27,26,28,28,27,28,25,27,27,26,28,27,27,27,26,26,27,24,26,26,25,25,24,23,23,21,19,19,17,17,15,16,13,14,13,13,12,10,9,8,7,6,7,6,5,6,7,5,4,6,6,3,5,5,6,5,4,2,1,0,1,3,5,5,6,5,7,7,7,7,9,9,9,7,9,10,8,7,8,10,9,9,11,10,10,9,10,10,12,11,9,10,11,10,10,11,11,11,10,11,12,12,11,12,13,13,13,14,14,12,14,14,14,16,15,16,14,15,16,17,13,16,17,16,16,18,16,15,17,16,16,15,18,19,17,18,19,22,18,19,21,21,19,20,20,21,20,21,20,20,22,19,22,22,23,24,24,24,25,24,25,26,25,23,25,25,25,24,26,26,24,24,26,25,24,24,25,24,24,25,25,23,23,23,23,21,21,21,19,18,18,18,17,17,16,16,14,14,15,14,13,13,13,12,12,12,14,13,13,14,15,14,14,15,15,14,15,16,16,16,14,17,16,17,17,18,19,19,18,19,20,19,21,21,21,21,23,23,24,25,24,25,25,26,26,26,26,26,25,26,27,26,26,26,25,24,25,27,25,25,25,24,25,25,24,25,24,23,23,22,22,23,22,23,22,21,20,19,20,18,17,17,17,15,16,16,15,13,15,15,14,12,13,13,13,14,14,14,14,15,15,16,16,16,17,15,17,17,16,17,20,19,17,19,20,21,18,18,17,18,17,15,14,16,16,14,15,15,14,13,14,14,13,13,14,16,15,15,16,14,15,16,15,15,16,17,15,14,15,15,14,14,13,16,14,13,10,10,10,10,11,13,13,12,13,12,12,13,13,14,13,14,13,14,12,14,13,12,13,12,11,12,14,13,11,13,14,12,11,14,14,13,14,15,16,15,15,16,16,16,16,14,14,16,18,16,21,19,20,20,22,21,20,22,23,21,24,22,23,23,23,25,25,24,25,26,24,24,24,24,24,23,24,24,21,22,23,24,21,24,21,21,22,23,20,20,22,18],[29,29,29,30,29,29,30,29,29,29,28,28,29,28,29,28,29,27,29,29,28,29,30,29,29,30,30,30,30,30,29,30,30,30,30,30,29,30,30,30,30,30,29,30,30,30,30,29,29,29,28,29,29,29,28,28,28,27,27,28,27,25,24,23,24,22,23,22,22,22,23,19,21,19,22,23,24,24,26,25,24,26,26,24,26,27,27,28,28,27,27,28,28,28,28,28,29,28,29,28,28,29,28,28,28,29,29,28,28,28,29,28,29,29,28,29,27,28,27,28,28,28,28,28,28,28,27,28,28,27,27,28,27,27,26,27,27,28,28,28,28,28,28,28,29,29,28,28,28,28,28,28,28,27,28,27,29,28,28,28,28,27,27,27,27,26,26,28,27,27,27,28,26,27,27,27,25,26,26,27,26,25,25,26,27,25,26,26,26,25,26,26,24,26,26,25,26,26,25,26,26,26,26,27,27,27,27,27,26,26,28,27,26,28,27,27,27,27,27,26,26,28,26,24,26,26,24,23,26,25,21,23,22,24,23,25,23,25,23,24,25,23,24,25,24,20,23,23,20,20,22,22,20,22,21,21,22,22,21,20,20,22,19,20,23,23,19,23,24,21,22,23,24,23,22,25,25,25,26,26,25,26,23,24,25,25,21,23,24,21,20,22,23,19,20,22,21,17,20,20,17,18,18,17,17,17,17,14,16,15,14,15,15,15,12,13,11,12,14,13,14,17,16,16,17,18,18,18,19,21,17,20,19,19,21,22,22,23,24,23,25,25,23,26,26,26,25,27,26,25,28,27,27,26,28,28,28,26,28,26,26,25,24,22,24,26,24,24,23,25,25,23,25,26,26,27,27,27,28,28,28,28,27,27,28,28,28,28,28,28,27,28,28,28,28,26,27,26,27,28,27,27,28,26,27,27,25,27,25,25,26,24,25,24,23,21,21,19,19,17,18,15,16,16,14,13,11,9,8,6,7,9,5,5,9,9,6,6,9,9,6,7,8,8,7,6,4,4,1,0,1,5,4,7,8,8,7,8,8,10,12,12,10,10,11,11,10,10,11,9,8,11,11,9,11,10,12,13,13,11,11,13,12,9,13,14,10,12,13,13,12,16,14,16,18,15,17,16,14,16,15,16,18,17,18,16,16,19,18,16,18,20,18,17,20,19,17,20,19,19,18,20,21,19,19,21,23,19,21,24,23,21,23,23,22,23,25,23,24,23,22,24,25,23,25,26,26,26,27,27,27,27,28,27,28,29,28,28,27,27,27,28,27,28,27,27,26,26,25,25,24,24,24,24,21,21,22,21,19,19,20,19,18,17,17,16,16,17,16,15,15,16,14,16,14,17,16,16,15,19,16,16,18,17,17,18,18,18,18,17,19,19,19,19,20,21,19,20,22,24,21,24,24,24,24,26,26,26,26,25,27,27,28,28,27,27,27,27,28,28,28,28,28,27,27,27,27,28,28,27,27,27,27,26,26,25,26,25,24,24,25,23,23,23,22,21,21,22,19,18,19,19,17,18,18,18,16,16,16,16,13,14,16,16,16,16,17,17,18,19,18,19,18,19,18,20,20,18,20,22,20,20,22,22,23,21,20,19,19,20,18,18,19,19,16,17,18,15,16,18,17,16,17,18,19,18,19,21,18,19,21,19,19,20,19,18,18,18,18,18,18,17,17,17,14,13,12,12,13,15,15,15,16,17,17,17,18,18,17,17,17,17,17,16,16,17,16,16,16,16,15,15,14,14,15,15,13,14,15,16,14,15,17,18,18,18,18,18,16,20,18,18,19,18,20,22,22,23,23,24,22,22,22,24,23,27,23,25,26,25,27,27,26,26,27,26,26,28,28,26,26,26,26,22,24,25,25,23,26,24,25,25,25,23,23,23,21],[30,29,29,29,30,30,30,30,29,29,29,29,29,28,29,28,29,29,28,30,29,29,30,29,29,30,29,29,30,29,29,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,29,29,29,28,28,28,28,28,27,27,28,26,27,26,25,22,22,24,21,22,21,21,22,22,20,20,21,22,21,23,23,24,23,23,24,24,24,25,25,26,25,26,27,26,26,28,27,27,27,27,27,27,27,27,27,27,28,27,28,27,27,26,27,27,27,27,28,27,27,27,26,25,25,26,26,26,26,26,26,26,26,27,26,25,27,26,25,25,26,25,26,25,26,26,26,27,27,27,27,26,27,27,27,26,26,26,25,25,26,27,26,26,26,26,26,25,25,26,25,24,26,25,25,24,26,24,25,25,25,24,24,24,25,24,24,24,25,25,24,25,25,24,24,24,24,23,25,24,24,25,25,24,24,24,24,25,24,26,24,25,25,25,25,25,26,25,26,25,25,25,26,26,25,24,26,24,23,24,24,23,22,23,23,21,22,21,22,22,22,23,22,21,22,23,21,22,23,23,22,21,23,21,22,21,21,22,22,22,21,21,22,22,21,22,22,20,21,23,23,21,22,22,22,23,23,23,23,23,23,23,23,24,24,24,25,22,24,24,23,21,22,22,21,20,22,22,20,20,20,21,20,20,19,18,17,18,17,16,15,15,14,12,13,13,12,11,11,11,11,12,11,12,12,12,14,15,13,17,17,16,18,19,20,17,18,19,19,20,22,22,22,24,22,25,25,24,26,24,25,25,25,25,24,26,26,26,26,27,27,27,26,27,26,24,25,23,22,24,24,22,23,23,24,25,24,25,25,25,26,27,26,27,27,26,27,27,27,27,27,27,27,26,27,26,27,28,26,27,26,27,27,26,28,27,26,28,25,27,27,26,27,26,25,26,24,25,24,23,20,20,18,17,16,16,14,15,14,11,12,11,8,8,6,7,9,5,5,9,7,5,6,7,6,6,7,9,8,7,7,6,4,3,2,0,2,4,4,6,6,7,8,7,9,9,10,8,7,8,7,7,6,9,8,7,9,10,8,10,10,12,13,13,9,10,14,10,9,10,12,9,9,13,10,9,11,13,15,17,14,14,16,12,14,14,15,19,16,19,18,16,19,19,18,19,20,19,17,20,19,19,18,20,19,18,20,20,20,19,21,22,19,21,21,21,22,21,21,21,22,22,23,22,23,21,22,23,23,23,24,24,25,25,25,25,24,26,25,26,26,25,25,26,26,25,26,25,26,24,25,24,24,23,23,24,22,22,22,21,22,21,20,19,19,20,18,17,18,17,15,15,16,15,13,12,14,12,14,14,14,13,15,13,18,14,14,16,17,15,16,18,17,18,17,17,18,19,18,20,20,20,19,21,21,20,22,22,23,22,23,23,24,24,24,25,25,26,26,25,26,26,26,26,26,26,26,25,26,25,25,26,26,26,24,26,26,25,25,25,24,23,24,22,23,23,23,22,21,21,20,20,20,18,18,18,18,16,17,18,14,14,14,14,14,13,14,15,13,14,14,14,14,17,14,15,18,17,18,16,19,19,19,19,21,19,18,21,21,21,19,18,17,18,18,16,17,18,17,14,15,17,13,13,15,14,13,14,16,15,16,16,18,15,16,19,18,16,19,18,16,17,17,14,15,16,15,14,12,12,11,10,10,11,12,13,13,13,13,13,14,14,14,14,14,16,15,14,14,14,14,13,14,12,12,14,13,12,14,14,13,12,12,14,14,12,13,17,17,18,17,17,17,16,19,16,17,19,17,18,22,21,22,23,25,24,21,23,25,24,27,23,26,27,24,27,27,27,27,28,28,27,28,27,26,25,27,26,22,23,26,25,24,25,24,24,25,23,22,24,24,20],[29,29,28,29,29,29,30,29,29,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,29,29,28,29,28,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,27,27,27,26,26,26,25,24,23,23,22,20,19,20,17,18,18,17,18,18,18,17,17,17,18,19,19,20,20,22,20,20,23,22,21,23,22,22,23,24,23,23,24,24,24,24,23,24,25,24,24,24,24,24,23,23,24,24,22,23,24,23,24,24,23,24,22,22,21,23,23,22,22,24,23,21,23,23,22,22,23,21,21,21,21,21,22,22,23,23,23,24,24,24,23,23,24,22,23,23,23,23,21,22,23,24,23,23,21,22,22,21,21,23,22,21,22,22,21,21,22,21,21,21,22,20,20,21,21,21,21,20,20,21,20,20,21,21,22,19,20,20,20,20,19,20,21,20,19,21,21,22,21,23,20,21,22,22,22,23,22,21,22,22,22,22,23,22,22,21,22,22,21,20,21,20,19,20,20,17,18,17,18,18,18,18,18,17,18,19,17,18,18,19,18,17,19,16,17,17,18,18,17,17,17,18,18,18,17,17,18,18,16,18,19,17,18,19,20,18,19,20,20,20,19,19,21,20,21,22,20,21,22,21,21,20,21,19,19,18,18,19,17,16,18,17,16,17,15,15,14,14,14,13,13,14,12,11,12,12,10,11,12,10,10,9,10,10,10,9,11,13,12,13,13,13,14,14,15,14,15,15,16,17,17,18,19,20,19,20,21,20,22,21,22,22,21,22,22,24,24,26,25,26,26,27,25,27,25,23,24,22,22,22,23,22,23,23,24,25,24,27,25,26,27,27,27,27,28,28,28,28,28,28,28,28,28,27,28,27,28,28,26,28,26,26,27,26,27,27,26,28,25,26,26,25,26,25,25,24,23,23,21,21,19,18,17,15,13,13,11,10,10,9,8,9,5,5,4,4,4,4,4,5,4,3,4,5,5,6,6,6,5,6,6,5,5,4,3,1,0,1,2,2,4,6,6,5,7,5,5,5,5,5,4,4,4,5,5,5,5,6,6,8,7,9,10,9,8,9,9,9,8,9,9,8,9,10,9,9,10,10,12,11,12,12,12,12,13,13,14,14,15,14,14,14,15,15,14,15,16,16,15,15,15,15,15,15,16,16,16,18,17,17,18,20,18,17,19,19,19,17,17,19,18,20,18,18,20,18,20,18,21,21,20,22,22,22,22,22,22,21,21,22,22,22,23,24,22,21,23,23,21,23,23,22,21,22,21,21,21,22,21,20,20,19,19,18,16,16,16,15,15,14,14,14,14,14,12,11,13,12,10,10,13,13,11,13,14,14,12,13,14,13,14,14,14,15,13,14,15,16,16,16,18,18,17,17,17,18,18,19,20,20,19,20,20,21,21,22,22,23,23,23,23,22,22,24,24,23,23,22,24,21,23,24,22,22,21,22,22,21,22,21,20,19,20,19,20,20,19,20,19,18,18,19,17,16,15,15,15,14,15,14,13,13,14,13,10,10,10,10,10,12,12,13,13,14,15,14,15,14,15,14,15,16,15,15,17,17,15,17,18,16,16,15,15,14,14,14,15,14,14,12,14,13,11,11,13,13,10,13,13,14,14,13,16,12,13,14,13,14,13,14,12,13,12,13,12,12,12,13,10,9,8,6,7,7,8,10,11,10,12,11,12,13,13,12,13,13,12,12,11,12,10,10,11,10,9,9,11,10,9,11,11,10,12,13,12,12,11,13,14,14,14,15,14,14,15,14,14,15,15,17,18,19,19,20,22,20,20,22,21,21,24,22,24,23,24,26,26,24,24,26,26,25,27,25,25,24,26,24,22,23,25,26,23,25,22,22,24,22,21,22,21,19],[29,29,29,29,29,30,29,29,29,29,29,29,29,28,29,28,29,29,28,29,29,28,29,29,28,29,29,29,29,29,28,29,30,30,29,30,29,29,30,29,30,29,29,29,29,29,28,27,28,27,27,27,27,27,26,26,26,25,24,25,22,21,18,18,17,16,17,17,17,17,17,17,16,16,16,18,18,18,17,18,18,18,18,18,18,18,19,19,20,20,20,21,21,22,20,22,22,21,22,22,23,22,22,23,22,22,22,22,22,20,21,21,22,23,22,21,22,19,20,19,19,20,20,19,21,20,20,21,21,20,20,21,20,19,20,20,20,21,20,21,22,21,21,23,21,21,21,21,20,20,20,19,20,20,20,20,21,21,21,18,20,18,19,19,20,19,19,20,20,20,19,20,19,19,19,18,19,18,19,18,19,18,18,19,18,18,19,18,18,18,18,18,18,18,19,18,18,19,18,18,19,19,20,19,21,19,20,20,19,19,20,20,18,20,20,19,20,19,19,18,18,20,18,16,18,18,17,17,18,18,17,18,18,18,17,17,19,16,16,16,18,17,17,18,19,20,17,18,17,18,16,17,17,18,17,16,16,15,15,16,17,17,16,16,17,16,15,16,16,16,16,16,16,15,16,17,17,18,18,18,18,18,18,17,18,16,15,16,16,15,16,16,17,15,15,16,16,16,15,13,15,12,13,13,11,12,11,9,8,9,9,9,8,8,9,7,7,7,8,8,8,9,10,10,12,12,11,13,12,12,13,13,15,15,16,16,19,18,19,18,19,20,21,20,20,21,21,21,22,24,23,25,25,24,26,25,25,25,26,24,23,23,22,22,23,23,23,22,24,25,25,24,27,25,26,28,28,27,28,28,28,27,28,28,28,28,28,28,27,28,27,28,28,27,28,26,26,28,27,27,27,27,28,26,26,27,26,26,25,25,25,24,23,22,22,19,18,17,12,12,10,11,10,10,8,8,6,5,5,4,4,5,3,2,5,4,3,3,5,4,4,5,5,5,5,6,5,5,4,3,2,1,0,1,3,3,4,5,4,5,5,5,5,3,4,5,4,4,6,4,4,5,7,5,5,6,6,9,8,6,7,9,7,6,9,9,6,7,8,8,8,9,10,12,12,12,12,11,11,11,13,12,13,14,14,14,14,14,13,14,15,15,13,13,14,13,15,13,14,15,14,14,15,14,14,16,16,15,16,16,15,16,15,15,15,16,16,16,16,17,17,18,17,17,18,18,18,18,20,21,20,20,21,20,20,21,20,20,20,19,19,20,20,19,19,19,18,17,18,18,17,18,17,17,16,16,15,15,15,14,14,14,15,13,12,11,11,12,11,10,10,11,10,9,9,11,11,10,10,12,11,10,11,12,11,12,13,12,13,12,13,13,15,15,15,14,16,14,16,16,16,17,16,16,17,17,18,18,17,18,20,20,20,20,19,19,20,20,21,21,21,21,20,22,20,20,22,20,20,19,20,20,19,18,19,19,17,18,18,18,17,17,16,15,16,16,15,15,16,12,12,14,13,12,12,10,10,11,10,9,7,8,9,9,10,10,11,11,13,12,12,13,12,13,13,13,13,14,13,15,14,14,15,15,15,15,14,13,12,13,11,12,12,13,9,11,12,9,10,11,10,9,10,11,11,11,11,12,10,10,13,12,12,12,12,11,10,11,11,10,11,12,10,8,10,6,7,5,7,8,8,9,9,9,9,10,10,11,10,11,10,11,10,9,10,9,8,9,10,8,9,10,9,9,10,10,9,11,11,11,11,13,12,13,14,13,14,14,14,14,13,15,15,16,17,18,18,19,20,20,21,19,22,22,21,24,22,23,25,23,25,25,25,24,26,25,25,25,25,24,25,25,25,22,23,25,25,23,24,22,22,23,22,21,21,22,20],[29,29,28,29,29,29,29,29,28,28,28,28,29,27,28,28,28,28,28,28,27,28,28,28,28,28,28,28,28,28,28,29,29,29,28,29,28,29,29,29,29,29,28,28,29,28,28,27,28,27,28,27,26,27,26,25,26,25,24,24,21,20,18,17,17,15,16,16,17,16,17,15,15,14,15,17,17,17,17,18,18,17,18,18,18,18,20,21,21,21,21,21,22,22,21,21,21,22,22,22,23,22,21,22,22,21,21,23,22,21,22,22,22,23,22,22,22,21,20,20,21,19,20,21,21,19,20,21,21,20,21,22,19,20,20,21,21,21,21,20,22,21,22,22,21,22,22,21,20,21,20,20,20,19,20,20,22,21,21,20,21,18,19,20,20,19,18,20,18,19,19,19,18,19,19,19,18,19,19,18,18,18,19,18,18,17,18,18,17,18,17,19,17,19,18,18,20,19,18,18,19,20,19,19,20,18,20,20,19,20,21,20,19,21,20,19,20,21,19,18,18,19,18,17,18,18,16,17,18,17,16,18,18,18,17,19,19,17,17,17,17,18,17,17,17,18,16,16,16,17,16,15,16,16,16,15,15,15,17,14,15,15,14,14,16,15,13,15,16,15,14,16,18,16,16,16,17,17,17,19,18,19,18,18,17,16,15,16,15,14,15,15,15,14,14,16,16,13,14,12,13,12,12,11,10,10,10,8,8,9,9,8,8,8,7,7,7,7,8,8,7,9,10,9,11,12,10,12,11,13,12,14,14,14,15,16,16,17,20,17,19,19,19,20,20,21,21,21,22,21,22,23,24,23,25,26,25,24,26,24,22,22,21,20,21,22,20,21,21,22,22,22,25,24,24,25,25,26,26,28,27,27,27,27,27,27,27,27,26,27,26,28,27,26,27,24,27,27,26,27,26,26,28,24,26,26,25,24,25,24,24,23,23,22,21,19,16,16,11,11,10,9,9,9,7,7,6,5,4,3,4,4,4,3,3,4,3,4,4,4,4,5,6,5,4,6,5,4,4,4,3,2,1,0,1,2,3,4,4,5,4,6,4,3,4,5,4,4,5,5,4,5,5,4,5,5,7,7,7,6,6,8,6,5,7,7,6,6,8,8,8,9,9,11,11,11,11,10,10,10,10,11,12,11,13,11,11,13,12,11,13,13,13,11,12,12,12,12,12,13,12,13,13,13,13,14,15,14,15,16,15,15,15,15,15,16,18,16,16,17,16,17,17,17,18,18,18,20,19,20,20,20,20,20,20,21,19,20,20,18,19,20,20,19,20,20,19,18,19,18,17,18,17,17,14,16,15,14,14,13,13,13,12,12,11,10,10,11,10,9,9,10,9,8,8,10,10,9,10,11,10,10,10,11,10,10,12,11,11,10,11,12,13,12,13,14,14,13,15,15,14,16,16,16,16,17,17,17,18,18,20,20,21,21,19,19,19,20,21,22,20,21,20,21,20,20,22,20,19,20,20,21,19,19,19,18,17,17,16,18,17,16,15,15,15,14,13,14,14,12,12,12,11,10,11,10,9,10,10,8,7,7,8,8,9,9,10,9,11,11,10,11,11,12,12,12,12,12,12,14,13,14,14,14,15,13,13,12,12,12,11,10,11,11,9,10,10,9,9,10,10,9,10,10,11,12,11,12,10,11,11,12,12,12,11,11,12,11,11,10,11,11,10,7,7,6,6,6,6,7,8,9,10,9,9,9,10,11,10,10,10,12,10,9,9,8,8,8,9,8,8,9,9,8,9,9,8,9,10,10,9,10,11,12,12,13,13,13,13,14,13,15,15,16,17,19,19,19,20,22,21,20,21,23,21,25,21,24,24,23,26,26,24,26,27,26,24,27,26,26,24,26,25,22,23,25,26,23,24,22,22,24,25,21,22,24,21],[27,28,27,28,28,28,28,27,28,27,26,26,27,26,27,27,27,26,27,26,26,27,27,27,27,27,27,27,27,28,27,28,28,28,28,28,29,27,29,28,29,28,28,27,28,27,27,26,27,27,27,26,26,26,25,24,24,25,23,22,20,19,18,17,17,14,15,15,15,15,15,14,14,14,15,15,17,16,17,17,20,18,19,20,19,20,20,20,20,22,22,20,22,22,21,20,22,21,22,23,22,21,21,22,22,20,20,21,22,20,20,21,21,23,21,20,21,20,20,18,20,20,20,19,22,22,19,20,22,20,19,21,20,20,19,20,20,21,20,20,21,21,21,22,22,22,21,22,21,21,20,21,21,19,21,22,22,21,21,18,19,21,19,19,21,20,19,20,20,20,18,19,20,18,18,20,18,17,18,19,19,19,17,18,20,18,18,19,19,19,17,20,18,19,18,18,18,19,18,18,20,19,19,18,20,17,20,20,18,21,20,20,20,21,21,20,21,21,21,20,19,20,20,19,18,18,17,18,17,16,16,17,15,16,16,15,16,15,14,15,16,15,15,16,16,15,13,16,14,14,15,14,14,15,14,15,16,15,14,14,14,15,13,14,16,16,13,15,17,16,15,17,18,16,16,16,16,18,17,19,20,18,19,19,19,18,17,17,17,15,15,16,15,13,14,14,13,12,13,12,12,12,10,11,11,10,10,9,8,8,8,7,8,7,6,5,5,6,7,7,8,9,10,10,10,12,11,11,12,13,13,12,13,14,15,16,16,16,18,17,18,19,18,20,19,19,19,20,20,19,21,22,22,21,23,24,24,22,24,23,21,22,20,20,21,21,20,20,21,22,23,22,24,24,24,25,25,26,26,26,27,27,26,27,27,27,26,26,25,25,25,26,26,24,26,24,25,25,25,26,25,25,26,23,24,25,23,23,23,23,22,21,22,19,18,16,14,14,12,11,11,9,10,9,8,8,7,5,4,3,4,4,3,3,4,4,4,4,4,3,3,4,4,4,4,5,5,6,4,4,4,3,2,1,0,1,3,2,2,3,3,4,3,3,4,3,3,3,4,4,4,4,5,4,5,5,7,6,7,6,6,7,6,6,7,7,7,7,8,9,8,8,9,10,11,11,11,10,10,10,10,12,11,13,11,11,11,12,12,11,12,12,12,12,12,12,12,12,12,13,13,13,14,13,14,14,16,14,15,16,16,16,15,14,17,16,17,16,16,19,17,18,17,18,19,19,21,21,20,20,21,20,20,20,18,19,19,20,20,19,18,20,20,19,19,22,19,19,20,20,18,19,19,18,17,17,15,14,12,13,12,12,12,12,11,10,11,10,10,9,10,9,10,8,9,9,11,10,10,10,11,11,10,10,11,11,11,11,11,10,12,12,13,13,13,15,14,13,14,15,15,15,16,16,16,16,18,18,18,19,20,20,19,20,21,21,19,19,20,22,20,20,20,22,18,20,22,18,19,19,20,20,19,18,20,19,16,18,16,18,16,17,16,15,15,15,13,14,13,12,11,12,11,10,10,10,10,9,10,9,8,9,9,10,10,10,12,10,11,12,12,12,11,12,12,12,12,12,12,13,13,12,14,14,14,13,13,12,11,11,11,10,11,11,10,9,9,9,9,9,10,10,12,10,11,10,11,12,10,11,11,11,12,12,10,10,9,10,9,11,12,10,9,8,8,7,6,6,8,7,9,8,9,10,9,10,11,11,11,11,11,11,10,11,10,9,9,10,9,8,9,9,10,8,10,10,10,10,10,10,10,10,11,12,12,12,13,12,14,14,13,15,15,16,15,18,18,18,18,19,20,20,19,21,20,23,21,23,23,22,25,25,24,23,24,24,24,24,23,24,22,24,23,22,23,23,23,22,24,21,21,22,22,22,20,22,20],[29,28,28,28,29,29,29,29,29,28,28,27,28,28,28,27,28,28,27,28,28,27,27,28,27,27,28,27,27,28,27,28,29,29,27,28,28,28,28,28,29,28,28,28,28,28,27,27,28,26,26,26,25,25,25,24,23,23,23,22,20,19,16,16,15,14,16,14,16,14,16,14,13,13,14,15,16,15,17,16,16,17,18,17,17,19,19,19,21,20,21,21,21,21,22,21,21,21,22,23,22,22,22,23,22,22,22,22,22,21,22,22,23,22,21,21,21,20,20,18,21,20,19,20,21,21,19,22,22,20,20,22,19,18,20,20,20,21,21,21,21,21,21,23,21,22,22,21,20,21,21,20,20,19,21,21,22,21,22,20,20,18,18,20,20,18,18,20,18,18,19,20,17,17,19,19,16,18,19,18,19,16,17,19,18,16,18,19,18,18,18,20,17,18,19,18,19,20,19,18,20,19,19,19,21,19,20,20,20,21,21,21,18,22,21,19,21,21,20,18,18,20,18,15,18,17,15,15,17,15,13,15,15,15,17,17,16,15,15,16,15,15,14,15,15,15,14,15,13,14,15,13,12,14,14,15,15,15,14,14,14,14,13,14,17,13,14,15,16,14,16,16,16,15,15,16,16,18,17,19,17,18,16,16,17,16,14,14,15,13,13,13,13,12,13,13,13,12,12,12,12,11,10,11,11,10,9,9,8,9,8,9,9,8,7,7,6,7,9,8,9,8,10,9,10,11,11,11,11,13,12,13,14,15,15,14,17,16,17,18,17,18,20,19,18,19,20,20,20,21,22,23,24,23,25,24,25,25,26,24,24,23,21,21,22,23,21,21,22,23,24,22,26,24,25,26,26,27,27,27,27,27,27,27,27,28,28,27,26,27,26,27,27,26,27,25,26,27,26,27,26,26,27,25,25,26,25,25,24,25,24,23,22,21,19,18,16,16,12,11,10,10,10,9,8,9,7,5,5,4,5,4,3,4,5,4,3,5,4,3,3,4,4,3,3,5,5,5,4,4,5,3,3,2,1,0,1,2,2,2,2,4,3,2,4,5,3,3,5,4,3,5,6,4,7,6,8,8,9,7,7,8,7,6,7,8,7,7,8,8,9,9,9,10,11,10,10,11,9,11,10,12,12,11,12,11,11,12,12,11,12,13,12,11,12,13,11,12,12,11,12,14,14,12,13,13,14,13,14,16,14,14,13,13,13,15,17,16,16,16,16,16,18,17,18,18,18,20,20,20,21,21,21,20,20,21,20,21,21,19,19,21,20,20,19,20,19,17,18,17,16,16,15,15,14,14,13,12,13,13,11,12,12,12,12,11,11,10,11,10,10,9,9,9,9,10,11,11,10,10,11,11,11,11,11,12,11,12,11,11,13,12,12,12,13,12,13,13,13,14,14,15,15,14,14,15,17,18,17,17,20,20,20,20,19,19,19,19,21,21,21,20,20,22,20,20,23,20,19,19,21,20,18,19,18,17,18,16,16,15,16,14,14,13,14,13,12,14,13,11,12,12,11,11,11,11,10,10,10,10,8,8,9,10,9,10,11,11,11,11,12,12,12,11,12,12,11,12,13,13,12,13,13,13,14,13,13,12,12,12,12,11,11,13,10,10,10,9,9,10,11,9,10,10,11,10,11,10,10,10,12,11,12,12,10,10,11,11,10,10,11,10,11,8,7,6,6,6,7,7,8,8,8,8,9,9,10,11,10,12,10,12,10,9,10,10,9,9,11,9,10,9,10,9,10,10,10,10,10,10,11,10,11,12,12,13,13,12,12,14,13,13,14,15,16,17,17,20,19,20,20,20,21,20,21,23,22,24,24,23,25,25,25,25,25,25,24,25,25,26,24,25,25,22,22,24,24,23,23,21,22,22,23,21,20,21,19],[28,28,27,28,28,28,27,28,27,26,26,26,27,26,26,26,26,26,26,26,26,25,26,26,26,26,27,26,27,27,26,27,28,27,27,27,27,27,28,28,28,27,27,27,27,27,26,26,26,26,25,25,24,24,23,23,22,22,21,20,19,18,17,15,15,14,14,15,14,14,13,12,13,13,15,15,16,16,18,17,17,18,18,18,18,19,20,19,20,21,21,20,21,20,20,21,20,21,21,21,21,21,21,21,20,22,21,20,21,22,22,21,22,22,20,20,20,19,19,21,21,20,19,19,20,21,18,20,21,19,19,21,20,18,18,19,20,21,21,20,21,20,21,21,22,21,20,21,21,20,20,20,20,18,21,20,22,20,20,19,19,20,20,19,19,20,18,19,20,19,18,20,18,18,18,19,18,18,19,18,20,17,17,18,19,17,17,19,19,18,17,19,18,19,17,19,20,19,18,18,20,19,19,18,19,18,19,19,19,21,20,18,18,21,20,20,20,20,19,19,18,20,19,17,17,17,17,17,17,17,15,15,14,15,15,16,15,16,15,17,16,15,14,16,15,14,14,16,14,13,15,15,14,13,14,16,16,16,14,14,15,14,14,14,16,16,14,15,17,16,16,16,18,16,17,17,17,19,18,18,19,19,18,18,18,18,17,17,16,16,15,15,15,14,14,13,13,13,12,11,12,11,11,11,11,9,9,9,8,9,9,9,8,7,7,7,7,7,7,8,8,9,8,10,10,10,10,11,11,11,12,12,12,14,13,17,17,16,18,19,19,18,17,20,19,18,18,20,19,19,21,21,21,23,23,23,24,23,22,22,21,21,19,19,20,20,19,20,20,21,21,21,23,22,23,24,24,24,25,26,26,26,26,26,26,26,26,25,24,25,24,25,25,24,25,23,25,24,23,24,23,24,25,23,22,24,23,22,22,22,22,20,21,18,18,16,15,14,11,11,10,9,9,8,7,7,6,6,5,4,5,5,4,4,5,4,3,4,4,4,4,4,4,4,4,4,5,6,6,5,5,5,4,2,2,1,0,1,2,2,3,3,3,3,4,3,3,3,4,4,3,6,5,5,6,6,7,8,8,7,7,7,8,7,7,8,9,8,8,9,9,10,11,11,10,11,11,11,9,10,10,12,11,11,11,12,11,12,13,12,13,13,13,13,12,14,12,13,14,13,13,14,15,14,14,14,15,15,15,16,16,17,16,16,16,16,19,16,17,18,17,18,16,20,19,18,20,20,19,20,20,20,18,21,20,20,20,20,20,18,19,20,20,19,18,21,18,18,19,19,17,17,18,17,16,15,16,15,14,13,13,14,12,12,12,12,10,10,10,10,9,9,9,10,10,10,11,12,10,12,12,11,11,12,12,11,12,12,12,13,12,12,13,13,13,14,15,13,14,15,15,15,16,16,16,16,17,18,17,19,19,19,19,20,20,20,20,18,19,21,19,18,19,21,19,20,22,20,19,20,19,20,17,19,20,18,18,17,15,15,16,16,16,15,15,14,14,14,13,12,12,13,11,11,12,10,10,10,10,11,9,10,10,11,10,11,11,10,12,12,11,12,12,12,12,12,12,13,12,13,14,13,13,13,13,12,13,11,11,11,11,10,11,11,9,10,10,9,9,9,10,10,10,10,11,11,12,12,10,11,12,11,12,11,11,11,10,10,10,10,10,9,9,8,7,5,6,5,7,7,9,9,9,10,9,9,11,11,11,12,11,12,11,12,11,11,11,10,11,11,11,10,11,11,10,11,11,11,10,11,10,10,11,12,12,13,14,13,14,15,15,16,14,16,16,17,17,18,19,20,19,18,19,20,19,23,19,22,23,23,25,25,23,24,24,24,24,23,23,24,20,23,23,20,20,23,23,22,23,21,21,22,24,21,20,21,20],[27,27,27,27,27,28,28,27,27,27,26,26,26,26,26,26,26,25,27,26,26,26,26,26,27,27,27,27,27,26,26,27,27,28,27,27,27,27,28,27,27,26,26,27,28,27,26,26,26,25,26,25,24,25,25,23,22,24,22,20,19,18,17,15,15,14,15,14,14,14,14,14,15,15,14,16,17,17,19,17,18,19,18,19,20,19,21,20,20,21,21,20,20,21,20,20,22,20,20,21,21,21,20,21,21,21,21,21,20,21,22,21,21,23,21,20,20,19,20,20,21,21,19,20,20,21,19,20,21,20,20,22,21,19,19,21,20,21,21,20,21,21,20,21,22,21,20,21,21,20,21,22,21,20,20,21,21,20,20,19,19,20,18,19,21,20,18,20,21,18,18,20,20,19,19,20,18,18,19,18,20,19,20,20,20,18,19,20,20,19,19,20,20,20,19,19,20,21,19,20,20,20,20,18,19,18,20,20,20,22,21,19,19,21,21,21,22,21,20,19,20,20,20,18,20,18,19,17,18,17,18,17,15,16,16,17,16,16,15,17,18,16,15,18,17,17,16,17,16,16,16,15,17,14,15,17,17,18,16,16,16,16,16,16,17,16,16,17,18,18,18,17,19,16,17,18,18,19,19,19,19,20,19,19,18,18,17,18,18,16,17,15,16,17,16,15,14,14,13,13,15,13,12,11,11,10,10,9,9,9,10,9,9,8,8,9,7,7,8,8,8,10,9,10,11,10,11,12,11,12,11,13,13,11,14,16,16,15,18,17,19,19,17,19,19,18,18,21,19,19,21,23,21,21,23,23,23,22,22,22,20,20,20,19,19,20,20,19,20,21,21,21,24,22,24,25,24,24,25,25,25,26,25,25,25,26,26,26,25,25,23,25,24,24,25,22,25,24,24,25,24,24,25,23,23,24,23,22,23,23,21,21,21,18,18,16,15,14,11,10,10,8,10,9,8,6,6,6,6,6,5,5,4,4,5,3,3,5,4,3,3,5,3,2,3,5,5,5,4,5,6,5,4,3,3,1,1,0,1,2,3,3,2,2,4,3,3,4,5,4,4,6,6,6,6,7,8,9,9,8,9,9,9,8,9,9,8,10,10,10,9,11,11,12,12,12,12,12,11,11,12,12,12,12,12,13,13,13,13,14,13,15,13,15,14,15,14,14,15,13,14,17,16,14,15,16,17,15,16,17,17,17,16,16,17,16,19,17,17,19,17,19,18,20,20,19,20,20,19,18,20,19,18,19,20,20,19,20,20,19,18,20,20,20,20,21,19,19,21,20,18,17,19,18,17,17,17,15,16,15,14,15,15,14,13,12,12,12,12,11,11,10,11,10,11,10,13,12,12,12,13,11,13,13,12,13,14,13,12,12,14,14,15,13,13,14,15,14,15,16,16,15,17,15,16,16,18,18,18,20,19,20,19,19,20,20,20,19,19,20,19,19,19,21,19,20,21,20,20,20,20,21,19,18,19,19,18,18,16,16,17,17,17,16,15,15,15,14,16,13,13,14,13,12,12,11,11,11,11,10,9,9,9,11,10,10,10,11,11,10,12,13,12,13,11,13,13,12,12,14,14,12,13,14,14,14,13,14,13,12,11,11,12,12,9,11,11,9,9,9,11,8,10,11,10,8,11,12,8,10,13,12,10,12,12,8,10,12,10,9,11,10,10,9,6,6,6,6,7,6,9,8,7,8,8,8,11,10,10,12,12,14,10,11,12,10,11,12,11,10,11,11,12,11,12,12,11,13,12,12,13,12,12,13,14,14,15,15,16,16,15,15,16,18,17,20,19,20,20,22,22,20,20,23,22,26,21,25,23,24,26,25,24,24,26,25,24,26,25,25,23,25,24,22,21,24,25,22,24,21,21,24,23,21,20,21,20],[29,29,29,29,29,30,29,29,29,29,28,28,29,28,28,28,28,27,28,28,27,27,28,28,27,27,28,27,28,28,27,28,28,29,28,29,28,28,29,28,29,28,28,28,29,28,28,27,27,27,26,26,25,24,24,23,23,23,22,21,19,18,15,14,13,12,12,12,11,12,11,11,10,11,11,12,13,13,14,12,14,14,15,14,14,17,17,17,18,18,17,18,19,19,19,19,18,18,19,19,19,20,18,20,19,20,19,20,19,19,20,20,20,20,19,19,18,19,18,17,19,18,17,17,20,18,16,19,18,18,17,19,17,18,17,18,17,20,18,19,21,19,19,20,18,19,18,19,18,18,19,18,18,16,17,18,18,19,18,17,16,17,15,17,17,15,15,17,17,17,16,16,15,15,16,17,15,16,16,16,17,15,16,17,17,15,17,16,16,16,14,18,15,18,15,16,17,17,16,16,17,16,17,17,17,16,16,17,18,17,18,18,16,19,19,17,19,18,18,15,16,18,17,14,16,16,13,13,14,13,11,12,13,12,14,13,13,14,13,14,13,12,12,14,13,13,12,13,12,12,14,11,11,11,12,13,14,14,14,13,11,13,12,12,14,12,12,14,13,12,13,15,14,13,15,15,15,15,16,16,15,16,14,15,15,14,12,12,13,12,11,10,12,13,11,11,11,11,11,10,10,9,9,9,8,8,8,7,7,8,7,7,8,7,6,7,5,6,7,5,6,6,6,7,8,8,7,8,9,9,8,10,11,10,12,14,15,14,17,17,18,18,18,19,20,19,19,20,22,20,22,24,23,23,25,25,25,24,24,24,22,23,20,20,21,23,21,20,24,23,23,22,24,25,25,26,26,27,27,27,27,27,27,27,27,27,27,27,25,27,25,28,26,26,27,24,27,26,26,27,25,27,27,23,25,26,24,24,25,24,24,23,22,21,19,16,14,12,9,7,7,5,6,5,4,4,4,4,4,3,4,3,3,3,3,2,2,2,3,2,2,3,2,2,2,3,3,4,3,4,4,3,3,3,2,1,1,1,0,1,1,2,2,1,2,2,2,3,3,3,3,4,4,4,4,4,5,6,7,5,6,7,8,6,7,7,7,7,7,8,8,8,8,9,10,10,10,11,9,10,9,10,10,11,10,11,11,10,10,10,11,11,10,10,12,10,11,12,11,10,11,11,12,10,11,11,12,12,11,14,11,12,11,11,12,13,15,15,14,15,14,14,14,14,15,15,14,15,15,16,18,17,17,16,17,18,17,18,17,16,16,18,17,16,15,16,16,14,15,14,14,13,13,13,13,11,11,11,12,10,10,11,10,10,10,10,9,9,9,10,8,8,9,9,9,9,9,9,9,9,9,9,9,10,10,11,11,10,10,10,11,10,12,11,10,11,12,11,10,11,11,11,13,11,12,12,12,15,14,14,15,17,17,16,16,16,16,16,17,18,17,18,17,18,17,18,19,17,17,17,16,16,17,15,14,15,14,13,12,12,11,11,11,11,11,10,11,11,10,9,9,10,9,9,9,8,7,8,8,7,7,7,7,9,8,7,8,8,8,8,10,10,10,9,9,9,9,10,9,10,11,9,11,10,10,10,9,8,9,8,8,8,9,8,7,7,8,6,6,7,7,6,8,8,8,7,9,9,6,7,9,8,7,8,8,6,7,7,7,6,6,7,6,5,4,4,4,4,4,5,6,5,5,6,6,6,8,9,7,9,9,10,9,7,9,9,7,9,8,9,8,9,10,8,9,10,9,9,9,10,10,9,10,11,12,13,12,12,12,14,12,13,14,14,15,16,16,18,20,21,20,18,20,21,21,23,22,24,23,22,26,25,23,23,24,23,23,24,24,22,21,24,24,20,19,24,24,23,24,22,22,23,23,22,21,23,21],[28,28,28,28,28,28,28,28,28,27,26,26,27,27,27,27,27,26,27,26,26,26,26,26,26,27,27,27,27,27,25,28,28,28,27,28,28,28,28,28,27,27,26,27,27,27,27,26,25,25,25,24,24,24,22,21,21,22,20,18,17,15,14,13,12,11,10,11,11,10,10,10,10,10,11,12,12,12,14,12,14,15,13,15,14,15,16,15,16,17,16,16,17,16,18,16,16,16,17,17,17,18,17,16,17,18,18,17,18,19,20,18,17,17,17,17,16,18,16,17,18,16,15,16,17,16,14,17,16,15,16,17,16,15,16,16,17,16,16,17,15,16,18,17,16,16,16,16,16,17,17,17,17,15,16,16,16,16,16,15,16,16,14,14,16,14,14,15,16,14,14,15,14,14,14,16,14,14,15,14,16,15,14,14,15,14,13,15,15,14,13,15,15,14,14,14,17,15,14,15,16,15,15,15,15,15,17,15,15,17,17,14,14,17,16,15,15,16,15,15,15,16,14,14,15,15,14,14,14,13,11,12,11,12,12,13,13,13,12,13,13,11,11,13,12,12,12,13,12,11,12,12,12,12,12,13,13,14,13,13,11,12,11,13,12,13,13,12,12,12,13,13,13,13,13,13,13,14,14,14,13,13,13,13,13,13,13,13,13,12,11,11,12,12,12,11,11,11,10,9,9,8,9,8,7,7,8,6,6,7,7,6,8,7,6,6,5,5,7,6,5,6,7,7,8,8,7,8,8,8,8,9,9,8,11,11,12,13,15,15,17,16,15,19,18,17,19,20,18,17,20,22,21,20,24,23,23,22,23,22,21,21,20,20,21,21,21,20,22,22,22,22,22,23,24,24,25,25,26,26,25,26,25,25,25,25,25,25,24,25,24,25,24,23,25,22,25,24,23,25,23,24,26,22,24,25,23,23,24,22,23,22,21,18,17,15,13,12,9,7,6,5,7,5,4,4,4,4,4,4,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,2,2,1,1,0,1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,5,5,7,6,5,6,7,6,6,6,7,6,7,8,7,7,8,9,10,10,9,10,10,9,9,9,9,10,10,10,10,10,11,10,10,10,11,10,11,10,11,10,10,11,10,10,11,11,10,11,11,12,12,12,12,12,12,11,10,11,13,15,13,13,14,13,13,13,15,15,14,15,16,15,15,16,15,14,15,17,18,16,17,17,14,14,16,15,14,15,15,14,15,13,13,12,13,14,13,12,12,12,11,11,10,11,10,10,9,9,8,7,8,8,7,8,7,7,7,7,8,8,8,8,8,8,8,9,9,8,8,9,9,9,8,9,9,10,9,9,10,10,9,10,10,10,10,12,11,11,12,12,13,13,15,15,16,16,15,16,15,15,15,15,17,16,16,15,17,15,16,17,16,16,16,16,16,15,15,15,14,14,13,12,11,11,11,11,11,11,11,10,10,10,9,9,9,8,8,8,7,7,7,7,6,6,6,6,7,6,6,7,7,8,7,8,7,8,7,7,8,8,8,8,9,9,8,9,9,9,8,8,8,8,8,7,7,7,7,6,6,6,5,6,6,6,6,6,6,7,6,8,8,6,7,8,7,8,7,7,6,6,7,6,5,7,6,6,5,4,4,4,4,5,5,5,6,5,6,6,6,8,8,7,8,8,9,7,7,8,7,7,7,7,7,7,7,8,8,7,8,8,8,9,9,9,9,9,10,11,12,11,12,12,13,12,12,14,13,13,17,15,18,19,20,20,17,19,19,19,22,19,22,21,21,25,24,22,23,23,22,22,24,23,23,21,24,22,20,18,22,22,19,21,20,19,21,20,18,18,19,19],[28,28,27,27,28,28,27,27,27,25,25,25,26,26,26,26,26,25,25,26,26,26,26,27,26,26,26,26,26,27,26,26,27,27,25,27,27,27,27,27,27,27,27,26,27,26,26,24,25,23,24,24,23,23,24,22,21,22,21,18,16,16,14,12,11,10,10,10,9,10,9,9,8,8,10,10,11,12,13,11,11,13,13,11,13,15,14,14,16,16,15,17,17,16,17,16,17,17,17,17,17,17,17,17,17,19,19,18,17,20,19,20,19,18,18,18,17,18,16,17,18,16,15,17,16,16,15,18,17,15,16,19,16,15,16,17,16,16,15,17,17,16,18,17,16,17,17,16,16,16,16,15,16,14,17,17,17,16,16,17,14,14,13,14,15,12,13,16,14,13,14,16,13,13,15,15,13,15,15,14,15,13,14,14,15,13,14,15,14,14,14,15,13,14,15,15,15,15,14,15,16,14,14,15,15,15,15,14,15,17,17,15,14,17,16,15,16,16,16,13,15,15,14,12,14,13,11,11,12,12,10,10,10,11,9,11,12,12,10,13,13,11,11,13,10,10,11,12,10,10,11,11,9,10,11,12,13,13,12,11,10,11,10,10,12,11,10,12,13,11,12,12,13,11,13,13,13,13,14,15,12,15,12,13,13,13,11,11,11,11,10,10,11,10,9,9,10,9,8,8,8,7,8,7,6,7,7,5,5,6,7,6,6,6,5,6,5,5,5,5,5,5,6,5,7,6,6,7,7,7,7,8,8,8,9,11,12,13,15,15,17,14,15,18,17,17,18,20,17,17,20,21,19,18,23,21,22,21,22,21,19,20,18,19,20,20,19,20,20,19,22,20,24,22,23,22,24,24,25,25,24,25,25,25,25,25,25,25,24,25,24,24,24,23,25,23,25,23,23,25,22,24,25,22,25,25,23,23,23,22,21,21,20,18,18,16,13,14,9,6,6,5,5,4,4,3,3,3,3,3,4,3,3,3,3,2,3,3,3,2,2,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3,4,4,5,5,4,5,6,6,5,6,6,6,6,7,7,8,8,9,10,9,9,9,10,8,8,8,8,9,8,9,8,8,9,9,9,10,9,9,9,10,10,9,9,10,9,8,9,10,9,9,10,11,9,10,11,11,10,10,10,11,11,13,12,13,12,12,12,13,12,14,13,13,14,14,16,16,15,15,15,16,16,15,16,15,14,14,15,15,14,14,14,13,13,13,13,13,10,12,12,10,10,10,10,9,8,9,9,9,8,9,7,7,8,8,7,6,7,7,7,7,8,7,6,8,8,7,8,9,8,8,8,9,9,8,8,8,9,9,8,9,9,9,9,10,9,9,9,11,11,10,10,12,12,12,13,14,14,15,15,13,14,14,15,15,17,15,18,15,17,15,16,17,16,15,16,16,16,14,14,13,12,12,11,10,9,11,10,11,10,9,9,9,9,9,8,8,8,7,7,7,7,6,7,7,6,5,6,6,7,6,7,7,7,7,7,8,8,8,7,7,8,8,8,8,9,8,8,8,9,8,8,7,7,8,8,6,7,7,7,6,6,7,5,6,6,6,6,6,7,7,7,7,7,6,7,7,7,7,7,7,7,6,6,6,5,6,5,5,4,4,4,4,4,4,5,5,5,5,6,6,6,7,8,7,8,7,8,8,6,7,7,6,7,7,6,6,8,8,7,8,8,8,8,9,9,9,8,9,10,10,11,11,11,11,13,11,12,13,12,14,16,15,16,19,22,20,18,20,20,19,23,21,21,24,22,24,24,23,24,25,25,24,25,25,24,24,26,23,20,20,24,24,21,22,20,20,21,19,20,18,21,20],[29,28,28,28,28,29,28,28,28,28,27,27,28,27,27,28,27,26,27,27,27,27,27,28,27,27,28,27,27,28,26,28,28,29,27,28,28,27,29,28,28,27,27,28,28,27,27,26,26,25,25,24,24,24,23,22,21,22,19,18,18,16,13,12,11,10,10,9,9,9,8,7,8,8,9,9,10,10,11,10,10,12,12,11,12,14,14,14,15,15,16,16,15,15,16,16,16,16,17,16,17,18,17,17,17,18,18,18,17,18,18,18,17,18,16,17,16,17,15,15,16,15,14,16,16,15,14,17,17,14,16,17,15,15,16,16,17,16,16,16,15,15,17,16,16,15,17,16,14,16,16,14,15,13,15,16,15,15,15,15,14,13,11,13,13,12,12,14,13,12,13,14,12,12,13,14,12,13,14,12,14,11,13,14,13,12,13,14,13,14,13,15,13,14,14,15,16,17,14,15,16,16,15,15,16,15,16,15,15,16,16,15,14,16,15,14,14,14,14,12,14,14,12,11,13,12,10,10,11,11,9,10,9,10,10,11,10,11,10,12,11,9,10,12,10,9,11,11,9,9,11,10,9,10,10,12,13,13,11,10,9,10,9,10,12,10,9,11,12,9,10,12,12,11,12,12,12,13,13,13,12,14,10,10,12,11,8,9,10,9,8,9,9,8,8,9,9,8,8,7,6,6,7,6,5,6,6,5,5,6,6,4,5,6,5,5,4,5,5,4,5,5,5,5,6,6,5,6,6,7,7,7,8,8,11,12,14,15,15,17,18,17,18,18,18,19,20,20,19,19,22,23,21,21,25,24,25,24,24,25,21,23,21,22,22,23,22,21,23,24,22,25,25,24,25,25,26,26,27,27,27,27,26,26,26,27,26,26,26,25,25,26,25,25,26,23,27,25,25,26,25,26,27,23,25,26,25,25,25,24,25,24,21,20,18,17,16,14,11,7,6,5,5,4,4,3,3,2,3,3,3,2,2,3,2,2,2,2,2,2,2,3,3,2,3,4,4,4,4,4,4,3,3,3,3,2,2,2,2,1,1,0,1,1,1,1,1,1,2,2,2,2,3,3,3,3,4,5,5,4,4,5,4,4,5,6,5,6,7,7,7,8,9,10,10,8,9,9,7,8,8,8,8,8,8,8,7,9,8,7,9,9,8,8,9,10,7,7,9,8,7,8,9,8,7,10,10,8,9,11,9,8,9,9,10,11,13,13,11,12,11,11,13,11,13,13,13,13,14,16,16,16,15,16,17,18,17,16,16,14,14,15,14,14,13,13,12,11,11,11,10,9,10,10,8,8,9,8,7,7,8,7,7,7,7,6,6,7,7,5,6,7,6,5,6,7,6,6,7,7,6,6,7,6,6,7,8,7,7,6,7,8,7,7,8,8,8,8,9,9,8,9,10,9,9,10,10,11,11,12,13,13,15,14,13,14,13,14,16,16,15,15,15,16,15,16,16,16,16,15,15,13,13,14,12,12,12,11,11,10,10,9,9,8,9,8,8,8,7,7,6,6,6,6,6,5,5,6,5,4,4,5,5,6,5,5,6,6,6,6,7,7,7,6,6,7,7,6,7,7,7,7,8,7,8,7,6,6,6,6,5,6,5,5,4,5,6,4,4,5,5,5,5,6,6,6,7,6,5,6,7,6,7,7,6,5,7,6,5,5,6,5,4,4,3,4,3,3,4,4,5,5,5,6,6,6,7,7,7,7,7,9,7,6,7,7,5,6,6,6,5,6,7,6,6,7,7,7,8,8,8,8,8,9,10,11,11,12,12,13,12,12,14,14,15,16,16,19,19,20,20,20,20,20,20,22,22,22,23,22,24,24,25,23,24,23,25,24,24,24,23,25,23,22,22,23,23,23,22,21,20,21,20,19,20,21,18],[29,29,29,29,30,30,29,29,29,29,28,28,28,28,28,28,28,28,27,28,28,27,28,28,27,28,28,28,28,28,27,29,29,29,28,29,29,29,29,28,29,28,28,28,28,28,27,26,26,26,25,25,24,24,23,22,21,21,20,19,17,16,13,11,11,9,9,9,8,8,8,7,7,6,8,8,9,9,10,9,9,10,10,10,10,12,12,12,13,13,14,14,14,14,15,15,14,14,15,15,15,16,15,16,16,17,17,16,16,17,17,16,16,17,15,16,15,14,13,14,15,13,12,14,15,14,12,15,15,13,14,15,13,13,14,14,15,15,15,15,15,14,15,15,14,14,15,14,13,14,14,12,13,11,13,13,15,15,13,13,12,12,11,12,12,11,11,12,12,11,11,12,11,11,12,12,11,11,12,11,12,10,11,12,12,10,11,12,12,11,11,13,11,12,12,13,14,14,13,14,14,13,13,14,14,13,14,13,13,13,15,14,12,14,14,12,13,13,12,11,12,12,12,10,11,11,9,9,10,9,8,8,8,9,9,10,10,10,9,10,10,9,9,10,9,8,9,9,8,8,9,9,8,8,9,10,11,11,10,8,8,9,8,8,10,9,8,9,10,9,9,10,10,9,10,10,11,11,11,12,10,11,9,10,10,9,8,9,9,8,8,8,8,7,7,7,7,7,6,6,5,6,6,6,5,5,5,4,5,5,5,4,5,5,4,4,3,4,4,4,5,4,5,5,5,6,5,6,6,7,6,7,8,8,9,10,12,12,15,15,16,15,16,17,17,17,18,18,18,18,20,22,22,21,24,24,24,22,24,22,21,21,21,20,20,22,22,21,22,23,23,22,24,24,26,25,25,26,27,27,26,27,27,27,27,27,26,26,26,26,26,27,26,25,26,24,26,26,26,27,25,26,27,25,25,26,25,24,24,23,23,21,22,19,18,15,13,13,10,7,6,4,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,4,3,3,2,2,2,2,2,2,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,4,4,4,5,4,5,5,5,5,6,6,6,7,7,8,8,7,8,8,6,7,7,7,7,7,7,7,6,7,7,7,7,7,8,8,7,7,7,8,8,7,7,8,8,8,8,8,8,8,8,9,8,8,8,8,8,10,11,11,11,11,10,10,11,10,11,11,11,11,13,13,14,14,14,13,14,14,14,14,14,12,12,13,12,12,11,11,11,10,10,10,10,9,9,9,8,8,7,8,7,6,7,7,6,6,6,6,5,6,6,5,5,6,5,5,5,6,6,6,6,6,6,6,7,7,6,7,7,7,6,6,7,7,7,7,8,7,7,8,8,8,8,8,9,8,9,9,9,10,10,10,12,11,13,12,12,12,12,12,13,14,12,13,14,15,13,15,15,13,14,13,14,13,12,12,11,11,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,5,5,5,6,5,5,6,6,6,6,7,7,7,6,6,7,7,7,6,7,7,7,7,7,7,7,7,6,6,6,5,5,6,5,5,5,6,4,5,5,5,5,5,6,5,5,6,6,5,5,7,6,6,6,5,5,6,5,5,4,5,5,4,4,3,3,3,3,3,4,4,4,4,5,5,5,7,7,6,8,7,8,7,5,7,6,5,6,6,6,5,6,6,6,6,7,6,6,7,7,6,7,7,8,9,10,11,11,11,13,11,12,13,13,13,16,16,17,19,20,20,18,20,21,20,24,21,23,23,22,26,24,24,25,24,23,24,25,24,23,23,24,23,21,21,22,24,21,23,22,21,23,22,21,20,22,20],[28,28,28,28,28,28,28,28,28,26,27,26,27,26,26,27,26,27,26,26,27,26,26,27,26,26,27,26,26,26,26,27,28,28,27,28,27,26,28,27,28,27,27,27,27,27,26,25,25,23,24,23,23,23,22,22,20,20,20,17,15,14,11,10,9,8,8,8,7,8,7,7,6,6,7,8,8,8,9,9,10,10,10,10,10,11,11,12,12,12,12,13,12,12,13,12,13,13,13,13,14,14,14,14,14,15,15,15,15,16,16,15,14,15,13,14,13,13,13,12,14,11,12,13,14,13,12,14,13,12,13,14,12,12,13,14,13,13,13,14,13,12,14,13,13,12,13,12,12,13,12,11,11,11,12,12,13,14,12,13,12,11,9,12,11,10,10,12,11,10,11,12,10,10,11,11,10,11,11,10,11,10,10,11,11,10,11,11,10,10,11,12,10,11,11,12,13,12,11,13,13,12,12,13,13,12,13,11,12,12,13,12,11,13,12,10,12,12,11,10,11,11,10,10,10,10,8,9,9,8,8,8,8,8,8,9,9,9,8,9,9,9,8,9,8,8,8,9,8,7,9,8,8,7,8,9,10,10,9,8,8,8,8,8,9,9,8,8,10,8,8,10,9,8,9,9,10,10,10,11,10,10,9,10,10,9,8,9,9,8,8,8,8,7,7,7,7,7,6,6,6,5,5,6,4,5,5,4,4,5,4,4,4,4,4,4,3,3,3,4,3,4,4,4,5,5,4,5,6,5,6,6,8,8,9,10,12,10,14,13,16,14,14,16,15,15,16,17,17,17,18,20,21,20,22,22,22,21,23,21,18,20,19,19,19,19,20,19,21,21,21,22,25,23,24,24,25,26,26,26,26,26,26,26,26,25,26,25,24,25,24,25,25,24,25,23,26,24,24,26,22,25,26,24,25,25,24,24,23,23,23,20,21,18,17,14,12,13,8,6,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,3,3,4,4,4,4,4,4,4,4,5,4,4,5,6,5,6,7,7,8,7,7,8,6,7,6,6,6,6,6,7,6,7,7,7,7,7,8,7,7,8,7,7,7,7,7,8,8,8,7,8,8,8,8,9,8,8,8,8,8,10,11,11,10,10,10,9,10,9,11,10,11,11,11,12,13,13,12,13,13,13,12,13,13,12,11,12,11,10,11,12,10,10,10,10,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,4,5,5,4,5,5,6,5,6,6,6,6,7,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,7,8,8,8,8,9,10,9,9,11,11,12,11,11,11,11,11,12,13,12,13,13,13,13,14,14,13,12,12,13,12,12,12,11,10,10,8,8,8,8,8,8,8,8,7,7,7,7,6,6,6,6,5,6,5,5,5,5,4,4,4,4,5,5,5,6,6,6,6,6,6,6,6,6,6,7,6,6,7,7,7,7,7,7,6,6,5,6,6,5,5,6,5,4,5,5,4,4,5,5,4,5,5,5,5,6,6,5,5,6,6,6,6,6,6,5,5,5,4,4,4,4,3,3,3,2,3,3,3,4,4,4,5,4,5,6,6,5,6,6,7,6,5,6,5,5,5,6,5,5,6,6,5,6,6,6,6,6,7,6,6,7,7,8,9,9,9,10,11,10,10,11,12,12,15,14,17,18,19,19,17,17,19,17,22,19,21,21,20,23,22,23,22,22,22,21,24,22,23,20,24,22,19,20,23,22,21,23,21,20,20,23,20,19,21,19],[29,28,28,28,29,29,28,29,28,27,27,26,28,27,27,27,27,28,26,27,27,27,27,28,27,27,28,27,27,28,26,27,29,29,28,28,28,28,29,28,29,27,27,27,28,28,27,26,26,25,24,24,24,23,22,21,20,21,18,18,15,14,12,11,9,9,8,8,7,7,7,7,6,6,8,8,8,9,10,9,9,10,10,9,10,12,12,12,13,13,14,14,14,14,14,14,14,15,16,14,16,16,16,15,15,16,16,15,15,17,17,16,15,16,13,15,14,14,13,13,15,13,13,14,14,13,13,15,14,13,14,15,13,13,13,14,15,15,15,15,15,15,15,15,14,14,14,14,12,13,14,12,13,11,14,14,14,14,12,13,13,11,11,12,12,10,11,13,11,11,11,12,10,10,11,12,10,11,12,11,12,10,11,12,12,10,11,12,12,11,11,13,11,12,12,13,14,14,12,14,15,13,13,13,14,13,14,12,13,13,15,13,11,15,13,12,13,13,12,10,11,12,10,9,10,10,9,9,9,9,8,8,8,9,10,10,9,10,9,11,10,9,9,10,9,8,9,10,8,9,10,9,8,9,9,10,11,11,10,9,8,8,8,8,10,9,8,10,10,9,9,11,11,9,11,11,11,11,11,12,11,11,10,10,10,10,8,8,9,8,7,8,9,7,7,8,8,7,7,6,6,5,6,6,5,5,5,4,4,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,7,6,9,9,11,11,14,14,15,14,14,18,17,16,17,18,18,18,20,20,21,21,22,23,23,22,23,22,20,21,18,20,19,21,20,20,21,22,22,22,24,23,25,25,25,26,26,26,26,26,26,27,26,26,26,26,25,26,25,26,25,24,25,23,26,24,24,26,23,24,26,23,24,25,24,22,24,23,22,22,20,19,19,16,14,14,9,6,5,4,4,3,3,2,2,2,3,3,3,2,2,2,3,2,2,3,2,2,2,3,2,2,3,3,4,4,4,4,4,3,3,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,3,3,4,4,4,4,5,4,5,5,5,5,5,6,6,6,7,7,8,8,8,8,8,6,7,7,7,7,6,8,6,6,7,7,6,8,8,8,8,8,8,7,7,8,7,6,8,8,7,7,9,9,7,8,10,9,8,8,8,9,11,12,11,11,11,10,10,11,10,12,12,11,12,12,13,14,14,14,13,14,15,13,14,14,12,12,13,13,12,11,11,11,10,9,11,10,8,9,9,8,7,8,8,7,6,7,6,6,6,6,5,5,5,6,5,5,5,5,4,5,6,6,5,6,6,5,5,7,6,6,7,7,7,6,6,6,7,7,6,7,7,6,7,7,7,7,7,8,8,7,8,9,10,10,10,11,11,12,12,11,12,11,11,13,13,13,13,13,13,12,14,14,14,13,13,13,12,12,12,11,11,10,9,8,8,8,8,8,8,7,7,7,6,6,6,6,5,5,6,5,5,5,6,5,4,4,5,4,5,5,5,6,6,5,6,6,6,6,6,5,6,6,6,6,7,6,5,6,7,6,6,5,5,6,5,4,5,5,5,4,5,5,4,4,4,4,4,5,5,5,5,6,6,5,5,6,5,5,5,5,4,5,5,4,4,5,4,4,3,3,3,2,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,6,6,6,6,5,5,6,6,5,6,6,6,6,7,6,6,7,7,7,6,8,8,9,10,10,10,11,12,11,11,12,12,13,16,15,16,18,19,19,18,18,19,18,21,20,21,22,20,24,24,25,22,24,24,23,23,23,25,22,24,23,21,21,22,22,22,20,20,21,21,21,20,19,20,20],[29,29,29,29,29,29,29,29,28,27,27,27,28,27,27,27,28,28,27,28,27,26,27,28,27,27,28,27,28,29,27,28,29,29,27,29,28,28,29,29,29,28,28,28,28,28,27,25,27,25,24,24,24,24,23,22,21,20,18,18,15,14,11,10,9,8,7,7,7,7,6,6,6,6,7,7,7,8,9,8,7,9,9,7,9,10,10,11,11,11,13,13,13,13,13,14,12,13,15,14,15,15,14,14,16,16,16,15,15,16,15,15,14,15,13,14,13,12,12,13,14,11,11,12,14,12,11,14,15,12,13,14,12,12,13,14,15,15,14,14,13,13,15,14,13,13,14,13,12,13,13,10,11,10,12,13,12,13,12,12,10,10,10,11,10,9,9,11,10,9,10,10,9,9,11,11,9,10,11,10,11,9,10,12,10,9,11,11,10,10,10,11,9,11,12,13,14,14,11,13,13,13,12,13,13,12,13,12,12,12,14,12,10,13,12,10,11,12,11,9,10,11,9,8,9,9,8,7,8,8,7,7,7,8,9,8,9,9,8,9,9,8,8,9,8,8,8,8,8,8,8,8,7,7,8,9,10,10,8,7,7,8,7,7,8,8,7,8,9,7,8,9,9,8,9,10,10,10,10,10,9,10,8,8,9,8,7,7,8,7,7,7,7,6,6,7,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,3,4,4,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,8,10,11,12,13,15,15,15,16,17,16,17,18,19,18,17,21,21,21,21,23,23,24,23,24,21,20,22,20,19,20,22,21,19,21,23,22,23,25,24,26,26,26,27,27,27,26,26,26,27,26,27,26,26,26,27,25,26,26,25,26,23,26,25,25,27,24,26,27,22,24,26,25,23,24,22,23,21,20,18,17,14,14,12,9,6,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,6,7,7,7,6,7,7,5,6,6,6,6,6,6,6,5,7,6,6,7,7,6,6,7,7,6,6,7,7,6,6,7,7,6,7,7,7,7,8,7,7,7,7,8,9,10,11,10,9,9,9,10,9,10,10,9,10,11,13,13,14,13,13,14,13,13,13,12,11,11,12,11,10,9,9,10,9,9,8,8,7,8,7,7,7,7,6,6,6,6,6,5,5,5,5,4,5,5,4,4,5,4,4,4,5,5,5,5,6,5,5,6,6,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,7,8,8,9,8,9,10,10,12,11,9,11,10,10,12,13,12,12,13,13,11,13,12,12,12,11,12,11,10,10,10,9,9,8,8,8,8,8,7,7,7,6,6,6,5,5,6,5,5,5,5,4,4,5,4,3,4,4,4,5,5,4,5,5,5,5,6,6,7,6,5,6,6,5,6,6,6,5,6,6,6,6,5,5,5,5,5,5,5,4,4,4,5,4,4,4,4,5,4,5,5,5,6,5,4,5,6,5,5,5,5,5,4,5,4,5,4,4,4,3,3,3,2,3,3,3,4,4,4,5,5,5,6,6,6,7,6,7,6,5,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,8,9,9,10,10,11,11,10,11,13,13,14,15,17,19,20,19,18,20,20,19,23,20,22,22,20,25,23,22,23,24,23,24,24,23,23,22,23,22,19,21,22,22,20,22,22,20,21,22,19,20,22,18],[30,30,29,29,30,30,30,29,29,28,28,28,29,28,28,28,28,28,27,28,28,27,28,28,27,27,29,28,28,28,27,28,29,29,28,29,29,28,29,29,29,28,28,28,28,28,27,26,27,26,25,25,25,24,22,24,22,22,21,20,17,16,13,10,10,9,7,8,7,7,6,6,6,6,7,7,7,8,9,8,8,9,9,9,9,10,10,11,11,12,12,12,12,12,13,12,12,12,13,13,14,14,13,14,14,14,14,14,14,15,15,14,14,14,13,13,13,12,11,12,13,11,11,12,13,12,11,13,12,11,12,13,11,12,12,13,12,13,13,13,13,12,13,13,12,13,13,12,11,12,12,10,11,10,12,12,13,13,12,11,11,10,10,10,10,9,9,10,10,9,10,10,9,9,10,10,9,9,10,10,10,9,9,10,10,9,10,10,10,10,10,11,9,10,10,11,12,12,11,12,13,12,12,13,13,12,12,11,12,12,13,12,10,12,12,10,11,11,10,9,10,10,10,8,9,9,8,8,8,8,7,7,7,8,9,9,8,9,8,9,9,8,8,9,8,8,7,8,8,7,8,8,7,8,8,9,9,9,8,8,7,8,8,7,8,8,8,8,9,8,8,9,9,8,9,9,10,10,9,10,9,9,9,9,9,8,8,8,7,7,7,7,7,7,7,7,7,6,6,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,3,3,3,3,4,4,4,4,5,5,4,5,5,5,5,6,7,7,9,10,11,11,15,15,17,16,15,17,18,16,17,19,19,18,19,22,22,21,23,23,24,23,24,21,20,21,19,19,19,21,21,20,21,23,23,23,26,24,26,26,26,27,27,28,27,27,27,27,27,27,27,27,26,27,26,26,26,24,27,24,25,27,25,26,26,25,27,24,23,25,24,24,24,23,22,20,20,17,17,15,13,13,9,6,5,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,4,4,3,3,3,3,2,3,3,3,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,3,3,4,3,3,4,4,4,4,5,4,4,5,6,5,6,7,8,7,7,8,7,6,6,6,6,6,6,6,6,6,7,7,6,7,7,7,7,7,7,7,7,7,7,6,8,7,7,7,8,8,7,8,8,8,8,8,8,8,10,11,11,10,10,10,9,9,9,10,10,10,10,11,12,13,13,12,12,13,12,12,13,12,11,11,12,11,10,10,10,10,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,5,5,4,4,5,4,4,5,5,5,5,6,6,6,5,6,6,6,6,7,7,7,6,6,7,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,9,9,9,10,10,11,11,10,10,10,10,11,12,11,12,12,13,12,13,13,12,12,12,12,12,12,11,11,10,9,9,8,8,8,8,8,7,7,6,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,5,5,5,5,5,6,6,6,7,6,6,6,6,6,6,6,7,6,6,7,7,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,6,5,5,6,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,2,2,3,3,4,4,4,4,5,5,6,6,6,7,7,7,6,5,6,6,5,5,6,5,5,6,6,5,6,6,6,5,6,7,6,6,6,7,8,10,10,10,10,11,11,11,12,12,13,14,14,16,18,18,17,17,18,18,17,21,19,21,21,20,23,23,22,22,23,22,23,23,23,21,22,23,22,19,20,23,22,21,23,20,21,22,22,21,20,21,20],[28,28,28,28,28,28,27,28,28,26,26,26,27,26,26,26,26,27,26,26,27,26,26,27,26,26,27,27,27,27,26,27,27,28,27,28,27,27,28,28,28,27,26,27,28,27,26,25,26,24,24,24,23,23,22,21,20,22,20,18,16,14,12,10,9,8,7,7,6,7,6,6,5,6,7,7,7,8,8,8,8,9,9,8,9,10,10,11,11,11,11,11,11,12,12,11,11,12,12,12,13,13,13,12,13,13,13,13,13,14,14,13,13,14,12,13,11,12,12,12,12,11,11,12,12,12,11,12,11,10,11,12,11,11,11,13,12,12,12,12,12,12,13,12,12,12,12,12,11,11,11,10,11,10,12,12,12,12,11,11,10,10,10,10,10,9,10,10,10,9,9,9,10,9,10,10,10,10,10,10,10,10,9,10,10,9,10,10,9,10,10,11,9,10,10,12,12,12,11,12,12,12,11,12,12,12,12,11,11,12,12,11,10,12,11,10,11,11,10,9,10,10,9,9,9,9,9,8,8,8,7,7,7,8,8,9,8,9,9,9,9,8,8,8,8,8,8,8,8,8,8,8,7,8,8,8,9,9,8,7,7,8,8,7,8,8,8,8,8,8,8,9,9,9,9,9,9,10,10,10,9,9,9,9,9,9,8,8,8,8,8,7,8,7,6,7,7,6,5,5,5,5,5,5,4,4,5,3,4,4,4,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,5,7,7,8,10,11,10,14,16,16,14,14,17,16,14,17,18,17,17,20,20,20,19,21,21,22,21,22,21,19,20,19,19,19,20,21,19,20,22,21,22,26,23,24,23,25,26,26,26,25,26,25,26,26,25,26,25,25,26,24,25,24,24,25,22,25,24,24,26,23,24,26,23,24,24,24,23,23,22,22,21,20,18,16,15,13,13,9,6,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,4,4,3,3,3,2,2,2,2,2,3,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,6,6,7,7,7,7,7,6,6,6,6,6,6,6,6,6,7,7,6,7,7,7,7,7,7,7,7,7,7,6,7,8,7,7,8,8,7,8,8,8,8,8,8,8,9,11,10,10,10,9,9,9,10,10,9,10,10,11,12,12,12,12,13,13,12,12,12,11,11,11,12,11,10,10,10,10,9,9,9,9,8,8,9,8,7,7,8,6,6,7,6,5,5,6,5,4,5,5,4,4,5,4,4,5,5,5,5,6,6,5,5,6,6,5,6,7,6,7,6,6,7,7,6,7,7,7,7,7,7,7,7,7,8,7,8,8,8,8,9,10,10,11,10,10,10,10,10,11,12,11,11,11,12,12,12,12,12,11,12,12,11,11,11,10,10,9,8,8,7,8,7,7,7,6,6,7,7,6,6,6,5,5,6,5,4,4,5,5,4,4,4,4,5,5,5,5,6,5,5,6,6,6,6,6,6,6,5,6,6,7,5,6,6,6,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,5,5,5,5,5,6,5,6,5,5,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,2,3,3,3,4,4,4,5,5,5,6,6,5,6,6,7,6,5,6,5,5,5,6,5,5,6,6,5,6,6,6,6,6,6,6,6,7,7,7,9,9,9,10,11,10,10,11,12,13,15,14,15,18,18,17,16,19,18,17,21,19,21,21,20,24,23,22,23,24,23,22,24,24,24,21,22,23,21,20,22,22,21,22,20,20,21,22,20,19,20,19],[28,28,28,28,28,29,28,29,28,27,27,26,27,26,26,27,27,27,26,27,27,26,27,27,26,27,27,27,27,28,26,28,28,29,27,28,27,28,28,28,29,28,27,28,28,28,27,25,26,25,24,25,24,23,22,22,20,20,18,18,15,14,11,9,9,7,6,7,6,6,6,5,5,5,6,7,7,8,8,8,7,8,8,7,8,10,9,10,11,10,11,11,11,11,12,11,12,12,12,12,12,12,12,13,13,13,13,13,13,13,14,13,12,12,12,12,12,11,11,11,12,10,10,12,12,11,11,12,12,10,11,12,11,11,12,12,12,13,12,13,12,12,13,12,11,11,12,11,10,11,11,9,10,9,11,11,11,11,10,11,10,9,9,9,10,9,9,10,10,9,9,10,9,9,10,10,9,9,10,9,10,8,9,10,9,9,10,10,9,10,10,10,9,10,11,12,12,12,11,12,13,12,12,12,13,12,12,11,11,11,12,11,10,12,11,10,10,11,10,8,9,10,8,8,9,8,8,7,8,8,7,7,7,8,8,8,8,9,8,9,9,8,8,9,8,7,8,8,7,7,7,7,7,8,7,8,9,9,8,7,7,7,7,7,8,7,6,8,8,7,8,9,8,7,8,9,9,10,9,10,9,9,8,7,8,8,7,7,7,7,6,6,7,6,6,7,6,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,4,4,3,3,4,3,3,4,4,4,4,5,4,4,4,5,5,5,6,5,7,9,11,12,13,15,16,15,15,17,16,16,17,18,17,17,19,21,20,21,22,21,24,21,22,21,19,22,20,17,20,22,22,21,21,23,23,24,26,23,26,26,25,26,27,27,27,27,27,27,27,27,27,27,26,27,26,26,26,25,26,23,26,26,25,27,24,26,27,24,25,26,25,24,25,22,23,23,20,18,17,15,13,13,9,6,4,3,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,4,4,3,4,3,2,2,2,2,3,3,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,3,3,3,3,4,3,4,4,4,4,5,5,5,6,7,7,7,7,7,7,7,5,6,6,6,6,5,6,5,5,6,6,5,6,7,6,6,7,7,5,6,7,6,5,6,7,6,6,7,7,6,7,8,7,7,7,7,8,9,10,11,10,9,8,8,9,8,10,10,9,10,11,12,11,11,12,12,13,11,12,11,11,10,10,11,10,10,10,9,9,8,8,8,7,7,7,7,6,6,6,6,5,5,6,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,5,4,5,5,5,5,6,6,6,5,6,6,5,6,6,6,6,6,6,6,6,7,7,7,6,7,8,8,8,8,10,9,10,10,9,10,10,10,11,11,10,11,11,11,10,11,11,11,11,10,11,10,9,10,10,9,9,8,7,7,7,7,7,6,6,6,6,5,5,5,5,4,4,5,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,6,5,5,5,4,4,4,4,4,4,5,4,4,4,4,3,4,4,4,4,4,4,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,3,4,3,3,3,2,2,2,3,3,3,3,3,4,4,4,5,5,6,5,6,5,6,6,5,5,5,5,4,5,5,4,5,5,5,5,6,5,5,5,6,6,6,6,7,7,9,9,9,10,11,11,10,11,12,13,15,15,15,19,19,18,17,18,17,18,21,19,20,21,20,22,23,22,22,22,22,23,22,22,24,20,22,23,21,20,21,22,21,22,20,20,21,22,19,20,22,20],[29,30,29,29,29,29,29,29,28,28,28,28,28,27,28,27,28,28,27,28,28,27,27,28,27,28,28,28,28,28,27,28,29,29,28,29,29,28,29,29,29,28,28,28,28,28,27,26,27,26,25,25,25,24,22,22,21,21,20,18,16,14,11,9,8,7,7,7,6,6,6,5,5,5,6,6,7,7,7,7,7,8,8,7,8,8,8,9,10,10,10,11,11,11,11,11,11,11,12,12,11,13,12,12,13,14,14,13,14,13,14,13,12,12,11,12,11,10,10,10,11,10,9,11,12,10,10,12,11,10,10,11,9,10,11,12,11,11,12,11,11,10,11,12,10,11,11,10,10,10,10,9,9,8,10,10,11,11,10,10,9,9,9,9,9,8,8,9,9,8,8,9,8,8,9,9,8,8,9,8,9,8,8,9,9,8,8,9,8,8,9,9,8,9,9,10,11,11,9,11,11,10,10,11,11,11,11,10,10,10,11,10,8,10,10,9,9,9,9,7,8,9,8,7,8,7,7,7,7,7,6,7,7,7,8,7,7,8,7,8,8,8,7,7,7,6,7,7,6,6,7,7,6,6,7,7,8,8,7,6,6,7,6,6,7,7,6,6,7,7,7,7,8,7,7,8,8,8,8,9,8,8,7,7,7,7,6,7,6,6,6,6,6,5,5,6,5,5,5,4,4,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,7,6,7,10,11,11,14,16,15,14,15,17,16,15,17,18,17,18,19,21,22,21,23,23,24,22,24,21,21,22,20,19,20,22,20,20,21,24,23,24,26,25,26,26,26,27,27,26,26,27,26,27,26,27,27,27,26,27,27,27,26,25,27,25,26,27,25,26,25,26,27,25,24,26,24,24,23,23,22,21,21,18,17,15,13,12,9,6,4,3,3,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,6,6,6,6,6,5,5,5,5,5,4,5,5,5,5,5,5,5,6,5,5,6,6,5,6,6,6,5,6,6,6,6,6,6,6,6,7,7,6,7,7,7,8,9,9,9,9,8,8,8,8,8,9,8,9,10,10,11,11,10,11,12,12,11,11,11,10,10,10,9,8,8,8,8,7,7,7,7,6,7,7,6,6,6,6,5,5,5,5,4,5,4,4,4,4,4,3,3,4,3,4,4,4,3,4,5,5,4,4,5,5,5,5,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,6,6,7,7,8,7,8,9,9,10,9,8,9,9,9,10,10,10,10,11,11,10,11,11,11,11,10,10,10,9,9,9,8,8,7,7,7,7,7,6,6,6,6,5,6,5,5,5,4,4,4,5,4,4,4,4,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,4,5,5,4,5,5,6,5,5,5,5,6,5,4,5,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,4,4,4,4,3,4,4,3,3,3,3,3,2,2,2,2,3,3,3,4,4,4,4,4,5,5,5,6,5,6,5,4,5,5,4,4,5,4,4,5,5,4,4,5,5,4,5,5,5,5,5,6,7,8,9,9,10,11,9,10,11,13,13,14,15,16,19,18,18,17,18,18,17,21,19,20,21,20,23,22,22,22,23,21,23,23,21,21,22,22,21,19,22,23,22,20,22,22,21,22,23,19,20,21,18],[29,28,28,28,29,29,28,28,28,27,27,26,27,26,26,27,26,27,26,26,27,27,26,27,27,27,27,27,27,27,26,27,28,28,27,28,27,27,28,27,28,27,26,27,27,26,26,25,25,24,24,24,23,23,22,22,21,22,20,18,16,14,12,9,8,8,7,7,6,7,6,6,5,6,6,6,6,7,7,8,8,8,8,8,8,8,9,9,9,9,9,10,10,10,9,9,10,10,10,10,11,10,10,11,11,11,11,11,11,12,12,11,10,11,10,10,10,9,9,9,10,9,9,9,10,9,9,10,9,9,10,10,9,9,9,11,10,11,10,10,11,10,10,10,9,9,10,9,9,9,9,8,9,8,9,9,10,10,10,9,9,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,10,10,10,9,10,10,10,10,10,10,10,10,9,9,10,10,9,8,9,9,8,9,9,8,8,8,8,8,8,7,7,8,8,7,7,7,7,7,7,8,7,7,7,8,7,7,7,7,7,7,6,6,7,7,6,7,7,6,6,7,7,8,8,7,7,7,7,7,7,7,7,7,7,7,8,7,7,7,7,8,7,8,8,8,8,7,8,8,8,8,7,7,7,7,7,7,6,6,6,6,6,5,6,5,5,4,4,5,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,5,6,7,7,8,10,10,11,14,15,15,14,15,16,16,14,16,17,17,16,19,20,19,19,21,21,23,20,22,20,18,19,19,18,18,20,20,19,20,22,22,23,26,23,24,24,25,25,26,25,24,25,25,25,25,26,26,26,24,25,24,25,25,23,25,23,23,24,23,25,24,24,26,23,23,24,23,22,21,23,21,20,20,17,17,14,13,12,8,6,4,4,4,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,4,4,3,3,2,2,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,2,2,3,3,2,3,3,3,3,3,4,4,4,4,5,5,6,6,7,7,7,7,6,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,6,7,7,7,6,7,7,7,8,10,9,9,9,8,7,8,8,9,8,8,9,9,10,10,10,11,11,11,11,10,10,10,9,9,10,9,8,8,8,8,8,8,7,8,7,7,7,7,7,6,6,5,6,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,9,9,8,8,8,8,9,9,9,9,10,11,10,10,11,10,10,10,10,10,10,9,9,8,7,7,7,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,5,4,3,3,3,4,4,5,4,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,5,6,6,6,5,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,4,5,4,4,4,4,3,3,3,4,3,3,2,2,2,2,3,3,3,3,3,4,4,4,5,5,5,5,6,6,5,4,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,6,6,5,6,6,7,8,9,9,10,10,10,10,10,12,13,14,14,15,18,18,17,16,17,17,16,19,18,20,19,20,22,23,21,21,23,22,22,23,23,23,20,22,22,18,19,22,22,19,22,20,20,21,22,20,20,20,18],[27,28,27,27,27,28,27,27,27,26,26,26,27,26,26,27,26,26,26,26,26,26,26,27,26,26,27,26,26,27,26,27,27,28,26,27,27,27,27,27,27,26,26,26,27,26,26,24,25,24,24,23,23,23,22,22,20,21,20,18,16,14,11,10,9,7,6,7,6,6,5,5,5,5,6,7,7,8,8,8,8,8,8,8,9,9,9,9,10,10,10,11,11,10,11,11,10,10,12,12,11,11,12,11,11,12,12,11,11,12,13,11,11,11,10,10,10,10,10,10,10,9,10,10,10,10,10,10,10,9,10,11,9,10,11,11,12,11,11,11,11,11,11,11,10,10,11,10,9,10,10,9,9,9,10,10,10,10,10,9,10,9,9,9,9,9,9,9,9,9,9,9,9,8,9,9,9,9,9,9,9,8,8,9,9,9,9,9,9,9,9,9,9,9,10,10,11,11,10,11,11,11,11,11,12,11,11,11,11,10,11,10,9,11,11,9,10,10,9,9,8,9,9,8,8,8,8,7,8,8,7,7,7,7,8,8,8,8,8,8,8,7,8,8,7,7,7,7,7,7,7,8,6,7,8,8,8,8,8,7,7,7,7,7,8,8,7,8,8,8,8,8,8,8,8,9,8,10,9,9,8,8,8,8,8,8,8,7,8,8,7,7,7,6,6,6,6,6,5,5,4,4,5,4,4,4,4,3,4,4,4,3,4,4,4,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,6,6,8,10,11,11,14,16,16,14,14,17,16,15,17,19,17,17,20,21,19,21,22,20,22,20,23,20,18,19,18,18,19,20,20,19,20,21,22,22,25,24,24,24,25,26,26,26,26,26,26,27,26,26,26,26,25,26,25,26,24,25,25,23,25,24,24,26,22,24,26,24,24,24,24,22,23,21,22,21,20,18,18,14,12,12,8,7,5,4,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,3,4,4,4,4,4,4,4,3,3,2,3,3,3,4,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,2,3,3,3,3,4,4,4,4,5,4,4,5,6,5,6,6,6,7,7,7,7,6,6,6,6,6,5,6,6,6,7,6,6,7,7,6,7,7,7,6,6,7,7,6,7,7,7,7,7,8,7,7,8,8,7,7,7,8,9,10,10,10,10,9,8,8,9,9,9,9,9,10,11,11,11,11,11,12,12,11,11,10,10,10,10,10,9,9,9,9,8,8,8,8,7,8,8,7,6,7,7,6,6,6,6,5,5,6,5,4,5,5,4,4,5,4,4,5,6,5,5,6,6,5,6,6,6,6,6,6,6,7,5,6,7,6,6,7,7,6,7,7,7,6,7,7,8,6,7,8,8,8,8,9,9,10,10,9,9,9,9,10,10,10,10,10,11,10,11,11,11,10,11,10,9,10,10,9,9,9,8,8,7,7,7,7,7,6,6,6,6,5,6,6,5,4,6,5,4,4,5,4,3,4,4,4,5,5,5,6,6,5,6,6,6,6,6,5,6,6,5,6,6,6,5,6,6,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,4,4,5,5,5,6,6,6,6,5,6,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,2,3,3,3,4,4,4,4,5,5,5,6,6,6,6,6,7,6,5,5,5,5,5,6,5,5,6,6,5,6,6,6,5,6,6,6,6,7,7,8,8,9,9,10,11,11,10,11,12,13,14,14,15,17,17,17,16,17,17,16,19,18,19,19,19,22,21,21,22,22,22,21,23,22,22,20,22,22,19,20,21,22,20,21,20,21,20,22,20,19,19,18],[28,29,29,28,29,29,28,29,28,27,28,27,28,27,27,28,27,28,27,27,27,26,27,27,26,27,28,28,28,28,26,28,29,29,27,29,28,28,29,28,29,28,28,28,28,28,27,26,27,26,25,26,25,24,23,23,22,21,20,20,16,15,11,9,8,6,6,6,6,6,5,4,5,4,6,6,7,6,7,7,6,7,7,7,7,8,7,8,8,8,9,9,9,9,9,9,9,9,11,9,10,10,10,10,11,11,11,11,11,11,12,11,10,10,9,9,9,9,8,9,10,9,8,9,10,9,8,10,9,8,9,10,8,9,10,11,10,10,10,11,9,9,10,9,8,8,9,8,8,9,8,8,8,8,8,8,9,9,8,8,8,8,8,8,8,8,7,8,8,8,7,8,8,7,8,8,8,7,8,7,8,7,7,8,7,7,8,8,7,7,8,8,7,8,9,9,10,9,9,10,10,9,10,10,11,10,9,9,9,9,9,9,7,9,8,7,7,8,7,7,7,7,7,7,7,7,6,7,7,6,6,7,7,7,7,7,7,7,7,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,7,7,8,8,7,6,6,6,5,6,7,6,5,6,7,6,6,7,7,6,7,7,8,8,7,8,7,7,6,6,6,6,6,6,6,6,5,5,6,5,5,5,6,5,5,5,4,5,4,4,4,4,4,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,5,5,5,5,6,7,10,10,11,14,15,16,16,15,17,16,18,18,19,19,19,20,23,22,23,24,23,25,22,25,22,21,22,20,20,21,22,24,22,22,25,24,26,28,25,27,27,27,28,28,28,28,28,28,28,28,28,28,28,27,28,27,28,27,27,27,24,27,26,26,27,25,26,27,24,24,25,24,24,24,22,22,21,20,17,16,12,12,11,8,6,4,3,3,3,2,2,1,1,1,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,4,5,4,4,4,4,4,3,3,3,3,3,4,4,3,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,5,6,6,7,7,7,7,6,5,6,5,5,5,5,5,4,4,5,5,4,5,6,5,5,6,6,5,5,5,5,5,5,6,5,5,6,6,6,6,7,6,6,6,6,7,8,9,9,9,8,7,7,8,7,7,8,8,8,9,9,10,10,10,9,11,10,10,9,9,9,8,9,8,8,7,7,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,3,3,4,3,3,3,4,4,3,4,4,4,4,5,5,4,5,5,5,5,4,5,5,5,5,6,5,5,6,6,6,5,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,10,9,10,9,10,9,9,9,9,9,8,9,8,8,8,7,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,3,3,4,3,3,3,3,4,4,4,4,5,5,4,5,5,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,4,4,4,4,3,4,4,4,3,4,3,3,3,4,4,4,4,4,5,5,5,5,4,5,5,5,4,4,4,4,4,4,3,3,4,4,3,2,2,2,2,3,3,3,3,3,4,5,4,5,5,6,5,6,5,6,5,4,5,4,4,4,5,4,3,4,4,4,4,5,5,4,5,5,5,5,5,6,7,8,9,9,10,11,10,10,11,13,13,15,15,16,19,18,18,17,18,17,18,20,19,20,20,21,22,22,23,22,21,22,23,22,22,24,21,22,23,19,21,23,22,21,23,22,21,22,22,19,19,21,19],[29,28,28,28,28,28,28,28,27,27,26,26,27,25,26,26,26,27,26,27,26,26,26,27,27,27,27,27,27,27,27,27,28,29,27,28,28,27,28,28,28,27,27,27,27,27,26,25,26,25,25,24,23,22,21,21,20,20,19,18,15,14,12,8,8,7,6,6,6,5,5,4,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,9,8,8,8,9,9,9,9,10,9,9,10,10,10,10,11,11,10,9,9,9,8,9,8,8,8,9,8,8,8,8,8,8,9,8,8,8,8,8,8,9,9,9,9,9,9,8,8,9,8,8,8,8,7,7,8,8,7,7,7,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,7,7,7,7,6,7,7,6,7,7,6,7,7,7,6,7,7,6,7,7,8,9,8,8,9,9,8,9,9,9,9,9,8,8,8,9,8,7,8,7,7,7,7,6,6,6,6,6,6,6,6,5,6,6,5,5,5,6,6,7,7,6,7,7,7,7,6,6,6,6,6,5,6,5,5,5,5,5,5,6,6,7,7,6,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,7,6,7,6,6,6,6,6,6,5,5,5,5,5,5,5,4,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5,6,6,7,9,10,10,13,14,15,14,14,16,16,15,16,17,17,16,18,20,21,20,21,21,23,21,23,20,19,19,19,19,19,21,22,20,21,22,23,25,27,24,25,26,26,26,27,26,26,26,26,26,26,27,27,27,24,26,25,25,26,24,25,23,24,25,23,25,24,23,26,23,23,24,23,22,21,21,21,19,20,17,15,14,13,12,8,6,4,3,3,2,2,2,1,1,1,1,2,2,2,2,3,3,2,3,3,3,3,4,4,4,4,5,4,4,4,4,4,3,3,3,4,3,4,4,4,4,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,1,2,2,2,2,3,2,3,3,3,3,4,4,4,4,5,5,6,6,6,6,5,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,6,6,5,6,6,7,7,8,8,8,8,7,6,6,6,7,7,7,7,7,9,9,9,9,9,10,10,9,9,9,9,8,8,8,7,7,7,7,6,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,5,5,5,4,5,5,5,5,5,5,5,5,6,6,6,5,6,6,6,6,6,7,7,8,7,7,7,7,7,8,8,8,8,9,9,9,10,10,10,9,10,9,8,9,8,8,8,7,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,4,4,4,5,5,4,5,5,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,4,4,5,4,4,4,5,4,3,4,4,4,3,4,4,4,4,5,5,5,5,5,4,5,5,5,5,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,3,3,4,4,4,4,5,5,5,5,5,5,5,6,6,5,5,5,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,5,6,7,8,7,9,8,9,10,9,11,12,12,13,15,17,17,16,15,16,16,16,19,17,18,19,20,22,22,22,22,23,21,23,21,21,21,21,21,21,18,19,22,21,18,22,19,20,20,22,18,18,20,19],[29,29,29,28,29,29,28,29,28,27,28,27,28,27,27,27,27,28,27,27,28,26,26,28,27,27,28,28,28,28,27,27,29,29,28,29,28,28,29,28,29,28,28,28,28,28,27,26,27,26,25,25,26,23,22,24,22,21,20,19,16,15,11,10,8,7,6,6,6,5,5,4,5,4,5,5,6,6,6,6,6,6,6,6,6,7,7,7,8,8,8,9,8,8,9,8,8,8,9,9,9,9,10,9,9,10,10,9,9,11,11,9,8,9,9,9,9,9,8,8,9,8,8,8,8,8,8,9,8,8,8,8,8,8,9,10,9,9,9,9,8,8,9,8,8,7,8,7,7,8,8,8,7,7,8,8,8,9,8,9,8,8,7,8,7,7,7,8,8,7,7,7,7,7,7,7,7,7,7,6,7,7,6,7,7,6,7,7,7,6,7,7,7,7,7,8,9,8,8,9,9,9,9,9,9,9,8,8,8,8,8,7,7,8,7,6,7,7,6,6,6,7,6,5,6,6,6,6,6,6,5,6,6,7,7,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,6,7,7,6,6,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,7,6,6,7,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,4,3,2,3,3,2,2,3,3,2,2,2,2,2,2,3,3,4,3,4,4,4,4,5,4,5,6,6,7,8,10,12,11,13,14,15,15,17,17,17,17,18,19,18,20,20,22,23,22,24,24,25,24,25,21,21,23,22,20,21,23,23,22,23,24,24,25,26,26,26,27,27,27,28,28,28,28,28,28,28,28,28,28,27,28,27,28,28,26,27,26,27,27,26,27,26,26,28,25,23,25,25,24,24,23,23,22,19,18,16,15,13,11,9,7,5,4,4,3,3,2,1,1,2,2,2,2,2,2,3,2,3,4,4,4,4,5,4,4,5,5,6,5,5,4,5,3,3,4,4,4,5,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,1,1,0,1,1,2,2,1,2,2,2,2,2,3,3,3,3,4,4,5,5,6,7,7,6,5,5,5,4,4,4,4,4,4,3,4,4,4,4,4,5,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,8,9,9,9,8,7,6,7,7,7,7,7,8,8,9,9,9,9,9,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,5,4,5,4,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,7,6,7,7,8,8,7,8,7,8,8,8,8,8,8,9,9,9,10,9,9,9,10,9,9,9,9,9,8,8,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,4,4,3,2,3,2,2,3,3,4,4,4,4,5,5,5,6,6,6,5,6,6,5,5,5,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,4,4,4,5,6,7,8,8,9,10,10,10,10,13,13,15,17,17,20,20,19,18,18,19,18,21,19,21,22,21,24,24,24,23,23,23,25,25,23,24,23,24,23,20,22,24,24,21,24,22,22,24,23,19,20,23,20],[28,28,27,28,28,28,28,27,27,26,26,25,26,25,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,26,27,28,28,27,27,27,28,27,27,27,27,27,27,27,26,26,25,24,24,24,23,23,24,21,21,21,20,19,19,16,14,12,9,8,7,6,6,5,5,5,4,4,4,5,5,5,5,5,6,5,6,6,5,6,6,6,7,7,7,8,8,7,7,8,8,7,8,9,8,8,9,10,9,9,10,10,9,9,11,11,9,8,9,8,8,8,7,8,7,8,7,7,8,8,7,7,8,7,7,7,8,7,7,8,9,8,8,8,8,7,7,8,7,7,7,7,7,7,7,7,6,7,7,7,8,8,8,7,7,7,7,7,7,6,6,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,7,7,8,8,7,8,9,8,8,9,9,8,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,4,5,5,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,4,4,4,4,4,4,5,5,6,6,5,5,4,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,6,6,7,10,10,10,13,14,15,14,14,16,16,15,16,17,18,17,19,21,21,21,22,23,23,21,24,20,20,20,19,19,20,21,22,21,22,23,25,26,26,25,26,27,27,26,27,27,27,27,27,27,27,27,27,27,26,27,26,26,26,25,26,24,24,25,25,26,25,24,26,23,24,24,24,23,22,23,21,20,20,17,17,16,13,13,8,6,5,4,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,5,5,6,6,6,5,5,5,4,4,3,4,4,4,5,6,4,5,5,4,4,3,3,3,3,2,2,2,2,2,2,1,1,0,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,6,6,5,4,4,3,4,3,3,3,3,3,3,3,3,3,4,4,3,4,4,3,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,6,7,8,8,8,7,6,6,6,6,6,7,6,6,7,8,9,9,9,9,9,9,8,9,8,8,7,8,7,7,7,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,9,9,8,10,9,9,9,9,9,8,8,8,8,7,7,7,6,6,6,6,5,5,5,4,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,4,5,5,4,5,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,4,5,5,5,5,5,4,4,4,4,4,3,3,3,3,2,2,3,2,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,5,6,7,7,8,8,8,9,9,10,12,12,14,15,17,18,15,14,16,17,15,18,16,17,19,18,19,21,19,19,21,20,21,21,20,20,20,20,19,17,19,20,20,19,20,19,18,20,22,18,16,18,18],[28,29,29,29,29,29,29,29,29,28,28,27,28,27,27,27,28,29,27,28,28,27,28,29,28,28,29,28,28,28,27,28,29,29,28,29,28,28,29,28,29,28,28,28,28,28,27,25,26,25,24,25,25,23,22,23,22,22,19,19,16,14,11,9,8,6,6,5,5,4,4,4,4,3,4,4,5,5,5,5,5,5,6,5,5,6,6,6,6,7,6,7,7,7,7,7,7,7,8,7,7,8,8,7,8,9,9,8,8,9,10,8,7,7,7,8,7,7,7,7,7,6,6,7,7,6,6,7,7,6,7,7,6,7,7,8,8,7,7,7,7,6,7,7,6,6,7,6,6,6,6,5,6,6,7,7,7,7,7,7,7,6,6,6,6,5,6,6,6,5,6,6,5,5,6,6,5,5,6,5,5,5,5,5,5,4,5,6,5,5,5,6,5,5,6,7,7,7,7,7,8,8,7,8,8,8,7,7,7,7,7,6,6,6,6,5,6,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,5,5,6,5,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,6,5,4,4,4,4,4,3,4,4,4,4,5,4,4,5,5,5,5,5,5,6,5,6,5,6,5,5,5,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,5,6,6,7,9,11,10,12,13,15,15,15,16,17,17,17,18,18,19,20,22,22,23,23,23,24,24,25,23,21,24,22,22,22,22,23,21,21,25,24,26,26,25,26,27,27,27,28,28,28,28,27,28,28,28,28,28,27,28,27,28,28,27,28,25,27,27,27,27,27,26,27,23,24,25,25,24,24,23,22,23,20,18,17,16,15,12,9,7,5,4,4,3,3,3,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,4,4,4,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,2,3,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,4,4,5,6,5,6,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,4,6,6,6,7,8,8,8,8,6,6,6,6,6,6,7,7,7,8,8,8,8,8,9,8,8,8,7,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,6,7,6,6,6,7,7,7,7,8,7,8,9,7,8,8,9,8,7,8,7,8,7,6,6,6,5,5,4,5,5,4,4,4,4,4,4,4,4,3,3,4,3,2,3,3,2,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,4,4,4,4,4,4,4,3,4,4,4,4,4,3,3,4,4,4,4,4,4,5,5,5,4,4,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,5,6,7,7,8,9,9,9,9,11,11,13,15,17,20,19,17,16,17,18,17,22,18,21,21,21,25,24,23,22,23,22,24,24,23,22,22,23,22,19,21,22,22,20,23,20,21,21,23,18,17,21,19],[28,28,28,28,28,29,28,28,28,26,27,26,27,26,27,26,26,27,26,27,27,26,27,28,27,27,28,28,27,27,26,27,28,28,27,27,28,27,28,28,28,28,27,27,28,26,25,25,26,25,25,25,24,23,22,22,20,21,20,19,16,14,11,8,7,6,5,5,4,4,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,7,6,7,6,7,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,6,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,6,5,4,5,5,5,5,5,5,5,5,5,4,5,4,4,5,4,4,4,5,4,4,5,5,4,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,3,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,4,4,5,5,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,2,1,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,8,9,10,12,14,15,14,15,18,18,16,18,19,18,20,20,22,23,22,23,23,24,23,24,21,21,22,21,20,22,23,22,21,22,23,25,24,26,24,25,26,27,26,27,26,27,27,27,27,26,27,27,27,26,26,26,26,27,26,26,25,25,27,24,26,25,24,26,24,23,24,24,24,23,23,22,21,20,17,18,15,14,13,8,6,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,4,5,5,5,5,6,6,5,5,5,4,4,4,4,4,4,5,6,5,5,5,5,4,4,4,3,3,3,3,3,2,2,2,2,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,4,5,5,5,5,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,6,7,7,7,6,5,5,4,4,5,5,5,5,5,6,6,7,6,7,7,7,7,7,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,3,3,4,4,3,3,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,6,6,7,8,8,8,8,10,11,12,16,17,19,20,17,16,19,18,17,20,18,19,22,20,23,23,23,21,22,23,24,23,23,23,22,22,22,19,21,23,22,19,21,20,20,21,22,18,17,20,19],[28,28,28,28,29,29,28,28,27,27,27,27,27,26,27,26,26,28,27,27,28,27,27,28,27,28,28,28,28,28,27,28,28,29,28,28,28,28,28,28,28,28,28,27,27,27,26,25,26,25,24,24,25,23,22,23,21,20,19,19,16,13,11,9,7,6,5,5,5,4,4,4,3,3,4,4,4,4,5,5,4,4,5,4,4,5,5,6,6,6,6,7,6,6,7,7,6,7,8,7,7,8,8,7,8,9,9,8,8,9,10,8,7,7,7,8,7,7,6,7,7,6,6,7,7,6,6,7,6,6,7,6,6,6,6,7,7,7,7,7,7,6,7,7,6,6,6,6,5,6,6,5,5,5,6,7,7,7,7,7,6,5,6,6,6,5,5,6,5,5,5,6,5,5,5,5,4,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,5,5,6,6,7,7,7,7,7,7,7,7,7,7,7,6,6,6,7,6,6,6,6,5,5,5,5,4,5,5,4,4,5,5,4,4,4,4,4,4,4,5,5,6,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,5,5,6,6,8,10,10,12,14,15,14,15,17,18,17,18,19,18,20,20,23,23,22,24,23,24,24,24,22,22,23,21,19,21,23,23,21,21,24,24,25,26,25,26,27,27,27,28,27,28,27,27,27,27,27,27,27,27,27,26,26,28,26,27,26,26,27,26,27,26,26,26,24,24,25,25,25,23,24,22,21,20,18,17,15,14,12,8,6,5,4,3,3,3,3,2,2,3,2,3,3,3,3,3,4,4,4,4,5,5,5,5,6,5,6,6,5,5,5,5,4,4,4,5,5,6,6,5,6,5,6,5,4,4,4,4,3,3,3,3,3,3,2,2,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,3,3,5,6,5,5,5,4,4,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,5,6,6,8,7,7,7,6,5,5,6,5,6,5,6,6,7,7,8,7,8,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,4,4,5,5,4,5,5,5,5,5,6,6,6,6,5,6,6,6,7,7,7,7,8,7,8,8,7,8,8,9,8,7,7,7,7,7,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,3,3,2,2,2,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,5,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,5,6,6,7,7,9,9,9,9,12,11,14,17,18,20,19,18,16,19,20,17,21,18,21,21,20,24,23,24,22,23,22,25,24,22,22,23,22,21,19,21,23,21,19,22,20,19,21,22,17,17,21,18],[28,27,28,27,28,28,27,27,27,26,26,26,27,25,26,25,26,26,26,27,27,27,27,27,27,27,28,27,27,27,26,27,28,28,27,28,27,28,28,27,27,27,26,27,26,26,25,24,24,24,23,22,22,21,19,20,19,18,17,17,14,12,11,8,7,6,5,5,5,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,6,6,6,7,6,6,7,7,6,7,7,7,7,8,8,7,8,9,9,9,9,10,9,8,7,7,7,8,7,7,7,7,7,7,6,7,7,6,6,7,7,6,7,7,6,6,7,7,7,7,7,7,7,6,7,7,6,6,7,6,5,6,6,5,5,5,6,6,7,7,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,6,7,7,7,7,6,6,6,6,6,6,5,6,6,5,5,5,5,4,5,5,5,4,4,5,4,4,4,4,3,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,5,5,6,8,9,9,11,12,14,12,13,15,15,15,17,17,17,19,19,20,22,21,21,22,24,22,24,21,20,21,20,19,21,22,22,20,21,23,24,25,26,25,25,25,26,26,27,26,26,26,26,26,26,27,27,27,26,26,26,26,27,25,26,25,25,26,25,26,25,25,26,24,24,24,24,23,22,22,21,20,18,17,16,15,13,12,8,6,5,4,3,3,3,3,2,2,3,3,3,3,3,3,3,3,4,4,5,5,4,5,5,5,5,5,5,5,5,5,4,4,4,4,5,4,5,6,5,6,5,5,4,4,4,4,3,3,3,3,2,3,2,2,2,2,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,3,4,4,5,5,5,5,4,4,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,6,7,7,7,6,5,4,5,5,5,5,5,5,6,6,7,8,7,7,8,8,7,7,7,7,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,5,6,6,6,6,7,6,7,7,7,7,8,7,8,8,8,7,7,7,7,6,6,6,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,4,4,5,4,4,4,4,4,4,4,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,4,4,4,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,4,5,6,6,7,9,8,8,8,10,10,13,15,16,18,19,17,14,18,19,16,21,17,20,21,19,22,22,22,22,23,22,23,23,22,22,21,22,20,17,19,21,20,18,21,19,19,20,21,17,16,20,17],[27,27,27,27,27,27,27,27,27,26,25,25,26,25,25,25,25,26,26,25,26,26,26,27,26,26,26,26,26,25,25,26,26,27,25,26,26,26,26,26,27,25,25,25,26,25,24,23,23,23,23,22,22,21,20,21,19,20,18,18,15,14,11,8,7,6,5,5,4,4,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,6,6,7,7,7,6,7,8,7,7,8,8,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,7,6,6,6,6,6,6,6,6,5,5,6,6,5,6,6,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,5,4,4,4,5,4,4,5,5,4,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,4,4,5,5,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,1,2,1,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,7,9,9,10,12,14,15,12,14,16,16,15,17,17,17,17,18,20,21,20,21,21,22,22,22,20,19,20,20,19,19,20,22,19,21,21,24,24,26,23,23,25,25,25,26,26,26,26,26,26,25,26,26,26,25,26,25,25,26,24,25,24,24,25,24,25,24,24,25,23,23,23,23,22,21,22,20,20,18,16,16,13,13,11,8,6,5,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,5,6,5,5,4,4,4,4,4,4,4,5,6,5,5,5,5,4,4,4,3,3,3,3,3,2,3,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,3,3,4,4,4,4,4,3,3,2,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,6,7,7,7,6,5,5,5,4,5,5,5,5,6,6,7,7,7,7,7,8,7,7,6,6,6,6,6,5,5,5,5,5,4,5,4,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,5,5,5,5,6,6,6,6,7,7,7,8,7,7,7,7,7,7,7,7,6,6,6,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,3,3,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,5,4,4,4,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,4,4,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,6,6,7,8,9,8,8,9,10,12,13,14,17,18,16,13,17,18,15,20,15,18,19,18,21,21,19,20,21,20,21,21,21,17,19,20,20,15,17,21,21,16,21,18,19,19,21,16,15,18,18],[28,28,28,28,28,28,27,28,27,27,27,26,27,25,26,26,26,27,26,27,28,27,27,28,27,27,27,28,27,27,27,27,28,28,27,28,28,27,28,27,28,27,27,27,26,26,26,24,25,25,25,23,23,23,21,22,20,21,20,19,16,14,11,8,7,6,5,5,5,4,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,6,6,6,6,6,6,6,6,7,7,6,7,7,7,7,8,8,7,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,7,6,6,6,6,6,5,6,6,6,5,5,6,5,5,6,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,6,5,5,5,5,5,4,5,5,5,5,5,4,5,4,4,5,5,4,5,5,4,4,5,5,4,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,4,4,5,5,4,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,6,7,8,9,11,12,13,15,14,14,17,17,17,19,19,19,20,19,21,24,22,22,23,24,23,24,21,21,23,20,21,22,22,23,22,22,24,26,26,27,26,25,27,27,27,27,27,28,27,27,28,27,28,28,28,27,27,28,27,27,26,27,26,26,27,26,27,27,25,26,26,24,24,25,23,23,22,22,21,20,17,16,15,12,11,8,6,5,4,4,3,3,3,2,2,3,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,5,6,5,5,5,5,4,4,4,4,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,3,3,4,5,4,4,4,3,3,2,3,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,6,7,6,6,5,5,4,5,5,5,5,5,6,6,6,7,6,7,7,7,7,7,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,5,6,6,6,6,6,6,7,7,7,7,6,7,7,7,7,6,7,7,7,6,6,5,5,5,4,4,4,4,4,3,3,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,6,7,7,8,9,10,9,9,11,11,13,14,18,19,20,15,14,18,19,16,20,17,19,22,20,23,23,22,22,23,22,23,23,23,21,21,23,22,18,19,23,22,18,22,20,20,20,22,17,16,19,18],[28,28,27,28,28,27,28,28,27,27,26,26,26,25,26,26,26,27,27,27,27,27,27,28,27,27,28,27,28,28,27,28,28,28,27,28,27,28,28,28,28,27,27,27,27,26,25,23,24,23,22,22,22,21,20,20,19,18,17,17,15,13,11,8,7,7,6,5,5,4,4,3,3,3,3,4,4,4,5,4,4,4,5,4,4,5,5,6,6,6,6,7,6,6,7,7,6,7,7,6,7,7,8,7,7,8,9,8,8,9,9,8,7,7,7,8,7,7,6,7,7,6,6,7,7,6,6,7,6,6,6,6,5,6,6,7,7,6,6,7,6,6,7,6,5,6,6,6,5,6,6,5,5,5,6,6,7,7,6,7,6,6,6,6,6,5,5,6,5,5,5,5,4,5,5,5,4,5,5,5,5,4,4,5,4,4,5,5,4,4,5,5,4,5,5,6,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,5,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,5,5,5,5,5,5,5,5,4,4,5,4,3,4,4,3,3,4,3,3,4,4,4,5,5,4,4,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,6,7,8,9,10,12,13,15,14,14,16,16,15,17,18,17,17,18,21,21,20,22,21,22,22,23,21,20,21,19,19,20,21,22,20,21,23,24,25,27,24,25,26,26,26,27,26,26,26,26,26,27,27,27,27,26,27,26,26,27,26,26,25,26,26,25,27,26,25,27,25,25,25,24,24,23,22,22,20,19,16,15,13,12,11,8,6,5,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,5,5,5,4,5,5,5,5,5,6,5,6,5,5,5,5,4,4,4,4,3,3,3,3,3,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,3,3,4,5,5,5,4,3,3,3,3,3,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,6,7,7,7,6,6,5,5,5,5,5,5,5,6,7,7,7,7,7,8,8,8,8,7,6,7,6,6,6,6,5,5,5,4,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,5,4,4,5,5,5,5,5,6,6,6,6,5,6,6,6,7,6,6,7,7,8,8,8,7,8,8,8,7,7,7,7,7,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,4,3,4,4,5,5,5,4,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,5,6,7,7,7,10,9,9,10,12,12,14,15,17,19,20,18,15,19,20,17,22,17,21,21,20,24,23,20,23,23,22,24,24,22,21,23,23,21,18,19,23,22,18,21,20,20,21,22,18,17,21,17],[27,27,26,27,27,27,27,27,27,26,25,25,26,25,25,25,25,25,26,26,26,26,27,26,26,26,26,26,26,26,26,27,27,27,26,26,26,26,27,26,26,26,26,26,26,25,25,23,24,23,22,21,22,21,20,20,19,19,17,18,15,13,11,9,8,7,6,5,5,5,4,4,4,3,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,6,7,8,7,7,9,8,8,8,9,9,8,9,10,10,8,7,8,7,8,8,7,7,7,8,7,6,7,7,7,7,8,7,6,7,7,6,7,7,7,7,7,7,7,7,6,7,7,6,6,7,7,6,7,7,6,6,6,6,7,7,8,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,5,5,6,5,5,6,6,5,5,6,6,5,6,6,6,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,6,5,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,5,5,6,6,5,5,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,3,4,5,4,4,5,5,4,5,5,5,5,5,6,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,4,4,5,5,5,6,6,8,9,9,10,11,13,14,12,13,15,15,14,15,17,16,17,18,20,20,20,21,21,22,21,22,20,19,20,19,18,19,20,20,19,20,21,23,24,26,24,24,25,25,25,26,26,26,26,25,26,26,26,26,26,26,26,26,26,25,25,25,24,25,25,25,26,24,25,26,25,24,24,23,23,21,22,20,19,18,16,16,14,12,11,9,7,6,4,4,3,3,3,3,3,3,3,3,3,3,4,3,5,5,5,4,5,5,5,5,6,6,6,6,6,7,5,5,4,5,5,7,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,3,3,3,3,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,3,3,4,4,4,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,4,4,4,4,5,4,4,5,5,5,6,7,7,7,7,6,6,5,5,6,6,6,6,7,7,8,8,8,8,9,9,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,6,6,7,6,7,7,6,6,6,6,7,7,7,7,8,8,8,9,8,9,8,9,8,7,8,8,7,7,7,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,4,4,5,4,5,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,5,5,5,4,5,5,4,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,4,3,4,3,4,4,4,4,4,5,5,4,4,4,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,5,6,7,7,7,10,9,8,9,10,10,12,13,15,15,18,15,12,16,18,15,21,16,19,20,19,22,22,20,21,22,21,22,22,22,19,19,21,20,16,16,20,21,16,20,18,19,19,21,18,17,19,17],[28,28,27,27,28,28,27,27,28,26,26,25,26,26,25,26,26,27,26,27,27,26,27,27,26,27,27,27,27,27,26,27,28,28,27,27,27,27,28,27,28,27,26,27,26,26,25,23,24,24,23,23,24,22,21,21,20,21,19,19,16,14,12,10,9,7,6,6,6,5,5,5,4,4,5,5,5,6,6,5,5,6,6,5,6,6,6,7,7,6,7,8,7,7,8,7,7,7,8,8,8,8,8,8,8,9,9,8,8,9,9,8,8,8,7,8,8,7,8,7,8,7,8,7,7,7,7,7,7,7,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,7,6,6,7,7,7,8,7,8,7,7,7,7,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,6,5,6,6,7,7,7,7,7,7,7,7,8,8,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,4,5,5,4,4,5,4,4,4,4,5,6,5,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,4,4,3,4,4,4,5,5,5,5,5,6,6,7,8,10,10,11,13,14,15,14,14,16,17,16,17,18,18,19,19,20,21,21,22,21,23,22,23,21,20,21,20,19,20,21,22,20,22,22,24,25,27,23,24,25,25,25,26,25,25,25,25,25,25,26,26,25,25,25,25,25,25,24,25,24,24,25,24,26,25,24,25,24,23,24,23,22,22,22,20,19,18,17,15,14,12,11,9,7,6,5,5,4,4,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,6,6,6,6,7,7,7,6,6,5,5,4,4,4,5,5,6,7,6,6,6,5,5,5,5,4,4,4,4,4,3,3,3,3,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,3,3,4,5,5,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,6,7,8,8,8,7,6,6,6,6,6,6,6,6,7,7,8,8,8,8,9,10,9,9,8,7,8,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,8,7,7,7,7,7,7,7,7,8,8,9,9,9,8,9,8,9,8,8,9,8,8,7,7,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,4,5,5,5,5,4,4,4,4,4,3,4,4,3,4,4,3,3,4,4,4,4,4,5,5,5,6,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,4,4,4,4,4,5,5,5,5,6,5,5,5,4,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,6,7,7,7,10,10,8,8,12,13,13,14,16,18,19,16,13,17,19,15,20,16,20,22,20,23,23,22,21,23,23,23,24,23,21,21,23,22,19,18,21,22,19,21,20,21,21,22,18,16,20,18],[29,29,28,28,28,28,28,28,27,27,26,26,27,26,27,26,27,27,27,27,27,27,27,28,27,28,28,28,28,27,27,28,28,29,28,28,28,28,28,28,28,27,27,27,27,27,25,25,26,24,23,23,24,22,20,21,21,20,19,19,17,15,13,10,9,8,6,6,6,6,5,5,5,4,5,5,5,6,6,5,5,6,6,5,5,6,6,7,7,7,7,8,7,7,8,7,7,8,8,8,8,8,8,8,8,9,9,9,9,10,10,9,8,8,8,9,8,8,7,7,8,7,7,7,8,7,7,8,7,7,7,7,7,7,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,7,7,7,8,8,8,8,7,7,7,7,7,6,6,7,7,6,6,7,6,6,7,6,6,6,6,6,6,5,5,6,6,5,6,6,5,5,6,6,6,6,6,7,7,7,7,7,7,7,8,7,8,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,6,6,6,5,6,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,5,4,5,5,4,4,4,5,6,6,5,4,4,4,4,4,5,5,4,4,5,5,4,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,3,3,2,3,2,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,7,7,8,10,10,11,12,13,15,14,15,17,17,17,19,20,19,20,21,22,24,22,23,24,25,23,25,21,22,23,21,21,20,22,22,20,21,23,25,25,27,25,26,27,27,27,27,27,27,27,27,27,27,28,28,28,27,27,27,27,28,26,27,25,26,27,26,26,27,25,26,25,24,25,24,23,23,22,22,21,19,17,16,14,13,11,8,7,6,5,5,4,4,4,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,6,7,6,6,6,6,5,5,5,6,6,7,7,6,6,6,6,6,5,5,5,5,4,4,4,4,4,3,3,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,2,2,3,3,5,5,5,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,5,5,5,6,6,7,8,8,8,7,7,6,6,6,6,7,6,6,7,7,8,8,8,8,9,9,8,9,8,8,8,8,7,7,7,6,6,6,6,6,6,5,5,5,5,4,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,7,7,8,8,6,7,7,7,8,7,8,8,9,9,9,9,9,10,9,9,9,8,8,8,8,8,8,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,5,5,5,5,5,4,5,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,3,3,4,6,7,7,7,10,8,8,10,11,12,13,15,17,18,19,17,14,18,19,15,21,17,20,21,20,23,22,20,22,22,23,22,23,23,21,21,22,22,18,18,23,22,19,21,18,20,22,23,17,16,21,18],[29,28,27,28,27,27,28,27,27,27,25,25,26,25,26,26,26,25,26,27,26,26,27,27,27,28,27,27,28,27,26,28,28,28,28,28,26,28,28,28,28,27,25,26,26,27,25,24,25,24,23,22,23,22,20,21,20,19,18,19,16,14,12,11,10,9,7,7,7,6,6,5,5,5,5,5,6,6,7,6,6,6,7,6,7,7,7,8,8,8,8,9,8,9,9,9,8,9,10,9,10,11,11,10,11,12,12,11,12,12,12,11,10,11,10,11,10,10,9,9,10,9,9,9,10,8,8,9,9,8,8,8,7,8,8,8,9,9,9,9,9,8,9,9,7,8,9,8,7,8,8,7,8,7,8,9,9,9,9,9,8,8,8,8,8,7,7,8,7,7,7,7,7,7,8,7,6,7,7,7,7,6,6,7,6,6,6,7,6,6,7,6,6,6,7,8,8,7,7,8,8,8,8,9,8,8,8,8,7,8,8,7,7,8,7,7,7,7,7,6,6,7,6,6,6,6,5,5,6,6,5,5,6,6,7,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,4,5,5,5,6,6,5,4,4,5,4,4,5,5,4,5,5,5,5,6,5,5,5,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,4,4,5,4,4,5,4,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,5,4,4,5,5,6,5,6,6,6,7,7,7,9,11,11,11,12,14,15,14,15,16,16,16,18,19,18,18,19,21,22,21,22,23,23,21,23,21,20,21,20,20,20,21,21,20,21,23,23,25,26,25,25,26,26,26,27,26,26,26,26,27,26,27,27,27,26,27,26,27,27,26,26,24,26,25,25,27,26,26,26,24,25,25,24,24,22,22,22,20,19,17,16,14,13,11,9,8,7,6,5,5,5,4,4,4,3,3,3,4,4,4,4,5,5,5,6,6,6,6,6,7,7,7,7,8,7,5,5,5,5,6,6,6,8,8,6,7,7,6,6,6,6,5,5,5,5,5,4,4,4,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,2,2,3,4,5,5,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,4,5,5,5,5,6,6,5,6,6,6,8,8,9,9,8,7,6,6,6,7,7,7,7,8,8,9,9,9,9,10,10,10,10,9,8,9,9,8,8,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,7,6,6,7,7,7,7,7,8,7,9,9,7,8,8,8,9,9,9,10,10,11,10,11,10,11,10,11,10,9,9,9,9,8,9,7,7,7,6,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,3,3,3,3,3,3,3,4,3,4,5,4,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,4,4,5,5,6,7,6,6,6,7,6,6,6,6,6,5,5,6,6,5,5,5,4,4,4,4,4,4,5,5,5,6,6,6,5,7,6,5,5,5,5,5,4,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,5,6,7,7,7,10,9,8,9,11,12,13,14,15,17,19,16,14,17,19,16,21,18,20,22,20,23,21,21,21,23,21,22,23,21,22,20,22,20,18,18,21,20,19,21,20,20,22,22,19,18,21,17],[28,27,27,26,27,27,27,27,27,26,26,25,26,25,26,26,26,26,26,26,27,26,27,27,26,27,27,27,27,26,26,27,27,28,27,27,27,27,28,27,28,27,26,27,26,26,25,24,25,24,23,22,23,23,21,21,21,20,18,19,16,15,13,11,10,9,8,8,8,7,7,7,6,6,7,7,7,8,7,7,8,8,8,8,8,8,9,9,9,9,9,10,9,10,10,10,10,10,11,10,11,11,11,10,11,11,11,11,11,12,12,11,10,11,10,10,10,9,10,10,10,9,9,9,9,9,9,10,9,8,9,9,8,9,8,9,9,10,9,10,10,9,10,9,9,9,10,8,9,9,9,8,9,8,9,9,10,10,9,10,9,8,9,9,9,9,8,9,9,8,8,8,9,8,8,8,8,8,7,8,7,7,7,7,8,7,7,7,7,7,7,7,7,7,7,8,9,9,8,9,9,9,9,9,9,9,9,9,9,9,10,9,8,9,8,8,9,8,8,8,8,8,8,8,7,8,7,7,7,7,6,7,7,7,8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,6,6,6,5,5,6,6,7,7,6,6,5,6,5,5,6,6,5,6,7,6,6,6,7,6,6,6,6,7,7,8,8,7,7,7,7,7,6,7,7,6,6,5,6,5,6,5,5,4,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,8,8,8,10,10,11,11,13,13,15,14,15,16,16,16,18,19,18,18,19,20,21,21,22,23,23,22,23,21,21,22,20,19,20,21,21,19,21,22,23,23,26,24,24,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,25,26,26,26,25,23,25,25,24,26,25,25,25,23,24,24,24,22,22,22,20,20,19,17,16,14,13,12,10,9,7,6,6,5,5,5,4,4,4,3,4,4,5,4,5,5,5,5,5,6,6,7,7,8,7,8,7,7,7,6,5,5,5,6,6,7,8,8,7,7,8,7,6,6,6,6,5,5,5,4,4,4,4,4,3,3,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,2,3,3,5,5,4,4,3,4,3,4,4,4,5,4,4,4,4,3,4,4,4,4,4,5,4,4,5,5,4,5,6,5,5,6,6,6,6,7,7,6,7,7,7,8,9,9,9,8,7,7,7,8,8,8,8,8,9,10,10,10,10,11,11,11,11,11,11,9,10,10,9,9,8,8,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,4,5,5,4,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,7,7,6,7,8,8,7,8,8,8,8,9,9,9,10,10,9,9,9,9,10,10,10,10,10,11,10,11,11,11,11,11,11,10,11,11,10,9,9,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,4,4,4,4,3,3,4,3,3,3,3,4,4,4,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,6,7,7,7,6,6,6,6,6,6,5,5,5,5,5,5,5,4,5,5,5,5,6,6,6,7,7,6,6,7,7,7,7,6,6,6,6,6,5,6,5,5,5,4,4,4,4,4,5,5,5,6,6,6,5,6,6,5,6,5,6,5,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,4,4,5,7,8,7,7,10,9,7,9,11,12,12,15,14,17,19,14,13,17,18,14,21,17,20,21,20,23,22,20,21,23,21,21,22,21,21,20,22,20,19,18,21,21,20,21,18,20,20,22,18,17,20,18],[28,29,28,28,28,28,28,28,28,27,27,26,27,27,27,26,27,27,27,27,27,26,27,28,26,28,28,27,28,28,26,28,28,28,28,28,28,28,28,28,28,28,27,28,28,27,26,25,26,26,24,23,24,23,22,22,22,20,20,20,18,16,15,13,11,10,9,9,9,8,8,7,7,6,7,8,8,8,8,8,8,9,9,8,9,9,9,10,10,9,10,11,10,10,11,11,10,10,11,11,11,11,11,11,11,12,11,11,11,12,12,12,11,11,11,11,10,10,10,10,11,10,9,10,11,10,10,10,10,10,10,9,9,10,9,10,9,10,10,10,10,9,10,10,9,9,10,10,9,10,10,9,10,9,10,10,10,10,10,11,10,10,9,10,10,9,9,10,10,9,10,10,9,9,9,9,8,9,9,9,9,8,8,8,8,7,8,9,7,7,8,8,7,8,9,9,10,10,9,10,10,10,10,10,10,10,10,10,9,10,10,10,9,10,10,9,9,9,9,8,8,9,8,7,8,8,7,7,8,8,7,7,8,8,9,9,8,9,9,9,9,8,8,8,7,7,7,7,7,6,7,6,6,6,6,7,8,7,6,5,5,6,6,5,6,6,5,6,7,7,6,7,7,7,7,7,8,8,8,9,8,8,7,8,8,7,7,7,7,7,7,6,7,5,6,6,5,5,5,6,6,6,5,5,5,5,4,4,4,4,4,3,4,4,3,4,3,4,4,4,5,6,5,6,6,6,6,7,7,8,8,9,8,9,11,12,13,13,14,15,17,16,17,19,19,19,20,20,20,21,22,23,24,22,23,24,24,23,25,21,22,22,21,21,21,22,23,22,22,23,24,25,26,24,25,26,26,26,27,26,26,26,26,26,27,27,27,27,27,27,27,26,26,25,26,25,25,26,25,27,26,25,26,24,24,24,23,23,23,22,21,20,19,17,17,15,15,13,11,10,8,7,7,6,6,6,4,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,8,8,8,7,7,7,6,6,6,7,7,8,9,8,9,8,8,8,7,7,6,6,6,6,5,5,5,4,4,4,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,2,3,3,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,4,4,5,4,4,5,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,7,7,7,8,8,9,10,10,10,9,9,8,9,9,9,10,9,9,10,11,11,11,11,12,12,13,12,13,12,11,12,11,10,10,10,9,9,8,9,9,8,8,8,8,7,7,6,6,6,6,6,6,6,5,4,4,4,4,3,3,4,3,3,3,3,3,3,4,3,4,4,5,4,5,5,5,5,5,5,6,6,6,6,7,6,7,7,7,8,8,8,8,8,9,8,9,9,9,9,9,10,11,11,10,10,10,10,10,11,11,11,11,12,12,12,13,12,13,13,13,12,12,12,11,11,11,10,10,9,9,8,9,8,8,7,7,7,7,7,6,6,6,6,5,6,6,4,4,5,4,4,4,4,5,5,5,6,6,6,6,7,6,6,7,7,7,7,7,7,7,7,7,8,8,8,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,7,6,6,7,7,8,8,8,7,8,8,7,8,8,7,7,7,7,7,6,6,6,6,6,5,5,6,6,6,7,6,7,7,7,7,7,7,7,7,6,7,6,6,5,5,4,4,4,3,3,4,3,3,3,3,3,2,3,3,2,3,4,4,6,7,8,8,8,10,9,8,9,10,12,13,13,14,18,19,15,15,19,19,17,20,17,21,21,20,21,23,20,21,22,22,22,23,23,21,21,23,23,18,18,21,22,18,21,18,20,20,21,18,17,19,18],[29,28,27,28,28,27,28,27,27,27,26,25,27,25,27,26,27,26,27,28,27,27,28,28,27,28,29,28,29,29,28,29,29,29,28,29,29,29,29,29,29,29,28,28,28,28,27,26,27,26,25,24,25,23,23,23,23,21,21,22,19,17,15,14,13,12,10,11,11,10,9,8,8,8,9,9,9,10,10,10,9,10,11,10,11,12,12,13,12,12,13,14,13,13,13,13,12,14,14,14,13,14,14,13,14,16,15,14,15,16,16,15,14,15,13,14,14,14,12,12,14,12,12,12,13,11,11,12,12,10,12,11,10,11,11,12,11,12,12,12,12,11,13,12,11,13,13,11,11,13,13,10,12,12,12,12,14,13,13,13,13,12,12,13,13,10,11,12,11,10,11,12,11,10,11,11,9,10,10,10,10,9,9,10,9,8,10,10,9,8,10,10,9,10,10,11,11,11,10,11,11,11,12,12,12,12,12,12,11,11,12,12,10,12,11,10,11,11,11,9,10,11,9,9,9,10,8,9,9,9,7,8,8,9,9,9,9,10,9,10,10,9,9,9,9,8,8,8,8,7,7,7,6,6,6,8,8,8,7,6,6,8,7,6,8,7,7,8,9,9,7,9,9,8,9,9,9,10,10,10,9,10,9,9,9,9,8,9,8,8,8,8,8,6,7,7,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,5,4,5,5,5,6,6,6,7,7,8,8,8,9,9,9,10,11,10,12,13,14,14,15,16,17,16,16,19,19,19,21,22,21,20,21,23,23,23,25,25,25,23,24,23,22,24,21,20,21,22,21,20,21,24,24,25,26,25,26,26,27,27,27,27,27,27,27,27,27,28,28,27,27,27,27,27,27,27,27,26,27,27,26,27,26,26,27,24,25,26,25,24,23,24,22,21,21,19,18,16,15,13,12,11,10,9,8,8,7,7,6,6,5,5,5,6,6,7,6,6,7,7,7,8,8,8,8,9,9,8,8,9,8,9,8,7,7,7,8,8,9,10,9,9,9,8,9,8,8,7,7,8,7,7,7,7,6,6,5,4,4,4,3,3,2,3,3,2,2,1,1,1,1,0,1,2,3,3,5,5,5,5,4,4,4,5,5,5,5,6,5,6,6,5,5,6,6,6,6,5,6,6,6,6,7,7,7,8,8,8,9,8,9,10,9,8,9,10,9,11,11,12,11,10,10,10,11,11,10,11,11,11,12,13,12,14,13,13,15,15,15,14,14,12,13,13,13,12,12,11,11,10,11,11,10,10,10,10,9,9,8,9,8,7,7,7,8,7,6,6,5,5,5,4,4,4,4,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,8,8,8,8,9,8,8,9,8,9,10,10,9,10,10,10,10,11,11,12,11,11,14,12,14,13,11,12,12,13,14,14,14,14,15,15,14,15,14,16,14,15,14,13,14,14,12,12,12,11,11,10,10,10,9,9,9,9,8,8,9,8,7,7,8,7,7,7,6,6,6,5,5,5,6,6,6,7,7,7,8,8,8,8,8,9,9,8,9,9,9,10,9,8,10,10,9,9,8,8,8,8,8,8,8,8,8,8,8,8,7,7,8,7,7,8,8,9,9,9,9,8,9,9,9,9,9,9,8,8,9,8,8,7,8,8,7,7,7,7,7,7,8,7,8,8,7,8,8,8,7,7,7,7,8,6,6,5,5,5,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,4,7,8,9,9,9,11,10,8,10,11,13,14,15,15,18,19,15,15,20,19,16,22,18,22,22,20,24,22,21,23,22,22,22,24,22,20,21,24,21,18,19,23,22,19,23,19,21,21,23,19,18,20,18],[27,27,26,27,27,26,27,27,26,26,25,25,26,25,26,25,27,26,26,27,26,26,27,27,26,27,27,28,28,27,27,28,28,28,28,28,26,28,28,28,28,27,27,28,28,27,27,26,26,26,25,24,25,24,23,22,23,22,21,21,19,18,17,14,14,12,12,12,12,11,11,9,9,9,10,11,11,11,12,11,12,12,13,11,13,14,14,14,15,15,15,15,16,16,15,16,16,16,16,16,17,17,17,16,17,17,17,16,17,17,18,17,16,18,17,16,16,16,15,14,16,15,14,15,15,14,13,14,15,12,14,14,12,12,12,13,13,14,14,14,13,15,15,16,14,16,15,15,15,15,15,13,16,14,15,16,16,16,16,15,14,15,13,15,15,13,13,15,14,12,13,14,14,13,13,14,11,12,12,11,13,11,10,12,12,10,11,12,11,10,12,12,10,11,11,12,12,13,11,12,13,12,13,13,14,13,13,13,14,14,15,14,12,16,14,12,13,14,13,12,13,13,11,11,12,12,10,11,11,11,9,10,10,11,11,12,12,11,11,11,12,11,11,11,10,10,10,9,10,9,9,8,7,8,8,8,9,9,8,7,7,8,8,7,9,8,7,9,9,9,8,9,10,9,9,10,10,10,11,12,11,11,11,11,11,10,10,10,10,9,9,9,10,7,8,8,8,6,8,7,7,8,8,6,7,7,6,5,7,7,5,6,6,6,6,6,5,6,7,7,7,8,8,8,8,9,9,9,9,10,10,11,10,11,12,12,13,14,16,16,18,16,17,19,19,18,19,20,21,19,20,23,23,23,24,24,24,23,25,23,22,23,21,20,21,23,22,21,23,24,24,25,26,25,26,26,27,27,27,27,27,27,27,27,27,27,28,28,28,27,27,28,27,27,26,24,26,26,27,27,26,26,27,25,25,25,24,25,23,24,22,21,21,18,19,15,15,14,12,12,11,9,9,9,8,7,7,6,5,6,6,6,7,8,7,7,8,7,8,9,8,9,10,10,10,11,9,10,9,8,7,9,8,8,9,9,9,11,10,10,10,9,9,9,9,8,8,8,9,8,7,8,7,6,6,6,5,5,4,4,3,3,3,3,2,2,2,2,1,1,0,1,3,3,5,5,5,6,4,5,5,6,6,6,7,6,6,7,7,5,6,7,6,6,6,6,5,6,8,7,6,7,8,8,7,8,10,9,9,10,10,10,10,10,10,11,12,12,12,11,10,10,11,11,13,12,12,13,14,15,16,15,16,15,16,17,16,17,16,14,16,15,15,14,14,14,14,13,12,13,11,12,12,11,11,10,9,9,8,8,8,7,7,7,6,5,6,5,5,5,5,5,4,4,3,4,5,4,4,6,6,5,5,7,6,6,8,7,8,8,8,8,9,9,9,9,9,9,11,11,10,12,12,11,11,13,13,13,13,13,15,14,15,16,14,15,14,15,16,16,15,16,16,17,15,17,17,17,16,16,15,16,15,15,15,14,14,13,13,12,12,11,11,10,10,9,10,9,9,8,8,8,8,8,7,8,6,6,7,6,5,4,6,6,6,8,8,8,8,9,9,9,9,8,10,10,9,9,10,10,10,10,11,10,10,10,9,9,9,9,9,8,9,8,9,8,8,8,7,8,8,8,8,8,9,9,10,10,9,10,10,10,10,10,9,9,9,9,9,9,9,8,8,8,7,7,7,7,8,8,9,8,8,9,8,8,9,9,7,7,7,7,8,6,7,6,5,4,5,4,4,5,4,4,4,4,4,3,4,4,3,4,5,5,6,8,9,8,9,11,10,9,10,11,13,14,13,16,16,18,15,15,18,19,15,20,17,21,21,20,24,23,20,22,24,22,22,23,22,21,20,22,21,18,17,22,22,18,20,19,20,20,21,20,17,18,17],[26,26,26,26,27,27,27,27,27,26,26,26,27,26,26,26,27,27,27,27,27,28,27,28,28,28,28,28,28,28,28,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,28,28,28,27,28,27,26,26,26,25,25,26,24,23,22,23,20,19,19,16,19,17,17,18,18,16,17,14,17,17,18,19,18,18,16,18,18,17,19,19,20,19,19,20,20,20,21,22,20,20,20,20,20,19,22,20,19,20,21,20,19,20,21,20,20,21,20,22,20,19,20,20,18,19,19,21,18,18,19,19,17,19,19,16,17,18,17,16,17,17,17,18,18,18,18,20,19,19,19,21,20,19,20,20,19,20,20,19,20,21,20,19,19,18,19,20,19,19,20,19,19,20,21,19,18,18,19,18,17,18,16,16,15,15,18,16,15,15,18,14,14,16,16,14,15,17,15,15,15,16,17,18,15,17,18,18,17,17,18,17,19,18,19,19,19,18,17,19,18,17,19,19,17,18,18,18,17,18,17,16,15,17,17,16,15,17,16,15,17,17,17,16,16,16,18,17,16,17,16,16,15,15,15,13,13,13,12,12,11,12,13,12,11,12,12,14,14,11,14,14,12,15,15,15,14,15,17,14,16,15,15,15,17,17,17,17,17,18,16,16,16,16,16,14,17,15,16,14,15,14,14,13,15,14,14,14,15,14,15,14,12,13,12,11,8,10,10,9,8,8,9,10,12,11,13,13,13,13,13,14,14,15,15,17,15,16,16,17,16,19,18,18,21,21,22,21,20,22,22,22,22,24,23,23,25,26,25,25,26,25,27,24,26,25,24,24,24,22,24,24,24,22,23,24,26,26,26,26,26,27,27,27,28,28,27,27,27,27,28,28,28,28,27,28,27,28,27,27,27,26,27,27,27,27,27,27,27,26,26,26,26,26,25,25,24,23,23,21,21,18,19,17,17,15,17,13,14,14,13,11,11,9,9,8,7,9,9,8,9,10,10,9,11,11,10,11,11,13,11,12,9,10,8,10,9,9,9,9,10,10,11,13,12,12,14,13,12,12,12,10,11,12,11,10,11,11,11,10,10,8,9,8,8,7,8,6,5,5,6,5,5,4,3,3,1,0,1,3,5,5,5,7,7,7,7,9,10,10,13,11,10,11,13,11,11,12,12,11,11,13,11,12,13,13,12,13,14,13,13,14,15,14,14,16,16,16,15,15,15,15,17,15,15,17,15,15,16,17,18,17,17,18,19,20,20,19,20,20,19,19,19,20,20,19,20,20,20,19,20,20,19,19,19,19,18,17,18,18,18,16,17,16,15,15,15,13,13,13,13,12,14,11,11,10,9,9,9,8,7,8,10,8,9,13,12,10,11,12,12,11,13,12,13,12,13,14,14,14,14,17,16,14,16,16,17,17,18,18,18,17,19,18,19,20,19,20,19,20,21,20,21,20,19,20,20,19,20,21,18,19,21,20,20,20,19,21,19,19,19,20,18,18,17,19,18,18,19,17,18,17,17,17,15,14,15,14,13,13,13,14,12,11,13,12,9,9,10,10,11,13,13,13,12,13,12,14,13,13,14,14,15,14,15,16,17,16,15,17,16,16,16,15,17,15,15,13,15,13,13,13,13,13,12,13,13,12,13,13,12,15,14,17,15,14,15,15,16,14,17,14,14,15,13,13,14,14,14,13,12,11,11,10,11,11,14,12,13,11,12,10,12,12,11,11,11,12,10,10,10,8,7,9,8,5,6,7,6,5,6,6,6,6,6,6,5,6,8,7,8,9,10,9,9,10,10,9,10,11,13,14,15,15,17,21,17,15,18,21,18,22,18,22,21,22,24,24,22,23,24,24,22,23,24,21,20,24,23,19,18,22,24,21,22,17,20,19,22,21,16,18,18],[28,29,28,28,29,28,29,29,28,28,28,27,28,28,28,28,28,28,28,29,29,29,29,29,29,30,29,29,30,29,29,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,29,28,29,28,27,27,28,27,25,26,26,26,24,25,23,21,22,19,20,18,18,17,17,17,18,16,16,16,17,16,16,17,18,17,17,17,18,17,18,18,18,19,20,19,20,20,20,20,20,20,19,19,20,20,20,20,20,20,20,20,20,19,20,19,20,20,20,21,19,19,19,19,18,19,19,18,18,17,20,18,17,19,18,17,18,18,17,16,16,17,18,18,18,18,18,19,20,19,18,19,20,19,18,19,19,18,20,18,19,20,20,20,20,18,20,18,18,19,20,18,18,20,19,17,19,19,18,18,18,18,16,16,17,17,17,16,15,17,17,15,16,16,15,15,17,16,16,16,16,17,18,18,18,19,18,18,19,19,19,17,19,19,19,18,19,20,18,19,18,18,17,19,18,17,17,18,16,16,17,17,15,16,17,17,14,16,15,15,15,15,17,15,15,16,17,16,16,16,16,16,15,15,15,12,13,14,12,12,12,13,14,12,11,10,12,14,13,12,15,14,13,14,16,16,14,17,16,16,17,17,18,17,17,17,18,16,16,16,16,16,15,16,15,14,14,15,15,14,15,16,14,13,14,15,14,14,14,12,13,14,13,11,12,13,10,11,11,11,9,11,11,12,11,11,12,12,13,13,14,15,16,16,16,16,16,16,17,16,17,19,18,18,20,20,21,22,21,23,23,23,23,24,25,24,25,27,26,26,27,26,27,26,27,25,24,25,24,23,24,24,24,24,24,25,26,25,26,26,27,28,28,28,28,28,28,28,28,28,28,29,29,29,28,28,28,28,28,27,28,27,28,28,27,29,28,28,29,27,28,28,27,27,26,26,25,23,24,22,22,19,18,19,15,15,15,14,15,13,13,12,11,10,11,10,10,11,11,10,10,10,10,10,10,11,11,12,11,12,12,11,11,11,10,10,10,10,11,10,10,11,11,13,13,12,14,13,12,12,13,11,11,12,13,11,10,11,11,12,11,11,12,10,10,10,9,10,7,7,6,6,4,4,4,2,1,1,0,1,3,4,5,6,8,8,9,10,10,11,12,11,10,11,12,10,10,11,11,9,11,11,13,12,12,12,13,15,16,14,14,16,16,15,16,17,16,15,15,15,17,16,16,16,17,17,16,18,18,17,18,18,18,18,19,20,21,20,20,19,21,22,21,22,21,20,21,21,20,19,20,19,19,18,17,16,16,17,17,17,16,16,16,15,14,14,15,14,14,13,11,11,11,11,11,11,11,10,10,11,8,10,11,11,11,13,12,12,11,14,13,13,14,13,15,14,15,15,16,15,16,17,16,15,17,16,16,17,18,17,17,18,19,18,18,18,20,21,20,20,20,19,18,21,21,21,21,20,20,21,19,20,21,21,21,19,20,20,19,19,19,19,18,18,17,19,19,17,17,17,16,17,16,16,16,14,15,14,15,14,14,14,13,12,13,13,11,11,13,13,13,13,15,14,13,13,15,15,14,14,14,15,17,15,15,17,17,15,16,16,15,16,16,16,15,15,15,14,15,14,13,14,14,13,14,13,13,13,14,14,13,14,15,15,13,13,15,14,14,16,15,13,13,15,14,13,14,15,14,13,12,11,11,11,12,12,12,12,13,11,12,13,13,13,12,12,12,12,13,12,11,11,10,11,10,10,11,10,8,8,10,8,8,8,8,8,7,8,10,8,9,10,10,10,11,11,11,9,11,11,15,15,16,16,16,18,16,17,19,20,19,22,20,21,21,22,25,23,22,23,24,24,21,25,24,21,22,25,23,21,20,24,24,21,24,19,22,19,23,20,18,19,18],[28,28,28,28,29,29,29,29,29,27,28,27,28,28,28,28,28,29,28,28,29,28,29,29,29,29,29,29,29,29,29,29,29,30,29,30,29,29,29,29,30,30,30,29,30,29,29,28,29,29,28,28,28,28,27,27,26,27,26,26,25,25,23,22,22,20,21,21,20,22,22,19,21,18,20,21,20,21,21,22,21,21,22,23,21,23,24,23,23,23,23,23,24,24,23,24,24,23,23,24,24,24,23,23,23,23,23,22,23,22,23,23,24,24,24,24,22,23,22,22,22,22,21,21,22,22,21,22,22,20,21,22,21,20,20,20,21,21,23,21,22,23,22,22,22,24,23,22,23,24,22,22,24,22,23,24,23,23,23,22,23,23,22,22,23,22,21,23,23,22,21,22,22,21,21,22,20,21,21,21,21,19,19,21,20,18,20,21,20,18,21,20,19,19,20,19,21,21,19,22,22,21,21,22,22,22,22,23,23,23,22,22,21,23,22,20,22,23,21,21,21,22,20,20,21,20,18,20,21,20,18,20,19,20,19,21,20,19,19,20,21,19,19,20,19,19,18,18,18,17,18,18,17,14,14,17,17,15,13,14,15,18,18,15,18,18,16,17,19,19,16,19,19,18,19,19,20,19,21,22,19,21,19,21,20,19,19,21,19,17,18,19,19,17,18,18,17,16,19,17,17,17,19,16,15,17,15,16,15,17,15,15,16,15,14,15,15,16,16,14,14,15,16,16,17,17,18,18,19,19,18,19,20,20,21,23,22,21,24,23,25,25,24,24,25,25,26,26,25,26,26,27,27,28,28,27,28,27,28,26,26,27,27,24,26,26,26,26,26,26,27,27,27,27,28,28,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,27,28,28,29,29,29,29,28,27,28,28,28,27,27,27,26,25,26,23,24,21,21,20,18,17,20,18,19,18,17,16,14,14,14,14,14,13,15,14,13,13,14,13,14,15,15,14,16,16,16,16,14,13,13,14,14,13,14,14,14,14,16,18,16,17,19,19,16,17,17,14,16,16,16,14,15,16,15,16,14,17,14,16,12,14,12,11,9,9,8,7,7,7,6,4,5,3,1,0,2,4,4,6,9,10,11,14,14,15,16,15,15,14,15,15,13,15,15,13,14,15,15,15,16,15,15,16,18,17,17,18,19,18,18,20,20,20,20,21,20,20,21,19,20,20,18,20,21,21,22,21,21,23,23,23,24,23,23,24,24,24,23,23,24,22,22,23,25,22,22,23,23,23,22,22,22,21,23,20,20,20,19,19,18,18,18,16,16,16,15,14,15,15,15,15,17,15,12,14,10,13,14,14,13,17,16,14,14,15,16,14,15,15,16,17,17,17,18,18,19,20,20,19,21,20,21,20,21,22,23,22,22,21,23,23,22,23,23,24,24,23,24,24,24,25,23,24,23,25,23,23,24,23,23,23,22,24,23,22,23,22,21,20,20,22,22,22,22,22,21,20,19,21,20,17,18,19,18,16,16,16,15,15,15,15,13,14,15,14,16,16,15,16,17,16,16,17,18,16,19,20,21,18,19,20,21,20,20,21,19,20,20,20,20,20,19,18,20,18,17,17,18,16,16,16,17,17,18,18,18,18,18,20,18,17,18,19,18,19,20,17,18,20,18,18,17,19,18,17,16,15,14,16,14,16,18,17,18,16,17,16,17,17,14,15,14,16,15,14,12,13,12,12,12,10,12,12,9,8,9,11,8,9,10,9,7,9,11,10,11,12,11,10,10,11,9,9,11,13,12,14,14,16,19,20,17,20,20,21,19,24,21,22,24,24,25,25,22,24,25,24,22,26,25,23,22,26,24,21,20,23,25,22,24,19,22,19,23,21,20,20,20],[27,27,27,27,28,28,28,28,28,27,27,27,28,27,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,29,29,29,28,29,28,28,28,28,27,26,26,26,26,24,24,23,24,23,23,24,24,22,22,19,22,23,23,23,24,24,22,24,24,23,24,24,24,25,24,24,26,25,25,25,25,25,25,26,25,25,25,25,25,24,24,25,25,23,23,24,24,25,25,25,24,25,23,23,24,23,23,24,22,22,24,24,22,23,23,21,21,23,22,21,20,22,23,23,24,23,23,24,24,23,24,25,25,24,24,25,24,25,24,24,24,26,26,24,26,24,25,25,25,24,26,24,24,24,25,23,23,24,24,23,22,23,20,22,21,21,22,21,21,21,23,19,20,21,21,20,21,21,21,22,21,21,22,22,21,22,24,23,22,22,23,23,24,24,24,24,24,24,23,25,24,24,24,24,23,22,23,24,22,22,23,22,20,21,22,21,20,21,21,21,22,23,22,21,22,21,22,20,21,21,20,20,20,19,19,18,19,18,18,16,17,18,18,18,17,17,17,19,19,17,20,19,18,22,20,20,19,21,22,19,21,21,21,21,23,23,22,22,23,23,22,21,21,22,21,19,21,19,22,20,19,20,20,17,21,20,19,19,20,20,19,20,17,17,19,17,16,17,17,15,14,16,16,19,18,18,21,19,19,20,19,20,21,21,22,23,21,22,22,22,23,24,24,24,25,24,26,26,25,26,26,27,27,27,27,27,28,28,28,28,29,28,29,28,28,27,27,28,27,26,26,27,27,26,26,27,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,28,29,28,29,29,29,29,29,28,28,28,28,28,28,27,27,26,26,24,25,21,23,21,21,21,23,19,21,20,21,20,17,19,17,17,17,18,18,17,16,17,17,16,17,18,18,17,18,20,18,18,15,16,14,17,16,16,17,17,16,17,17,20,18,21,21,21,19,21,20,18,19,21,20,17,18,20,18,18,17,18,17,16,16,14,14,13,12,12,9,10,10,9,8,8,9,6,5,1,0,2,3,5,8,8,11,11,15,15,17,17,16,15,16,17,16,17,16,16,18,17,17,18,18,18,17,20,20,19,20,19,22,20,20,21,22,21,22,21,23,21,23,20,22,23,21,22,21,23,24,24,24,24,24,25,26,24,25,25,25,25,25,25,26,24,25,25,25,25,25,25,25,24,25,24,24,23,24,24,23,21,22,22,20,20,21,20,19,19,19,18,17,18,17,17,17,15,13,13,13,15,17,16,16,20,19,17,18,18,20,19,19,16,19,19,20,21,21,21,20,24,23,20,22,22,23,24,24,24,24,23,24,24,25,25,25,26,26,26,25,25,26,26,26,26,25,26,25,25,24,24,27,24,26,25,24,25,24,24,25,25,24,24,23,24,24,23,24,23,24,24,22,23,22,19,21,21,20,20,19,20,19,19,20,19,18,17,20,20,19,21,20,21,20,21,21,23,19,21,22,21,23,21,21,22,23,22,22,24,22,23,23,22,24,22,21,20,23,21,19,20,21,19,20,20,20,20,21,20,21,22,20,22,21,20,22,22,21,23,22,22,22,22,21,22,22,21,20,20,20,19,21,19,19,20,20,19,21,20,20,21,20,21,19,18,18,19,20,19,16,17,15,16,14,14,15,15,12,13,12,11,10,11,11,10,8,10,12,11,11,14,13,11,10,11,10,11,12,15,15,16,17,16,19,20,19,19,21,22,19,23,20,23,23,23,27,26,23,24,26,24,24,27,25,20,22,26,25,21,21,23,26,22,25,20,22,20,23,21,19,20,21],[29,29,28,29,29,29,29,29,29,29,28,29,29,28,29,28,29,29,29,29,29,29,30,30,29,30,30,29,30,30,29,30,30,30,30,30,29,30,30,30,30,30,29,30,30,30,29,29,29,29,28,28,28,28,27,28,28,27,27,26,27,25,26,24,24,24,26,23,25,24,25,22,23,22,22,24,25,24,25,25,23,24,25,24,23,25,25,25,26,26,25,26,26,26,26,26,25,26,26,26,26,26,26,25,26,26,25,25,24,25,26,26,26,26,26,26,24,25,24,24,25,24,24,24,25,23,23,25,24,21,23,25,21,21,22,22,24,25,25,25,24,25,26,26,24,26,26,24,24,26,25,23,25,26,25,25,26,26,25,25,27,26,26,26,26,24,25,26,24,24,25,25,22,23,24,23,20,23,22,22,23,20,20,23,22,19,22,22,20,20,22,22,20,22,22,23,22,23,21,24,24,23,24,24,25,24,25,25,25,24,26,26,24,26,25,22,25,25,22,20,23,24,21,20,23,21,19,22,23,21,20,22,24,23,23,24,23,22,22,22,22,24,23,22,21,21,20,20,21,19,20,19,17,17,18,19,19,18,16,18,18,20,19,19,21,20,21,21,20,20,20,22,22,21,23,23,23,22,24,24,21,23,21,24,23,20,20,22,20,19,20,21,21,20,21,22,20,20,23,22,22,22,23,21,22,22,20,19,20,18,16,19,18,17,14,17,17,20,20,21,22,23,23,22,22,24,24,23,23,25,23,24,23,23,24,23,24,24,24,24,26,26,25,27,26,27,26,27,28,27,28,29,29,28,29,29,29,28,29,28,27,28,27,25,27,27,27,26,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,30,30,30,30,29,30,29,30,29,29,29,29,29,29,29,30,30,29,30,28,29,28,28,28,28,28,27,26,26,24,26,22,23,22,23,23,24,23,23,24,24,24,21,22,20,19,19,21,21,21,20,22,21,21,20,22,21,22,21,22,20,21,19,20,17,19,18,19,21,20,19,22,19,21,22,23,23,23,22,23,24,23,22,23,24,22,21,23,23,21,20,19,19,16,15,17,13,13,14,12,11,11,11,10,7,9,9,6,5,4,2,0,2,3,6,7,9,12,12,14,16,15,15,14,17,14,14,19,18,15,18,20,21,21,21,19,22,21,21,20,22,23,22,21,23,24,22,22,23,23,23,23,23,22,23,24,22,23,24,23,24,24,24,24,25,26,26,25,26,26,26,26,26,26,27,26,26,26,26,26,26,25,26,25,25,25,25,25,24,23,24,23,21,21,21,22,21,21,22,21,20,20,20,19,17,17,17,15,15,15,15,14,18,17,18,21,20,21,22,20,22,21,21,21,21,22,24,21,22,24,24,24,23,24,25,25,23,26,26,25,24,26,26,26,25,25,26,26,26,26,26,25,25,26,26,26,26,26,26,25,25,26,26,26,26,26,25,26,25,26,25,25,26,25,25,25,26,25,24,24,25,23,22,24,23,21,22,23,22,21,21,23,22,21,22,22,22,21,23,21,22,23,24,23,22,24,23,24,23,21,25,25,25,23,25,24,23,24,25,24,25,24,25,23,24,25,24,21,24,25,23,21,24,23,23,22,24,23,23,22,23,24,23,24,23,23,23,23,24,24,24,23,24,24,22,25,24,24,23,24,24,24,23,22,22,24,22,22,24,23,22,24,22,22,22,22,20,22,22,21,20,19,20,20,19,15,17,19,16,16,14,17,13,12,16,12,8,9,14,13,12,14,14,12,12,14,12,12,13,13,15,16,17,19,20,22,19,19,22,22,21,24,22,23,24,24,25,26,24,25,26,25,23,26,26,24,23,26,25,22,22,24,26,24,24,21,24,23,24,22,20,21,21],[28,28,28,28,29,28,28,29,28,28,27,27,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,29,28,28,28,28,26,26,26,25,25,25,23,25,24,24,24,25,22,22,19,21,23,24,22,25,24,22,23,25,23,22,24,25,24,25,24,26,25,25,25,26,26,24,25,25,25,25,25,24,25,25,24,24,24,23,24,25,24,25,25,25,25,23,25,22,23,24,23,22,22,23,22,21,23,23,20,22,23,21,21,22,21,23,23,24,23,23,24,24,23,22,25,24,22,24,25,24,22,25,24,24,25,25,24,24,25,26,25,25,25,25,23,24,25,23,22,23,24,21,21,23,22,19,22,22,21,21,19,18,21,20,17,21,22,19,19,21,20,19,21,22,21,23,22,21,23,24,23,23,24,24,24,24,25,24,23,25,25,23,25,24,21,24,24,21,19,22,23,20,20,22,20,17,20,21,20,17,21,21,21,22,23,21,22,22,21,20,20,22,20,20,19,19,19,18,16,17,18,14,15,16,17,18,16,16,15,14,19,17,15,19,18,17,20,19,20,19,21,21,20,21,22,22,21,23,23,21,22,21,23,22,19,20,21,19,18,20,18,18,18,19,19,15,14,18,20,19,19,19,18,20,19,16,17,18,17,12,18,18,16,13,17,16,21,19,19,20,20,21,20,20,21,22,22,21,24,23,23,23,23,24,26,25,24,25,25,25,26,26,27,26,27,28,27,27,28,27,28,28,28,29,29,29,29,29,28,28,28,28,27,28,27,27,28,27,27,28,28,28,28,29,29,30,29,29,29,29,29,29,29,30,30,30,30,30,29,30,29,29,29,29,29,29,28,29,29,29,29,29,28,29,28,28,28,27,27,26,26,26,24,26,22,23,23,22,23,23,22,22,22,21,21,19,18,18,17,17,18,18,17,17,18,18,17,19,19,20,18,20,21,20,20,18,16,16,16,15,17,17,19,18,17,19,21,19,22,22,22,20,21,21,20,20,21,21,18,20,20,18,20,18,17,16,13,14,15,13,11,13,12,10,10,10,9,7,9,9,7,7,5,4,1,0,2,3,5,5,9,9,11,12,12,9,10,13,9,9,14,14,11,17,16,15,18,19,17,17,21,20,18,20,21,22,20,22,22,22,22,22,23,22,22,22,22,23,23,21,23,23,23,23,23,23,24,24,25,25,24,25,25,25,26,26,25,26,25,25,25,25,25,24,25,25,25,25,24,24,24,23,23,23,22,20,21,21,19,18,20,19,18,16,17,18,15,13,15,14,9,11,12,11,9,14,16,15,17,17,18,20,19,20,20,20,19,19,21,22,20,22,23,23,24,23,23,23,24,25,25,25,24,25,25,25,25,25,25,25,26,26,25,26,24,25,25,25,25,25,25,26,25,24,25,25,25,26,25,25,25,25,25,24,25,25,25,24,25,26,24,24,24,24,22,23,24,23,19,22,22,20,20,21,20,19,20,21,21,19,19,20,21,21,22,21,22,22,21,22,23,22,22,24,23,24,23,24,24,24,24,23,24,24,24,24,22,24,24,23,20,24,23,21,22,23,21,20,23,22,22,23,22,23,24,23,24,24,23,23,23,24,24,24,24,23,24,24,23,23,23,23,22,21,20,20,19,20,21,21,22,22,21,22,21,22,22,20,21,19,20,20,20,18,17,17,18,17,16,17,18,15,13,14,16,10,10,12,11,7,7,9,12,11,14,13,13,12,14,13,11,13,14,17,17,19,20,21,23,22,22,23,24,22,25,23,24,25,24,27,26,25,26,26,26,25,26,26,24,25,26,25,23,24,25,26,24,25,23,24,23,24,22,21,22,21],[29,29,29,29,29,29,29,29,29,28,28,28,29,28,28,28,29,29,28,29,29,29,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,28,27,28,28,27,27,26,26,25,24,23,22,21,21,21,20,21,21,18,19,16,18,20,21,19,21,21,18,20,22,20,19,21,21,22,23,22,23,24,23,23,23,24,21,24,24,23,23,23,23,22,22,23,22,21,22,22,23,23,22,23,22,22,21,21,20,22,22,22,21,20,21,20,20,21,22,19,20,21,20,19,20,19,21,22,22,23,21,22,24,22,20,24,23,20,21,23,22,19,22,22,22,22,24,22,22,22,23,22,22,23,23,20,21,23,20,19,20,22,18,19,21,20,18,20,20,18,20,18,16,20,19,17,19,21,18,17,20,19,20,19,20,20,21,21,20,21,22,21,21,22,22,21,21,21,22,21,23,23,21,22,22,20,21,23,20,18,20,21,18,17,20,18,16,17,18,17,15,17,18,18,19,19,18,19,19,19,18,18,17,17,16,14,14,16,14,14,13,15,13,13,13,14,15,13,14,12,13,15,14,14,14,17,15,17,18,18,16,19,18,18,19,20,21,20,20,21,19,21,17,20,19,18,17,18,17,16,17,16,15,16,17,16,13,14,14,16,16,16,16,13,16,14,14,13,14,13,9,14,13,10,9,13,14,16,14,15,16,16,16,16,17,18,19,18,19,20,19,19,20,19,21,22,22,21,23,23,24,24,25,26,26,26,27,27,27,27,27,28,29,28,29,29,29,29,29,28,27,28,27,26,27,27,27,27,27,27,28,28,28,28,29,29,29,29,29,29,29,29,29,29,30,30,30,30,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,28,29,29,28,27,27,27,26,26,25,23,24,22,21,21,20,20,20,18,18,19,18,17,16,16,15,16,15,16,17,17,16,16,17,17,18,18,19,18,19,19,19,20,18,17,16,15,15,15,16,16,17,17,18,19,19,20,20,20,19,18,19,18,18,18,18,16,16,17,16,16,16,16,14,9,11,13,9,8,10,11,7,8,10,7,6,8,9,7,7,5,6,3,2,0,1,3,4,6,7,9,10,9,8,10,12,10,10,13,13,11,14,14,15,15,16,15,15,18,18,17,17,19,19,17,19,20,19,18,20,19,20,20,20,20,20,20,19,20,20,19,20,21,20,21,21,22,24,24,22,23,23,23,24,24,24,23,23,23,24,22,23,22,23,21,21,21,21,20,20,19,19,19,17,18,16,16,16,17,17,16,15,15,14,14,11,12,10,9,9,10,10,9,13,13,11,14,15,15,15,17,17,16,17,17,17,17,19,18,18,20,21,20,19,19,21,21,20,22,23,21,22,22,23,22,22,22,23,22,23,24,22,22,22,22,23,24,24,23,24,23,23,23,23,23,24,24,22,23,23,22,22,22,21,21,21,22,22,21,19,20,20,19,18,19,19,16,17,19,17,17,17,17,16,16,17,17,16,16,17,17,17,18,19,18,18,20,21,20,19,18,20,20,21,19,20,21,20,20,21,21,20,20,19,18,19,20,19,17,19,20,18,17,20,18,17,18,19,19,20,19,19,20,20,22,20,20,20,20,21,21,21,20,20,20,19,19,19,19,19,18,17,17,16,17,16,18,18,18,19,18,19,20,19,20,18,20,17,20,17,17,16,15,16,16,15,15,15,16,11,12,12,12,9,9,9,10,6,6,10,9,9,11,13,10,11,13,13,11,13,13,17,17,17,18,22,23,19,21,24,22,21,24,22,24,26,24,27,27,25,26,27,27,26,27,28,26,25,27,27,23,24,26,27,25,26,24,25,24,26,23,20,22,22],[29,29,28,28,29,29,29,29,29,28,28,28,29,28,28,28,28,28,28,29,28,28,29,29,28,29,29,29,29,29,28,30,29,30,29,30,29,29,30,29,29,29,29,29,29,29,28,28,28,28,27,27,27,27,26,26,26,25,25,25,24,22,21,21,20,19,19,18,19,18,19,17,16,14,15,16,18,16,19,18,15,17,19,17,15,19,19,20,20,19,20,20,20,21,19,20,18,20,20,20,20,20,19,19,20,19,18,19,18,18,19,19,19,19,19,19,18,18,17,17,18,19,17,17,18,16,16,18,17,15,16,18,15,16,17,17,17,18,18,18,18,18,19,18,16,20,19,15,17,20,18,16,19,19,19,19,20,19,20,19,20,20,20,20,20,17,18,19,17,16,17,17,15,14,16,15,13,15,15,14,14,13,13,15,14,13,14,15,14,14,16,15,15,16,16,18,18,17,17,19,18,18,19,19,19,19,19,19,19,19,19,19,18,19,17,16,17,18,16,14,16,16,14,14,16,14,13,14,15,14,12,14,15,15,16,17,15,14,15,14,14,14,12,13,13,11,10,12,10,9,10,11,8,8,9,11,12,12,10,9,9,12,11,11,13,13,12,14,14,14,14,16,15,14,17,16,18,16,18,17,15,17,14,17,16,14,14,15,14,14,14,13,13,12,13,12,9,9,10,13,12,13,11,11,12,11,10,10,12,9,8,11,10,8,7,11,11,14,12,13,14,15,14,13,15,16,18,16,17,18,17,19,17,18,19,19,20,20,21,21,23,23,23,25,25,24,25,26,26,25,26,27,27,28,28,28,28,27,28,26,26,26,25,24,25,26,26,25,26,26,27,27,28,27,29,28,29,29,29,28,28,29,28,29,29,29,29,29,29,28,29,29,29,28,28,28,29,28,28,28,28,28,28,27,28,27,27,26,26,26,24,24,23,21,21,19,19,18,18,18,17,17,17,18,16,16,12,15,12,12,12,15,15,14,15,16,16,15,15,16,17,16,16,17,16,17,16,16,14,13,13,13,14,13,16,15,16,16,16,17,18,17,16,17,16,16,16,16,16,16,12,14,15,13,13,11,11,10,9,11,8,7,9,8,6,6,7,6,6,7,8,7,6,7,7,5,3,2,0,1,3,4,5,6,7,8,7,7,8,7,8,9,9,9,11,10,10,10,12,11,12,14,14,14,15,16,15,15,18,18,17,16,17,17,17,17,17,17,17,18,17,17,18,16,18,18,16,17,19,21,20,19,19,20,20,21,21,21,21,20,20,21,21,20,20,19,20,19,18,18,18,18,18,16,16,16,14,15,14,14,14,13,13,11,11,9,9,11,9,9,10,7,8,8,8,8,9,10,10,10,10,10,11,12,13,13,14,14,14,16,16,15,16,17,18,16,17,17,18,18,17,19,20,19,18,20,20,20,19,19,20,21,20,20,20,19,19,21,20,21,21,20,20,20,19,20,21,21,21,21,20,21,20,20,19,19,19,20,19,19,19,18,16,17,17,16,16,17,17,15,14,16,14,15,15,15,11,12,14,11,11,11,15,14,13,16,17,15,16,17,16,16,17,16,18,17,18,17,19,18,18,18,18,18,19,17,18,16,15,18,17,16,16,17,16,15,17,17,15,15,17,17,17,16,17,17,17,17,16,17,17,17,17,18,18,17,17,17,17,18,17,17,17,16,16,15,15,15,16,17,17,16,16,16,16,16,17,17,16,16,15,16,15,13,14,12,12,10,11,10,11,10,10,10,9,10,8,8,9,8,6,4,10,8,8,10,11,10,10,13,12,10,12,13,15,16,17,18,20,23,19,18,22,22,19,23,20,23,25,23,25,25,25,25,25,25,25,26,26,25,24,26,26,23,23,26,25,24,25,23,24,24,25,23,20,23,24],[28,28,27,27,27,27,28,27,27,27,27,27,27,26,27,27,27,27,27,27,28,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,28,28,28,28,28,27,27,28,27,27,27,27,26,25,26,25,25,24,24,23,21,20,18,18,17,17,16,16,15,15,14,12,10,12,13,14,12,14,14,12,13,16,13,11,15,15,16,16,15,16,16,16,16,16,16,14,16,18,16,16,17,18,16,17,17,17,16,16,17,18,17,16,16,15,18,15,18,15,16,16,14,15,14,15,13,14,14,14,13,16,14,12,14,14,15,16,14,15,16,15,14,16,15,13,16,15,13,13,16,14,12,14,14,15,16,16,16,16,17,18,15,16,17,15,13,14,16,13,12,13,14,12,12,13,13,10,12,13,11,12,11,11,12,12,10,12,13,12,11,13,12,13,14,13,15,16,14,14,16,16,15,16,16,16,15,15,15,16,14,16,16,14,16,14,13,13,14,13,12,13,13,12,12,12,12,9,11,11,9,8,11,10,12,13,13,13,12,12,13,12,10,9,10,9,9,9,9,8,9,9,8,6,8,8,10,10,10,9,7,7,9,10,10,10,11,9,11,12,12,11,14,13,12,13,13,14,13,14,14,12,13,12,13,12,12,12,12,11,10,12,10,9,10,10,8,7,6,8,10,9,10,9,8,10,8,8,8,9,8,7,9,8,7,8,8,9,12,11,11,12,13,11,11,11,14,14,14,14,16,15,16,16,17,18,19,19,18,20,20,21,21,21,23,22,23,24,24,24,25,24,25,27,27,27,27,27,27,27,26,25,27,24,24,26,25,25,25,25,26,27,26,27,26,28,28,28,27,28,28,28,28,28,28,28,28,29,28,28,27,28,28,27,28,27,26,27,27,28,28,27,27,27,26,27,26,26,25,24,24,22,23,21,20,21,18,19,17,17,16,15,13,14,14,14,12,11,12,12,11,11,12,12,12,13,13,13,14,15,15,15,15,16,17,16,17,14,13,13,12,13,12,12,14,13,13,15,16,15,17,17,16,15,15,15,14,13,16,13,12,12,13,12,11,11,11,10,7,8,9,8,7,7,7,6,6,6,6,5,6,6,6,5,6,6,5,4,3,1,0,1,2,3,3,6,4,4,5,6,5,6,7,7,7,9,9,8,9,11,10,10,11,11,11,12,12,13,12,12,14,14,13,13,14,13,14,15,15,15,14,13,13,14,13,14,14,13,14,15,16,17,17,16,18,18,19,17,18,18,17,17,17,17,16,17,16,16,15,15,14,14,14,14,14,13,12,12,12,11,11,11,12,12,9,9,10,10,7,6,7,7,5,5,7,6,5,7,8,8,9,9,9,10,12,12,11,13,11,12,12,12,12,12,13,13,14,14,13,14,14,14,15,16,16,15,16,17,16,16,15,17,16,17,17,15,15,15,17,18,17,17,17,17,17,17,17,17,18,18,18,17,17,18,17,17,17,16,16,16,16,16,14,13,14,14,13,13,14,13,11,12,13,12,12,13,13,10,11,14,11,10,11,12,11,12,14,13,13,14,13,13,14,13,13,14,13,14,13,15,16,15,15,15,16,16,15,14,13,14,15,14,13,14,13,13,13,14,14,13,14,14,14,15,14,14,16,15,16,16,16,15,15,15,16,16,15,16,15,15,16,15,14,14,14,13,12,13,14,13,14,14,14,16,14,15,14,15,17,14,14,12,14,13,12,12,12,11,11,10,9,10,9,9,7,8,9,6,6,5,6,4,5,7,6,8,9,12,10,10,11,12,12,11,12,16,16,18,18,22,22,18,19,23,22,18,24,20,22,24,24,26,25,25,24,26,25,25,26,26,24,24,26,26,22,22,25,25,24,25,22,24,24,24,22,20,23,24],[29,29,29,29,29,29,29,29,29,28,28,28,29,27,28,27,28,28,28,28,28,27,28,28,27,28,29,28,29,29,27,29,29,30,28,29,28,29,29,29,29,29,28,28,28,28,27,27,27,26,26,26,26,25,24,26,25,24,23,23,22,19,17,15,14,13,12,12,12,11,11,10,9,7,8,9,9,10,10,10,9,10,11,10,9,10,11,12,12,11,12,12,11,12,12,12,11,12,12,12,12,12,13,12,13,13,13,13,12,13,14,13,12,13,12,12,12,12,12,11,12,11,11,11,12,10,11,11,11,10,11,10,9,11,11,12,10,12,11,12,12,11,11,11,10,11,11,10,10,12,10,10,10,10,11,12,12,12,13,13,13,12,12,12,11,10,11,11,10,10,10,9,9,9,9,9,8,9,9,9,9,9,8,9,9,8,9,9,9,9,10,8,9,10,10,12,12,11,11,12,12,12,12,14,13,12,12,12,12,12,12,11,11,11,10,10,10,10,10,8,9,9,9,8,8,9,7,8,8,7,6,8,9,9,10,10,9,9,10,9,9,8,8,8,7,6,6,6,5,5,6,5,5,5,6,6,7,7,7,5,5,6,6,6,7,7,6,8,9,9,8,10,9,9,9,9,11,11,10,10,10,9,9,9,8,9,8,9,8,7,8,7,6,6,7,5,5,5,5,6,7,8,6,6,7,6,5,6,6,5,5,6,6,5,5,7,7,9,9,9,9,10,10,9,9,10,10,11,10,11,11,13,12,12,14,15,16,17,18,19,20,19,20,23,22,22,23,24,24,25,26,26,27,26,27,27,28,27,28,25,26,26,24,24,25,25,26,24,26,26,27,28,28,27,28,28,28,28,29,28,28,29,29,29,28,29,29,29,28,28,28,28,28,28,28,27,28,28,27,28,28,26,28,26,26,26,26,26,24,24,23,22,21,20,19,17,16,15,14,13,13,10,11,11,10,9,9,9,9,10,9,10,11,11,11,11,12,12,11,12,13,13,12,14,14,13,13,12,12,11,11,11,11,11,13,13,13,14,13,13,14,13,13,11,12,11,11,11,11,10,10,10,9,9,9,8,7,6,6,6,5,4,5,5,5,4,5,5,4,5,6,6,5,6,7,6,5,3,2,1,0,1,3,2,4,4,3,4,4,4,4,5,5,4,6,7,6,7,7,8,7,9,8,8,9,9,10,10,10,10,10,9,10,11,11,12,12,13,12,12,11,11,11,11,12,12,10,11,12,12,12,13,13,14,15,14,14,14,14,13,13,13,13,13,12,11,12,12,11,11,11,10,10,10,10,9,9,9,9,8,7,8,8,7,6,7,7,6,5,5,5,4,3,6,5,4,6,6,6,6,8,7,7,8,9,8,9,8,9,10,9,10,10,10,10,10,11,11,12,11,11,12,12,11,11,12,12,12,12,11,12,13,13,13,12,12,12,13,13,12,13,13,13,14,13,15,15,15,14,14,14,14,14,13,13,13,13,13,12,12,12,11,10,10,10,10,10,10,10,9,9,9,9,9,9,9,8,8,9,9,8,8,9,10,9,10,10,10,11,10,10,10,10,11,11,10,11,11,11,12,11,10,11,11,12,10,10,10,10,10,10,10,9,10,9,10,10,10,10,9,10,11,11,10,11,11,11,12,11,11,12,11,10,12,12,10,11,11,11,11,10,10,10,10,9,10,10,10,10,10,11,10,11,11,11,11,11,12,11,10,10,11,10,10,10,9,8,8,7,8,8,8,8,6,6,6,5,4,5,5,4,3,4,5,7,8,10,10,10,14,13,12,12,14,16,16,17,18,21,22,20,18,22,22,19,23,20,23,24,22,25,25,25,25,23,24,26,26,24,25,24,25,25,22,22,25,24,24,24,24,23,25,25,23,21,24,23],[27,27,26,27,27,27,27,27,27,26,26,26,26,26,26,26,26,26,26,27,27,26,27,27,27,27,27,27,28,27,26,28,28,28,27,28,27,28,28,28,28,28,27,27,27,27,26,26,27,25,26,25,26,25,24,25,24,24,23,22,20,19,17,14,14,12,11,11,11,10,10,10,8,7,8,9,9,8,9,9,8,9,9,9,8,9,10,11,11,9,11,11,10,10,12,11,9,11,12,11,10,12,12,10,10,12,12,11,11,12,12,12,11,10,10,11,10,11,11,10,9,9,9,9,9,9,9,9,9,8,9,9,8,8,9,10,10,9,10,10,10,9,10,9,8,9,9,9,9,10,9,9,9,9,10,10,11,10,10,12,11,10,10,10,10,9,10,10,9,8,9,9,7,7,8,8,7,7,7,7,8,7,7,7,7,6,7,7,7,7,8,7,8,8,8,10,10,10,10,11,11,11,11,12,12,11,12,11,11,9,11,10,9,9,9,8,9,8,8,8,8,8,7,7,7,7,6,6,7,6,5,6,7,8,8,8,8,8,8,7,6,6,6,6,6,5,6,6,4,4,5,4,4,4,5,5,6,7,6,4,4,4,4,4,6,6,6,6,7,7,8,8,8,9,9,8,9,9,9,9,8,8,8,8,7,7,8,8,6,6,6,5,5,5,6,6,4,4,5,6,6,6,5,5,6,6,4,6,6,5,5,5,6,4,4,5,6,7,6,7,8,8,8,8,9,8,10,11,10,10,11,12,12,12,14,14,15,16,19,18,20,18,19,21,20,21,22,22,21,23,23,23,25,25,25,25,26,25,26,24,24,25,24,23,25,24,25,24,25,25,26,26,27,26,27,27,28,27,28,27,27,28,28,28,28,28,28,28,27,27,27,28,27,27,27,26,26,27,27,28,27,27,27,25,25,26,26,24,23,23,21,22,20,18,18,16,15,15,14,12,12,10,10,10,9,9,8,8,8,7,8,8,9,9,9,9,11,11,11,11,12,12,12,14,14,13,12,11,10,10,10,9,10,11,11,10,12,14,12,14,14,13,12,11,12,11,10,11,10,10,9,9,8,8,7,7,7,5,5,6,5,5,5,5,4,5,5,4,4,5,5,5,5,6,6,5,5,5,3,2,1,0,1,2,2,3,2,2,3,3,3,4,5,4,5,5,5,6,6,6,7,8,8,8,8,8,9,9,9,10,9,9,9,10,9,10,11,11,12,11,10,10,10,9,10,10,8,10,11,12,12,12,12,13,14,14,13,13,13,12,13,13,12,12,12,10,11,11,10,10,10,10,9,9,9,9,8,8,9,7,6,7,7,6,5,6,6,5,5,5,5,4,4,5,5,4,5,6,5,6,6,7,7,8,9,8,8,8,8,10,9,10,10,10,9,10,10,10,11,11,10,12,11,11,10,13,12,11,11,10,12,11,13,12,10,10,10,12,12,11,12,13,12,13,13,13,13,14,13,14,13,13,13,13,13,12,12,11,12,11,11,11,9,10,9,10,9,9,10,8,9,9,8,9,9,8,7,9,9,8,7,8,8,9,9,10,9,10,11,10,10,11,10,10,11,10,11,9,11,11,11,10,12,11,12,11,10,10,9,10,10,10,10,9,10,10,10,10,10,11,10,10,11,10,11,12,11,12,11,11,11,11,11,11,11,11,11,11,12,12,11,10,11,11,9,10,9,10,10,10,11,10,11,11,11,11,12,12,10,11,9,12,9,9,9,8,8,9,7,6,7,7,6,6,6,6,5,5,4,4,4,3,4,4,6,7,9,9,10,12,12,12,11,12,15,16,17,19,19,21,18,18,22,21,19,23,20,21,24,23,24,24,25,25,25,25,25,25,26,26,25,25,26,23,23,24,25,24,24,22,23,23,23,21,20,22,23],[29,28,28,28,28,28,28,29,28,27,28,27,28,26,26,26,28,28,27,28,28,26,28,28,27,28,28,27,28,27,27,28,28,28,27,28,27,27,28,28,28,28,28,28,27,27,27,26,27,26,25,24,25,24,23,24,23,22,22,21,19,18,15,12,11,10,9,9,8,8,7,6,6,6,5,6,6,5,6,6,5,6,6,6,5,6,7,8,8,7,8,8,7,7,9,8,8,8,9,8,8,9,9,8,9,10,9,9,9,10,10,9,9,8,8,9,9,8,8,8,8,7,7,7,7,7,6,7,7,6,7,7,6,6,7,8,8,8,7,8,8,7,8,7,6,7,8,7,7,7,7,6,7,7,7,8,8,8,8,9,8,7,7,8,7,6,7,7,7,6,7,6,6,6,7,6,6,5,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,8,8,8,8,8,8,9,9,9,8,9,8,8,8,8,8,7,7,7,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,4,5,6,6,7,7,6,6,6,6,5,5,5,5,4,4,4,4,4,3,4,4,3,3,4,5,5,6,4,4,3,4,4,4,4,5,5,5,5,5,6,6,6,6,7,6,7,7,6,7,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,4,5,4,4,5,4,4,4,5,4,4,5,5,4,5,5,6,6,6,7,7,7,7,7,7,7,8,8,8,8,9,9,10,10,12,13,13,14,16,15,17,16,18,19,18,19,20,21,21,22,22,23,24,24,25,25,25,25,25,24,24,25,23,23,24,24,25,24,25,25,27,26,27,26,27,26,27,27,28,28,27,28,28,28,27,28,28,27,27,27,27,28,27,26,27,27,27,27,26,27,26,26,26,26,26,25,25,24,23,22,21,21,19,18,18,16,15,14,12,10,10,9,8,8,7,8,7,7,7,7,7,8,8,8,8,9,8,9,10,10,11,11,11,12,13,11,11,10,9,9,9,8,9,9,10,10,11,12,12,11,11,11,10,9,10,9,8,9,9,8,8,8,7,7,7,7,7,5,5,5,5,5,5,5,4,4,5,4,4,5,6,5,5,6,6,5,4,4,4,2,1,1,0,1,1,3,1,3,3,3,2,4,5,4,5,5,6,4,5,6,5,5,5,6,6,6,6,6,6,7,7,6,7,7,7,8,9,9,9,8,8,7,7,7,7,8,7,7,8,8,8,9,9,9,10,11,10,9,9,9,9,9,9,8,9,7,7,7,7,7,7,6,6,6,6,6,5,5,5,5,4,5,5,4,5,4,5,4,4,4,4,3,3,5,4,4,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,7,7,8,8,8,8,7,8,8,9,8,7,7,7,8,9,8,9,9,10,10,9,10,10,10,10,11,10,10,9,10,9,9,9,8,9,8,8,7,6,6,7,6,6,7,7,5,6,6,6,5,6,6,6,5,6,7,6,6,6,6,7,7,7,7,7,7,8,8,7,7,7,7,8,7,8,9,8,8,8,8,8,7,8,7,7,7,8,6,7,7,7,7,7,7,7,7,8,8,8,8,7,9,9,9,9,9,9,8,9,9,9,9,9,9,8,8,8,8,8,8,7,8,8,7,8,8,8,8,9,8,8,8,9,9,9,8,7,9,7,8,7,6,7,7,6,6,6,5,5,5,5,4,4,5,4,4,4,4,4,4,5,7,8,9,10,11,11,12,11,13,15,15,16,18,20,21,18,19,21,20,19,22,20,22,25,23,23,25,26,24,23,25,24,24,25,25,24,25,25,23,24,24,25,24,24,23,24,23,24,23,21,23,24],[27,27,27,27,28,28,28,28,28,26,26,26,26,25,26,26,25,27,25,27,27,26,27,27,26,27,27,27,27,26,26,27,28,28,26,27,26,27,27,27,27,27,25,26,26,26,25,23,24,23,23,23,24,22,20,22,21,20,19,20,17,15,13,11,9,8,7,7,6,6,5,5,4,4,4,4,5,4,5,5,4,4,5,4,4,5,5,5,6,5,6,6,6,5,6,6,6,6,6,6,6,7,7,6,7,7,7,7,7,8,8,7,6,6,6,7,6,6,6,6,6,5,5,6,6,5,6,6,6,5,6,6,5,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,5,5,4,5,5,4,4,5,5,5,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,6,6,6,6,6,6,6,7,8,7,7,7,6,6,6,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,4,5,4,3,2,3,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,2,3,3,3,3,3,3,3,2,3,3,3,3,3,4,3,3,4,4,5,4,5,6,6,4,5,5,6,6,6,6,6,7,7,8,8,10,11,12,12,15,15,16,16,17,19,18,17,19,20,20,20,21,23,23,23,24,24,25,24,25,24,22,23,22,22,22,22,24,23,23,24,25,26,27,25,27,27,27,26,27,27,26,26,26,26,26,27,27,26,26,26,26,26,26,26,26,25,27,26,25,26,26,25,26,23,24,25,24,23,22,21,20,19,18,16,15,14,12,12,11,9,9,7,7,6,6,6,5,6,5,6,6,6,7,7,7,8,9,8,8,9,9,9,10,11,11,10,10,9,9,8,7,8,8,8,9,9,10,11,10,11,11,10,9,8,9,9,7,8,7,7,6,6,6,5,5,5,4,3,4,4,3,3,4,4,3,4,4,4,4,4,5,5,6,7,7,5,5,4,3,3,2,2,1,0,1,2,1,1,1,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,7,8,8,8,7,6,5,5,5,6,6,5,5,6,7,7,8,7,8,8,9,8,8,8,7,7,7,6,6,6,5,6,5,5,5,5,5,4,4,5,4,4,3,4,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,3,3,3,4,3,3,4,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,7,8,8,9,8,9,8,9,8,8,8,8,7,7,7,7,6,6,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,5,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,7,7,7,7,6,7,8,7,7,7,7,7,7,6,7,7,6,6,6,6,6,7,6,7,7,6,7,6,7,7,7,7,8,7,7,7,7,7,6,6,6,5,6,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,5,6,7,8,9,11,10,11,11,14,14,16,17,19,20,21,19,17,20,21,18,22,19,22,22,21,24,24,24,24,23,24,25,24,22,25,24,22,24,22,23,23,23,23,24,22,21,23,24,20,20,22,22],[27,28,28,28,28,28,28,28,28,27,26,25,27,25,27,26,26,27,26,27,27,26,27,27,26,27,28,27,28,27,25,27,28,28,27,27,27,27,28,27,27,27,27,26,27,27,26,25,26,24,24,24,25,22,21,23,23,21,21,20,18,16,13,9,8,7,6,5,5,4,4,3,3,3,3,3,3,3,4,4,3,3,4,3,3,4,4,4,4,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,5,5,5,5,4,4,4,4,4,4,5,4,4,5,4,4,4,4,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,4,3,4,3,3,3,3,4,4,3,3,4,4,3,4,4,5,5,5,4,5,5,5,5,5,5,6,5,5,5,4,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,3,3,4,4,3,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,3,3,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,1,2,2,2,3,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,4,4,4,5,4,4,4,4,5,5,4,5,5,6,6,7,7,8,10,11,12,14,17,17,15,17,19,18,18,22,22,21,23,22,25,24,23,25,25,26,25,25,23,23,25,23,23,24,23,25,24,23,24,27,25,28,25,27,27,28,27,27,27,27,28,27,28,27,28,27,27,27,26,27,27,27,26,27,27,26,27,25,27,26,26,27,24,25,25,25,24,24,22,21,21,20,17,17,15,13,12,10,8,7,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,7,7,8,8,8,9,9,10,8,9,8,7,7,6,6,6,7,7,7,9,10,9,9,8,9,8,7,7,7,6,6,6,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,5,5,5,6,6,5,4,3,3,2,2,1,1,0,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,5,4,5,6,7,6,5,5,4,4,3,4,4,4,4,4,5,5,6,5,6,7,7,7,6,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,5,4,5,4,4,5,5,5,5,4,4,5,5,5,5,5,5,5,6,6,6,6,7,6,7,6,6,6,7,6,6,6,5,5,4,4,3,3,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,5,5,5,5,5,6,6,6,5,6,6,5,6,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,6,6,5,6,6,5,5,4,6,5,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,4,6,7,7,9,10,9,11,10,12,13,14,16,17,19,18,16,17,20,18,18,21,19,21,22,21,23,23,23,22,23,23,24,23,23,24,23,22,25,22,24,24,23,24,23,23,24,23,24,22,20,24,24],[28,28,28,28,28,28,28,28,27,27,27,26,26,26,26,25,26,27,26,26,27,26,26,26,26,26,27,27,27,26,26,27,27,28,26,26,26,27,27,26,27,26,27,26,26,25,24,23,24,23,23,23,23,22,20,22,21,19,19,19,16,15,12,9,8,7,6,5,5,4,4,3,3,2,3,3,3,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,6,5,6,6,6,6,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,4,4,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,4,4,4,3,4,4,4,4,4,4,5,5,6,6,6,8,10,10,11,13,14,15,14,15,17,17,17,18,19,18,19,20,22,22,22,23,23,23,23,24,22,22,23,21,21,23,22,24,23,23,24,25,25,26,25,26,26,27,26,27,27,27,27,27,27,26,26,27,27,26,26,27,27,26,26,26,27,25,26,26,26,26,25,26,25,24,24,25,24,23,22,22,20,19,16,16,14,12,11,9,8,7,5,5,4,4,4,4,4,4,4,4,5,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,7,7,6,6,6,6,6,7,7,8,8,7,8,8,8,7,6,6,6,5,5,5,5,4,4,4,4,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,4,5,5,5,4,4,3,3,2,2,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,5,4,5,6,6,6,5,4,4,4,3,4,4,4,4,4,5,5,6,5,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,6,7,6,6,7,6,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,3,4,4,4,4,5,4,4,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,5,5,5,6,5,5,5,5,5,5,5,5,4,5,4,4,5,4,4,4,4,4,4,4,5,5,5,4,5,5,5,5,5,5,5,4,5,4,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,5,6,6,8,9,9,10,10,13,12,14,16,17,19,20,18,17,19,19,17,21,18,20,21,20,23,22,22,22,22,21,24,22,22,22,23,22,22,20,22,23,21,21,22,21,21,22,23,20,20,23,22],[28,28,28,28,28,28,28,28,27,27,27,26,27,26,27,26,26,27,26,26,27,27,26,27,27,27,27,27,27,26,27,27,27,28,27,27,27,27,27,27,27,27,26,26,26,26,25,24,25,24,24,23,22,22,20,21,20,21,19,18,16,14,11,8,7,6,5,4,4,4,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,6,6,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,4,4,5,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,6,6,7,9,10,10,13,13,15,13,15,17,16,16,18,18,18,19,20,21,23,22,23,23,25,24,25,22,22,24,22,22,22,23,23,22,23,23,26,25,26,24,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,26,27,26,27,26,26,25,25,26,25,25,26,25,26,24,24,24,24,23,22,21,20,19,18,16,15,14,12,10,8,7,6,5,4,4,4,4,3,4,3,3,4,4,4,5,5,5,5,5,6,6,6,7,6,7,7,7,7,6,6,5,6,5,5,5,6,6,7,7,7,6,6,7,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,3,2,2,3,3,2,3,3,4,4,5,5,5,4,4,3,2,2,2,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,5,6,6,6,4,4,3,3,3,4,4,3,4,4,4,5,5,5,5,6,6,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,5,6,6,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,4,5,4,5,4,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,3,4,5,6,7,8,9,9,9,12,11,14,16,18,18,20,18,17,19,21,16,22,18,20,21,21,22,22,24,22,21,21,23,23,21,24,23,22,23,22,22,22,22,22,21,22,21,22,23,21,21,23,22],[27,27,27,27,28,27,27,27,27,26,26,25,26,25,25,25,25,27,26,26,27,26,26,27,26,26,26,26,26,25,26,26,26,27,26,26,26,26,26,26,26,26,25,26,26,26,24,23,23,23,22,22,22,21,20,21,20,19,19,17,15,14,11,8,7,6,5,4,4,4,4,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,4,4,4,5,5,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,3,3,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,2,2,3,3,2,3,3,3,4,3,3,4,4,4,4,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,6,6,7,10,10,10,12,14,15,13,14,16,15,16,17,17,17,18,18,20,21,20,22,21,23,23,23,22,22,22,22,21,22,21,23,22,22,23,26,24,26,25,25,25,26,25,26,25,25,25,25,26,26,26,26,26,26,26,26,26,26,25,26,25,24,26,25,25,25,24,26,25,25,24,24,22,22,21,19,18,17,15,15,13,12,10,8,7,6,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,7,7,7,7,7,7,7,6,6,5,5,5,5,6,6,7,7,7,7,7,7,6,5,6,6,5,5,5,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,5,5,4,3,3,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,5,6,6,4,4,3,3,3,3,3,3,3,4,4,4,5,5,5,6,6,6,6,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,3,4,4,3,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,5,6,6,6,6,5,6,6,5,5,5,4,4,4,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,4,4,3,3,4,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,3,4,4,4,4,4,4,5,5,5,5,4,5,5,4,4,4,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,5,6,7,8,9,9,10,9,12,12,15,17,18,19,19,16,17,19,19,17,21,18,19,21,20,21,23,22,21,22,23,24,22,23,22,22,22,24,20,22,22,22,22,22,21,21,22,23,22,20,21,22],[28,28,28,28,28,28,27,28,27,27,27,25,26,25,26,25,25,27,25,26,26,25,25,26,25,26,26,26,26,25,25,25,26,27,25,26,25,25,25,25,26,25,25,25,24,24,23,22,23,22,21,21,22,19,18,19,19,17,17,17,14,13,10,8,7,5,4,4,4,3,3,3,2,2,2,2,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,4,3,3,4,3,3,4,4,3,3,4,4,4,4,4,5,4,4,5,6,5,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,4,3,3,3,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,4,4,4,5,5,5,7,8,9,9,11,13,13,12,14,16,15,15,17,17,17,18,18,20,21,20,21,22,23,22,23,22,21,23,20,21,21,21,23,22,23,22,25,24,27,24,25,26,26,25,25,25,26,25,26,25,25,26,26,26,25,25,27,26,26,25,26,24,25,26,25,25,25,24,25,23,22,23,23,22,21,19,19,18,17,15,14,13,11,9,8,6,5,5,4,3,4,4,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,7,6,7,7,7,6,5,5,5,5,5,5,6,6,7,7,6,6,6,6,5,5,6,5,4,5,5,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,5,4,4,3,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,3,3,2,3,3,3,3,3,4,4,4,4,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,5,5,5,5,5,4,4,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,4,4,5,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,4,4,6,6,8,8,9,10,9,12,12,15,16,17,19,19,17,16,19,19,17,20,18,20,21,20,23,22,23,22,22,23,24,22,22,24,23,22,23,22,23,23,22,23,22,22,22,22,24,21,20,23,23],[29,28,28,28,28,28,28,27,27,26,27,26,26,25,26,25,25,27,25,25,26,26,25,26,26,25,26,26,26,25,25,26,26,27,25,26,26,26,26,25,26,25,25,25,24,24,23,22,23,23,22,21,22,21,18,19,18,18,17,17,13,12,10,7,6,5,4,4,4,3,3,2,2,2,2,2,3,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,3,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,6,8,9,9,11,12,13,12,12,14,15,14,16,17,16,16,17,19,20,19,21,21,22,22,23,21,20,22,20,20,21,21,22,21,21,21,23,24,27,23,24,25,25,25,25,25,25,25,25,25,25,26,25,26,26,25,26,26,26,25,25,24,24,25,25,25,25,24,25,23,22,23,24,22,21,19,19,19,17,15,14,13,11,10,7,6,5,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,4,5,5,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,5,4,4,3,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,3,2,2,2,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,4,5,5,5,5,4,5,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,3,4,5,6,7,8,9,9,9,13,12,15,16,17,19,19,19,18,19,20,17,21,17,21,21,20,24,23,23,22,23,21,25,23,22,24,23,22,21,20,23,22,21,21,20,22,20,23,22,21,21,23,22],[28,28,28,28,28,27,28,28,26,27,26,25,26,25,25,25,26,27,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,25,26,25,26,25,25,26,26,25,25,25,25,24,23,23,23,22,21,21,21,19,19,18,20,17,17,14,13,10,8,7,6,5,4,4,4,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,5,5,5,5,6,6,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,5,4,5,4,4,4,4,4,3,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,4,4,3,4,4,4,4,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,4,4,3,4,4,4,5,6,6,7,9,9,10,11,12,13,12,13,14,15,14,16,17,17,17,18,19,21,20,21,21,22,21,22,20,20,22,20,20,21,20,22,20,22,22,24,23,25,24,24,25,25,25,25,25,26,26,26,26,25,26,26,26,25,25,26,26,26,25,25,24,24,25,25,25,25,24,25,24,23,23,23,22,21,21,19,19,17,15,15,13,12,10,8,6,6,5,4,4,4,4,3,4,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,6,6,6,5,5,5,5,5,6,6,6,7,7,6,6,6,6,5,6,5,5,5,5,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,5,5,5,4,4,3,3,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,3,2,3,3,3,3,4,4,4,5,5,5,5,4,4,3,3,3,3,3,3,3,4,4,5,5,5,5,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,1,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,5,6,6,6,6,5,6,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,4,3,4,4,4,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,4,5,5,5,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,6,6,7,9,9,9,8,13,14,14,16,17,18,19,16,17,18,18,16,21,18,20,21,21,24,23,22,20,23,22,23,23,23,22,21,22,24,20,20,21,22,22,21,21,21,22,23,21,19,21,22],[28,28,27,27,27,27,27,27,27,26,26,24,26,25,25,25,25,26,25,26,27,26,26,26,26,26,27,26,27,25,25,26,26,27,26,26,25,26,26,26,26,25,25,25,26,25,24,23,23,23,21,22,22,20,18,20,19,18,18,18,15,13,11,8,7,6,5,5,5,4,4,3,3,3,3,3,4,4,4,4,3,3,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,3,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,3,4,5,5,5,5,5,5,5,5,5,5,4,5,4,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,3,3,4,4,3,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,2,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,7,9,10,10,12,13,14,12,13,15,16,15,17,17,17,18,19,20,21,21,22,21,24,22,23,22,21,23,22,21,22,22,23,23,22,22,25,24,26,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,26,26,26,25,25,25,25,26,25,26,25,25,23,24,23,23,22,21,20,19,19,17,15,15,13,12,10,9,7,6,5,5,5,5,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,8,8,7,8,7,7,6,5,6,6,6,7,7,7,8,7,8,7,7,7,6,6,6,5,5,6,5,5,5,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,5,5,6,6,5,4,3,3,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,6,6,4,4,3,3,3,3,3,3,4,4,5,5,5,5,5,6,6,6,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,5,6,6,6,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,4,3,3,4,4,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,5,5,6,5,5,6,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,4,5,7,7,8,9,10,10,9,13,14,15,17,17,20,19,17,18,20,19,17,21,17,19,20,20,23,23,21,22,22,22,23,23,22,24,23,22,23,21,22,23,23,22,23,22,22,23,24,21,21,23,23],[28,28,28,28,28,28,28,28,27,27,27,27,27,25,26,26,25,27,25,26,26,26,26,26,26,26,27,26,27,25,25,26,27,27,26,27,26,26,26,26,26,26,25,25,25,25,24,22,24,23,21,20,21,20,18,20,19,17,17,18,16,13,11,8,7,6,5,5,5,4,4,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,5,5,4,5,5,5,5,4,4,4,4,3,4,4,4,3,4,4,3,4,4,3,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,3,2,3,3,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,7,9,10,10,12,13,14,12,14,16,15,16,17,17,18,18,19,20,21,21,22,22,24,23,23,22,22,23,21,20,22,21,22,22,23,23,24,24,26,24,25,26,26,26,25,26,26,26,26,26,26,26,26,26,26,26,27,26,27,26,26,24,25,26,25,26,26,25,26,23,23,24,24,22,22,20,21,19,18,17,16,15,13,10,9,8,6,6,5,4,5,5,4,4,4,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,8,7,7,6,6,6,6,6,6,7,7,8,8,7,7,7,8,7,6,6,6,5,5,6,5,5,5,4,4,4,3,3,2,2,3,2,2,2,3,3,2,3,3,3,3,3,4,5,6,6,6,5,4,3,3,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,4,3,4,5,6,6,4,3,3,3,3,3,3,3,3,4,4,4,5,5,5,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,3,3,3,3,3,3,4,3,3,4,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,5,4,4,5,4,5,5,5,5,4,5,5,4,4,4,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,4,6,7,7,9,10,11,11,11,14,14,16,16,17,19,19,20,18,19,20,19,21,19,21,21,22,24,24,23,23,22,23,25,22,22,25,24,22,23,23,24,23,22,24,22,23,22,24,24,23,22,24,24],[28,28,28,28,28,28,28,28,27,27,26,25,26,25,26,25,26,26,25,26,26,26,26,26,26,27,26,26,27,26,26,27,27,27,26,27,26,26,27,26,27,26,25,25,25,25,24,23,23,23,22,21,22,21,18,20,18,18,16,17,15,13,11,8,8,7,6,5,5,4,4,4,3,3,3,3,4,3,4,3,3,3,4,3,3,3,4,4,4,4,4,5,4,4,5,4,4,5,5,5,4,5,5,5,5,6,6,6,6,6,7,6,5,5,5,6,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,3,3,4,4,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,5,5,4,4,5,5,6,6,6,8,10,11,10,12,13,14,12,13,16,15,14,16,17,16,17,18,20,20,20,22,22,23,22,23,21,20,22,20,21,21,22,22,20,22,22,24,24,27,24,26,25,26,26,26,26,26,26,26,26,26,26,26,27,27,26,27,27,26,26,26,25,26,26,25,25,26,24,26,24,24,25,23,23,21,21,20,19,17,16,15,14,12,11,9,8,7,6,5,5,5,5,4,5,4,5,5,5,5,6,6,6,6,6,6,8,8,8,7,8,8,8,8,7,7,7,7,7,7,7,7,8,8,8,8,7,8,8,7,6,6,6,6,6,6,6,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,7,6,5,4,3,3,2,3,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,4,4,4,5,5,6,6,5,4,3,3,3,3,4,3,4,4,5,5,5,5,6,6,6,6,6,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,4,5,7,7,8,10,11,10,11,14,13,15,17,18,19,20,18,18,20,21,18,22,18,22,21,21,24,24,20,22,23,23,24,22,22,24,22,23,22,21,22,22,21,22,22,22,22,23,23,21,20,22,22],[27,27,26,26,27,25,26,27,24,25,25,23,26,23,24,24,25,25,24,25,25,24,25,25,25,26,26,25,26,26,25,26,26,27,25,26,25,25,26,25,26,25,25,24,24,23,23,22,22,22,20,20,21,20,18,18,18,17,17,16,14,13,11,9,8,7,7,7,6,5,5,5,4,4,4,4,5,4,4,5,4,4,5,4,4,4,4,5,5,5,5,5,5,5,6,5,5,5,5,5,5,6,5,5,6,6,6,6,6,7,7,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,4,5,5,5,5,5,4,4,5,5,5,4,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,5,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,3,4,4,4,3,4,4,5,5,6,5,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,4,4,3,3,2,2,2,2,2,3,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,4,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,5,5,5,5,4,5,6,5,5,6,6,7,7,8,9,10,10,10,11,12,13,12,12,14,14,14,15,16,17,16,16,18,19,18,20,20,20,21,22,20,19,20,20,19,19,20,22,19,19,21,22,23,24,23,23,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,26,25,24,25,25,24,24,25,25,25,24,23,25,23,24,23,23,23,21,21,19,19,18,16,16,14,12,11,9,8,7,7,6,6,6,6,5,5,5,5,5,5,5,5,6,6,6,6,7,8,7,7,8,8,8,8,7,7,7,6,6,6,6,6,7,7,8,8,8,8,8,8,7,7,7,7,6,6,7,6,5,6,6,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,4,6,7,6,5,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,2,3,2,3,3,3,3,4,4,4,4,4,5,6,6,6,5,4,3,4,4,4,4,4,5,4,5,5,6,5,6,7,7,7,7,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,4,3,4,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,4,3,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,6,5,6,6,5,5,5,6,6,6,6,6,7,6,7,7,7,7,7,7,7,6,7,7,6,7,7,6,6,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,5,4,4,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,5,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,4,6,7,7,8,10,10,10,10,14,15,15,16,17,18,19,16,18,19,18,15,20,16,20,21,18,20,22,20,20,21,21,21,22,21,21,21,22,23,19,21,22,22,22,22,22,22,22,22,21,19,21,22],[27,28,27,26,28,27,27,28,26,26,26,24,27,24,26,24,26,27,24,26,26,24,25,26,25,26,26,26,26,26,25,26,27,27,26,27,27,26,27,26,27,26,26,25,25,25,23,21,23,22,20,20,21,19,18,18,18,16,17,17,15,13,11,9,8,7,6,6,6,5,5,5,4,4,5,4,5,5,5,4,4,5,5,3,4,4,4,5,5,4,5,5,5,6,6,5,5,6,6,6,7,7,6,6,7,7,7,7,7,7,8,7,7,6,7,7,7,7,7,7,7,6,6,6,6,6,5,6,5,5,5,5,4,5,5,5,5,4,5,5,5,4,6,5,4,5,6,5,5,6,6,5,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,4,3,4,4,3,4,4,5,5,4,5,4,5,5,4,5,5,5,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,4,4,5,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,5,4,4,5,5,5,6,6,6,6,5,5,5,6,6,5,6,6,6,7,7,8,9,9,10,10,11,12,13,12,12,14,14,14,14,16,17,16,17,19,21,21,21,22,22,21,22,22,20,23,21,20,21,20,23,20,22,22,24,24,26,24,24,25,25,25,25,25,26,25,25,26,25,26,26,26,26,25,26,26,26,26,26,26,25,26,26,26,26,25,25,24,25,25,24,23,23,20,21,20,18,18,16,14,13,11,10,9,8,7,7,6,6,6,6,6,5,5,6,5,6,6,6,7,7,7,7,8,8,8,8,9,9,8,9,7,7,7,6,7,7,8,8,8,9,9,8,9,9,9,8,8,8,7,7,7,7,6,6,6,6,5,6,5,4,4,4,4,4,4,3,4,4,4,4,4,4,4,5,5,5,6,7,7,6,5,4,4,3,4,3,3,3,3,2,2,2,2,2,1,1,1,1,0,1,1,2,2,1,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,6,6,7,5,4,3,3,3,4,4,4,4,4,5,5,6,5,6,6,7,6,6,6,5,5,5,5,4,5,5,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,5,4,5,5,6,6,5,5,6,6,6,6,6,6,6,7,6,7,7,6,7,6,7,7,5,6,7,6,6,6,6,5,5,4,5,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,4,3,3,4,4,3,4,3,4,4,3,4,5,4,4,4,5,4,5,5,5,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,5,5,5,6,6,5,5,6,6,5,6,5,5,5,6,5,5,6,5,5,5,5,5,5,6,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,4,6,7,8,9,10,11,12,10,14,15,16,17,16,19,17,18,17,20,19,18,21,18,20,20,19,22,23,21,23,23,22,23,23,22,23,22,22,22,20,21,23,22,22,23,23,23,23,25,22,20,23,25],[28,28,28,28,28,28,28,27,28,27,27,27,27,26,27,26,27,27,27,27,27,27,27,27,26,27,27,27,27,27,26,27,27,28,27,27,27,27,27,27,27,27,26,26,26,25,24,24,24,23,22,21,22,20,19,20,19,18,17,18,15,12,10,8,7,6,5,5,5,4,4,3,3,3,3,3,4,4,4,3,3,4,3,3,3,4,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,4,4,4,5,5,4,5,5,5,6,6,6,7,8,9,10,10,13,14,12,13,15,15,14,16,18,18,18,20,21,22,22,23,23,24,24,23,23,22,23,21,22,22,22,23,23,24,24,25,25,27,26,26,26,27,27,27,27,26,27,27,27,27,27,27,27,27,26,27,27,27,27,27,26,26,27,26,26,26,25,26,24,24,24,24,24,23,21,21,20,18,17,16,15,13,11,9,8,7,6,5,5,5,4,5,4,4,4,4,5,5,5,5,6,6,6,6,7,7,8,7,8,8,8,8,7,7,6,6,6,7,6,7,7,8,9,8,8,8,8,7,7,6,6,6,6,6,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,5,6,6,6,5,5,4,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,4,6,6,6,4,4,3,3,2,3,3,3,3,4,4,4,5,4,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,4,3,4,4,4,5,4,4,4,4,5,5,5,5,5,6,5,6,6,6,5,5,6,6,5,5,6,6,5,5,5,4,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,6,8,8,9,11,10,11,11,13,15,16,18,19,21,21,21,20,21,22,20,22,20,23,22,22,25,25,24,24,24,24,25,24,24,26,25,23,25,24,25,24,24,24,23,24,22,25,24,23,24,25,25],[28,28,27,27,28,26,28,27,25,26,26,24,26,23,26,23,26,25,24,26,25,24,27,26,25,26,26,26,27,26,25,27,27,28,27,27,27,27,27,27,27,27,26,26,26,25,24,22,23,22,20,20,21,20,18,18,18,16,16,16,14,12,10,8,7,6,5,5,5,5,4,4,3,3,3,4,4,4,4,4,4,4,4,3,3,4,3,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,7,6,6,5,6,6,6,6,6,6,6,5,5,5,6,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,5,5,6,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,4,4,4,5,5,4,5,5,5,6,6,6,7,8,8,9,10,12,12,11,12,13,14,14,15,16,17,17,17,20,20,19,21,22,22,22,22,22,20,22,20,20,21,21,22,21,21,23,24,25,26,25,25,27,26,26,25,26,26,26,26,26,26,26,27,27,26,26,27,26,26,26,26,25,26,26,26,26,26,25,26,24,25,24,24,23,22,21,21,19,19,17,16,15,12,11,9,8,6,6,5,5,5,5,4,5,4,4,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,8,7,7,6,6,6,6,6,7,7,8,8,7,7,7,8,7,6,6,6,6,6,6,5,5,5,5,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,6,6,5,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,4,6,6,6,4,4,2,3,2,3,3,3,3,3,4,4,5,4,5,5,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,2,3,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,3,4,3,4,4,4,5,4,4,5,4,5,5,5,5,5,6,5,6,6,5,6,6,6,6,5,5,6,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,3,3,4,4,3,3,4,4,4,4,4,5,5,5,4,5,5,4,4,4,4,4,5,4,4,5,4,4,4,4,4,5,5,5,5,4,5,5,5,5,4,4,4,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,2,2,3,5,6,7,8,8,11,10,10,10,13,15,15,15,17,19,18,18,18,20,20,17,23,17,23,21,20,25,23,21,24,24,23,24,25,23,22,24,24,24,21,23,23,24,23,24,24,23,23,24,21,21,24,24],[28,28,27,27,28,26,28,28,26,25,26,23,26,23,25,22,25,26,24,26,26,26,26,27,25,26,26,25,26,26,26,27,27,27,26,27,27,26,27,26,27,26,26,25,25,25,23,21,22,22,20,20,21,18,17,18,17,16,16,15,13,11,10,7,6,6,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,3,4,4,3,3,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,4,4,4,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,2,2,2,2,2,2,2,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,4,4,4,5,5,4,4,5,5,6,6,6,7,7,8,9,10,12,12,11,13,14,13,14,14,15,16,15,16,18,19,19,19,20,21,21,22,20,20,21,21,20,21,21,22,20,21,22,24,24,26,25,25,26,25,26,26,25,25,26,25,26,26,26,26,26,25,26,26,26,25,25,26,25,25,25,25,26,25,25,25,25,24,24,23,23,22,19,20,20,18,17,16,14,12,10,9,7,6,6,5,5,5,5,4,4,4,4,4,5,5,5,5,5,6,5,6,7,6,6,7,6,7,7,6,6,6,5,5,6,6,6,7,7,7,7,7,7,7,7,7,6,6,6,5,6,6,5,5,5,5,4,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,4,3,4,3,3,3,2,3,2,2,2,2,2,2,2,1,1,1,2,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,4,6,6,6,4,3,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,4,4,4,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,4,4,4,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,5,4,4,4,4,5,5,5,4,4,5,4,4,4,3,3,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,5,5,6,7,9,9,10,10,10,13,13,15,16,18,18,17,17,17,19,18,17,21,17,21,20,20,23,24,20,21,23,22,22,23,23,23,22,23,23,21,21,23,22,23,23,23,23,22,25,22,21,25,26],[28,28,28,28,28,28,28,27,27,26,26,26,26,25,26,25,25,27,26,25,26,26,25,26,26,26,26,26,27,26,25,26,26,27,26,26,26,26,27,26,27,26,26,26,25,25,24,23,23,22,22,22,21,20,19,19,18,17,17,16,14,11,9,6,5,5,4,3,4,3,3,3,2,2,2,2,3,3,3,3,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,4,4,3,4,4,4,4,4,5,6,7,8,9,10,13,12,11,13,14,15,14,16,17,17,18,19,20,21,22,21,23,24,23,24,23,21,23,22,21,22,22,23,22,23,23,26,24,27,25,26,25,26,26,26,26,26,26,26,26,26,26,26,26,27,26,27,26,27,26,26,26,26,26,26,25,26,26,25,24,23,23,24,23,22,20,19,19,18,16,15,14,12,10,8,6,5,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,7,6,6,6,6,6,6,5,5,5,5,6,6,6,7,7,6,6,6,6,6,5,6,5,5,5,5,4,4,4,4,4,3,3,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,5,6,6,5,3,2,2,2,2,2,3,3,3,3,3,4,3,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,2,1,2,1,2,2,1,1,2,2,2,2,2,2,3,2,3,3,2,2,3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,5,4,4,4,5,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,5,7,7,9,9,10,10,11,13,13,15,15,16,19,18,19,18,19,20,19,21,19,23,22,22,24,24,23,23,23,23,25,22,23,25,23,22,24,22,23,23,24,24,22,24,23,24,24,24,22,24,25],[28,28,28,28,28,28,28,27,28,27,26,26,26,25,26,25,26,27,26,27,26,27,27,26,26,27,26,26,27,26,25,27,27,27,27,27,27,26,27,26,27,26,26,26,25,25,24,23,24,23,23,21,22,20,19,20,19,18,17,16,14,12,9,7,5,5,4,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,3,2,2,3,2,2,2,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,3,4,4,4,5,4,5,6,6,7,9,9,11,12,11,13,14,15,14,15,16,17,18,18,21,22,21,22,23,23,24,24,23,22,24,22,22,22,22,24,23,23,24,25,25,28,25,26,26,26,26,27,27,27,27,27,27,27,27,27,27,26,26,27,27,27,27,26,26,26,26,25,26,26,25,26,24,24,24,25,23,23,21,21,20,19,17,15,15,12,10,8,7,6,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,6,5,5,6,7,6,7,7,7,7,8,6,7,6,5,6,5,6,7,7,8,7,7,7,7,7,6,6,6,6,5,5,5,5,4,5,4,4,4,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,6,6,6,4,3,2,2,2,2,2,3,2,3,3,4,4,3,4,4,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,1,1,1,2,1,1,1,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,2,3,3,3,3,3,4,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,4,5,5,4,4,5,5,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,4,3,3,4,4,3,4,4,3,3,4,3,3,4,4,3,3,3,4,4,4,4,4,4,3,4,4,4,4,4,4,4,3,3,3,4,4,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,3,4,5,6,7,9,9,10,10,10,13,14,16,16,17,20,20,20,18,21,20,20,23,20,24,23,23,25,24,23,25,24,24,25,24,25,26,25,23,26,23,24,24,23,24,24,24,24,25,26,24,23,25,24],[28,28,27,27,28,27,28,28,26,26,26,23,26,23,26,24,26,25,24,26,25,24,27,27,23,26,27,25,26,27,24,27,28,28,27,27,27,28,28,27,28,27,27,27,26,25,24,23,23,23,20,20,20,20,18,19,19,17,16,16,14,12,10,7,6,5,4,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,2,3,3,3,3,3,4,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,3,3,4,4,3,4,4,4,5,5,5,6,6,7,9,10,11,13,11,12,14,13,14,14,16,17,17,17,19,21,20,21,22,23,23,24,21,21,23,20,20,21,22,23,21,21,23,25,24,27,25,25,25,26,26,26,26,26,26,26,26,26,27,26,27,26,26,27,26,26,26,26,24,25,26,25,26,26,25,26,24,24,24,24,23,21,21,21,19,18,17,16,15,11,11,8,7,5,5,4,4,4,4,3,4,3,4,4,4,4,4,5,4,5,5,5,6,6,7,6,6,6,6,6,6,6,5,5,5,5,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,4,4,4,5,5,4,4,3,3,2,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,3,2,4,6,5,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,2,2,1,2,2,2,2,2,2,2,3,2,3,2,2,2,3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,4,4,4,4,5,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,3,3,4,4,3,3,4,4,3,3,4,3,3,4,4,3,4,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,7,7,9,9,9,10,10,12,13,15,15,15,18,19,19,16,18,18,20,22,19,23,21,21,25,24,22,23,25,22,24,24,24,23,23,23,24,20,22,23,24,24,23,24,24,23,25,24,22,23,25],[28,28,28,28,28,27,28,28,27,26,27,25,27,25,26,24,26,27,25,27,26,25,27,27,25,27,27,26,27,27,25,26,27,28,26,27,27,27,27,27,27,26,26,26,26,25,25,23,23,22,21,21,21,20,19,19,18,18,17,16,14,11,9,6,5,5,4,3,4,3,3,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,3,3,3,4,3,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,3,4,4,4,5,4,5,6,8,8,9,10,12,12,12,12,13,14,14,15,16,17,17,17,19,21,20,20,21,23,22,23,23,21,23,21,21,22,22,24,21,23,22,26,24,27,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,26,26,26,26,25,25,25,26,26,26,26,25,25,24,24,24,23,22,21,20,19,18,17,16,14,12,10,8,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,6,6,6,7,6,6,7,6,6,5,5,6,5,5,5,5,4,4,4,4,3,4,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,4,4,4,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,3,2,4,5,5,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,4,3,3,4,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,7,6,8,9,9,10,10,14,13,16,17,18,18,18,18,17,19,18,19,23,19,22,21,22,24,24,24,23,24,23,25,23,24,24,23,23,25,22,22,24,24,24,23,23,24,23,26,24,22,24,25],[28,28,28,28,28,28,27,27,27,26,27,26,26,25,25,25,25,26,25,26,26,26,26,26,26,26,26,25,27,26,24,26,26,26,26,26,26,26,26,26,26,26,26,26,25,24,24,22,23,22,21,21,21,20,18,19,18,16,17,16,13,10,8,6,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,3,3,4,3,3,3,4,3,4,4,4,5,6,7,8,9,12,12,11,12,14,13,13,15,16,17,16,19,19,20,21,21,22,23,23,24,23,22,23,21,22,22,23,24,22,24,23,26,24,27,26,26,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,26,26,26,26,25,25,26,25,26,25,25,25,24,23,23,24,21,20,19,19,19,17,15,14,13,11,9,8,6,5,4,4,3,4,4,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,7,6,6,5,5,5,5,6,6,6,6,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,3,3,3,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,4,4,4,5,5,4,4,3,3,2,3,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,4,5,5,5,4,3,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,3,3,3,3,3,3,4,3,4,4,3,4,3,4,4,3,3,4,4,4,3,3,3,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,5,6,6,8,9,10,10,10,14,15,16,18,18,20,20,19,18,20,20,20,23,21,23,23,22,25,25,24,24,25,25,25,25,24,25,24,24,25,24,25,25,24,25,24,24,24,24,26,25,24,25,25],[28,28,28,28,28,28,28,27,27,27,26,25,26,25,27,25,27,27,25,27,26,25,27,26,25,27,27,25,27,27,25,27,27,27,26,27,27,27,27,27,27,27,26,26,26,26,25,23,24,22,22,21,21,20,18,19,19,17,16,16,13,10,8,6,5,4,4,3,3,3,3,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,4,4,3,4,4,3,3,3,4,3,3,3,4,3,4,4,4,5,6,7,8,10,11,12,11,12,14,13,13,15,16,16,17,18,19,21,22,22,22,24,23,24,24,23,25,22,21,22,23,24,23,24,24,26,25,27,26,26,27,26,27,26,27,27,27,27,27,26,27,27,27,26,26,27,27,27,27,26,25,25,26,26,26,25,25,26,23,23,23,24,22,22,20,20,19,18,16,15,15,11,10,8,7,5,4,4,3,4,4,3,4,4,4,4,4,4,5,4,5,5,5,6,6,6,7,7,6,7,7,7,7,6,6,5,6,6,6,7,6,7,7,7,6,7,6,6,6,6,6,5,5,5,4,4,4,4,4,3,3,2,2,2,3,3,2,2,3,3,2,3,3,3,3,4,4,4,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,3,2,4,5,5,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,4,4,4,4,3,4,4,3,3,3,3,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,6,6,8,9,10,10,10,13,14,16,17,18,20,20,19,18,19,20,20,23,21,23,22,22,26,25,24,25,25,24,25,25,25,25,23,25,25,22,23,24,24,25,24,24,25,24,26,24,23,24,25],[28,27,27,26,28,27,28,28,26,26,25,22,26,23,25,23,25,25,23,26,24,23,25,25,23,25,26,23,25,25,23,26,27,27,25,27,26,26,26,26,26,26,25,26,25,25,23,21,22,21,20,19,19,19,16,18,18,15,15,15,12,10,8,6,5,5,4,3,4,3,3,3,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,3,3,4,4,3,3,4,4,5,4,5,6,6,7,8,9,10,10,10,11,12,12,12,13,14,15,15,15,17,20,18,19,21,21,20,23,19,20,22,21,20,20,21,22,20,19,22,23,23,26,23,24,24,24,25,25,25,25,24,25,25,25,26,26,26,26,26,26,26,25,25,25,24,25,25,24,25,24,23,24,23,23,23,22,21,20,18,20,18,17,15,14,14,11,9,7,6,5,4,4,4,4,4,3,4,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,3,4,5,5,5,3,2,2,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,2,1,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,3,3,3,3,4,3,4,4,3,4,3,4,4,3,3,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,4,3,3,4,4,3,4,3,3,3,4,3,3,4,3,3,3,3,3,3,4,4,3,4,3,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,4,5,6,6,7,8,8,9,9,12,12,14,15,16,17,18,17,15,17,17,18,20,17,21,19,21,24,22,22,23,24,21,23,23,22,23,21,23,22,21,20,22,23,22,22,22,23,22,24,23,19,22,25],[28,28,28,27,28,28,28,27,27,26,26,25,26,24,25,24,25,25,24,25,25,24,25,25,24,26,26,24,26,26,24,26,26,27,26,27,26,26,26,26,27,26,26,26,25,25,23,22,24,22,20,21,21,19,18,20,19,17,16,16,13,10,8,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,4,3,4,4,4,5,6,7,8,9,11,11,10,12,13,12,14,15,15,16,16,18,18,20,20,20,22,23,23,24,22,22,23,21,22,22,22,23,22,22,22,26,24,27,25,25,25,25,25,25,25,25,25,25,25,26,26,26,25,26,26,27,25,27,25,26,25,25,26,25,25,25,25,26,24,24,23,23,22,22,19,19,19,17,16,15,14,11,10,8,6,5,4,4,3,4,4,3,4,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,6,6,6,7,7,6,6,7,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,3,4,5,5,4,3,2,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,2,2,2,2,2,1,2,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,4,5,6,6,7,9,8,9,10,12,13,15,16,16,19,19,18,17,18,18,19,21,19,23,21,22,24,24,23,23,24,23,23,24,23,24,22,23,24,22,22,23,24,24,24,24,24,23,25,24,21,24,25],[28,28,28,28,28,28,28,27,27,27,26,26,26,24,26,24,26,26,25,26,26,25,26,26,25,27,26,24,27,26,24,26,26,26,26,26,26,26,26,26,26,26,26,26,25,25,24,23,23,23,22,21,21,20,18,20,18,17,17,16,13,11,8,6,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,4,4,4,4,5,6,7,7,9,12,12,11,11,14,13,13,15,16,15,16,18,19,20,20,22,22,24,23,24,24,23,24,22,22,23,23,24,23,24,24,26,25,27,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,26,27,27,26,27,27,26,25,26,26,25,26,25,25,25,24,23,23,23,22,21,20,20,19,18,16,14,14,11,10,8,7,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,7,7,7,7,7,8,7,7,6,6,6,6,7,7,7,8,7,6,7,7,7,6,6,6,6,5,6,5,4,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,5,5,6,6,6,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,3,5,5,6,4,3,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,3,3,3,3,3,3,4,4,4,4,3,4,3,4,4,3,3,4,4,4,4,3,3,2,2,2,2,2,2,2,1,1,2,2,1,1,2,1,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,4,4,4,4,4,3,4,4,4,4,4,4,4,3,4,3,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,2,3,4,5,6,6,8,9,10,10,11,14,15,17,19,19,21,21,20,19,20,21,21,24,22,24,23,23,26,25,24,25,26,25,25,25,25,25,24,25,25,23,24,25,24,25,25,24,25,24,26,24,23,25,24],[28,28,28,27,28,28,28,27,26,26,26,25,27,24,25,24,26,26,25,26,25,25,26,25,24,26,26,24,26,25,23,26,27,27,25,27,25,26,26,25,27,26,25,25,25,25,23,21,22,22,20,19,20,19,16,18,18,16,15,16,14,11,9,7,6,5,4,4,4,3,3,3,2,2,2,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,4,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,3,4,3,3,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,4,5,5,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,4,3,3,4,4,3,4,4,4,5,4,5,6,6,7,8,9,11,11,12,12,13,13,14,15,16,15,16,17,18,20,19,21,22,24,22,23,23,23,25,21,21,22,23,23,22,22,24,25,25,26,25,25,26,25,26,26,25,26,25,26,25,26,26,26,26,26,26,26,26,27,25,26,24,25,26,25,26,25,24,25,23,22,23,21,21,22,19,20,18,17,16,14,13,11,10,8,7,6,5,5,4,4,4,4,4,4,5,4,4,5,5,5,5,6,6,7,7,7,7,7,7,8,7,8,7,7,6,6,6,6,7,7,7,8,7,7,7,7,7,6,6,6,6,6,6,6,5,5,5,4,4,4,4,3,3,3,3,4,3,3,4,4,3,4,4,4,4,5,5,5,6,6,6,6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,3,5,4,6,5,3,2,2,1,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,2,2,2,3,2,3,2,2,3,2,2,3,3,2,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,6,7,6,8,10,10,9,11,12,13,15,17,18,20,20,19,16,18,19,20,22,19,23,21,21,25,24,23,24,25,23,24,25,24,23,24,25,24,21,21,24,23,24,24,23,25,23,26,24,21,23,25],[28,28,28,28,28,28,28,28,27,27,26,25,27,24,26,24,26,26,25,26,25,24,26,26,24,26,27,24,26,26,24,26,27,27,26,27,26,27,27,26,27,26,26,25,25,25,23,22,23,22,21,21,20,20,18,19,18,17,17,16,14,11,9,7,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,4,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,5,5,5,6,8,8,9,11,13,12,12,12,13,13,14,14,14,15,16,16,17,20,19,20,22,23,22,23,21,21,22,21,21,21,22,22,21,21,23,25,24,26,24,25,25,25,26,26,26,25,25,26,25,25,26,26,25,26,26,27,25,26,25,25,24,24,25,25,25,25,25,25,24,23,23,22,21,21,19,20,19,18,16,15,15,12,11,8,7,6,5,5,5,5,5,4,5,4,5,4,5,5,6,5,6,6,6,6,7,7,7,7,7,8,7,7,7,7,6,6,6,7,7,7,7,8,8,7,8,7,7,6,7,6,6,6,6,6,5,5,5,5,5,4,4,4,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,4,4,4,4,3,3,3,3,3,3,2,2,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,2,2,3,5,5,5,7,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,4,4,3,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,5,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,10,10,11,12,13,15,16,18,19,19,19,17,18,19,20,22,19,22,21,21,24,24,23,24,24,22,24,24,23,24,23,24,24,22,23,25,24,24,24,23,23,24,25,25,22,23,25],[28,28,28,28,28,28,28,28,28,27,27,26,27,24,26,25,26,26,25,26,25,25,26,26,24,26,27,25,27,26,24,27,27,28,26,27,27,27,27,27,27,27,26,26,26,25,23,23,24,23,23,22,22,21,20,20,19,18,18,17,15,12,10,7,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,4,3,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,7,7,6,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,5,4,4,4,5,4,4,4,5,4,4,5,5,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,4,4,4,5,5,5,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,4,5,5,4,5,5,5,5,5,6,7,9,9,10,11,14,14,13,14,15,15,14,17,16,16,18,19,19,20,21,22,23,25,24,25,25,22,24,22,22,24,24,24,23,24,24,26,25,27,26,26,26,27,27,27,27,27,27,27,27,26,27,27,27,27,27,28,27,27,27,27,26,26,26,26,26,26,26,26,24,23,24,24,23,22,20,19,20,18,17,17,15,13,12,10,8,7,6,6,6,6,5,5,5,5,6,6,6,6,7,7,7,7,7,8,8,9,8,9,9,10,9,9,9,9,8,8,8,8,8,9,9,10,10,9,9,9,9,8,8,8,7,7,8,7,6,6,6,6,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,6,6,7,7,7,7,7,7,6,5,5,5,4,4,4,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,2,2,3,5,5,6,5,3,2,2,2,2,2,3,2,3,3,3,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,4,4,4,4,5,4,4,4,5,5,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,5,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,4,4,4,5,4,4,4,4,4,4,6,6,8,8,9,11,12,12,12,14,16,17,18,18,21,20,21,20,20,21,21,23,21,23,23,24,25,25,25,24,25,24,25,25,25,26,24,24,26,25,24,26,26,25,26,24,24,24,26,25,23,25,26],[28,27,28,28,28,28,28,28,28,27,27,26,27,26,26,25,26,26,25,27,26,25,27,26,25,26,26,25,26,26,24,27,27,27,26,27,26,26,26,26,27,26,25,26,26,25,24,23,23,23,23,20,21,21,19,20,19,18,17,18,15,13,11,9,7,7,6,6,6,6,6,5,6,5,5,6,5,6,5,5,5,5,5,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,8,8,8,8,9,9,8,10,9,9,10,10,8,8,8,9,9,9,9,9,9,8,8,9,8,8,8,8,8,7,8,7,6,7,7,8,7,6,6,7,7,6,6,7,6,6,7,7,6,7,7,7,6,7,7,8,7,7,8,7,7,7,8,8,7,7,8,8,7,8,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,5,6,5,5,5,5,5,4,5,5,5,6,6,5,6,5,5,5,6,6,6,5,4,5,4,5,5,4,4,5,4,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,7,8,8,9,8,8,8,9,8,7,8,8,8,8,7,7,8,7,7,6,6,6,6,6,7,7,7,6,6,6,5,5,4,4,5,4,4,4,3,3,3,3,3,3,3,4,4,3,4,3,3,3,3,3,3,4,4,4,4,5,6,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,9,9,8,8,8,7,7,7,7,7,7,7,8,7,8,8,8,9,9,10,12,14,14,13,13,16,16,15,16,17,17,18,19,20,21,21,23,24,25,24,26,25,23,25,23,22,24,25,26,24,25,25,27,27,28,27,27,27,28,27,28,28,28,28,28,28,28,28,28,28,28,27,28,27,28,28,27,27,27,27,27,27,26,26,26,25,24,25,23,22,22,22,22,21,20,19,18,17,14,14,12,10,9,8,8,8,8,8,9,8,9,9,9,9,9,9,10,10,10,10,10,10,12,11,11,11,11,12,12,11,11,11,10,10,11,11,11,11,12,12,10,12,11,12,10,10,10,9,10,10,10,9,9,9,9,8,9,8,8,8,8,8,8,8,8,8,8,8,8,9,8,8,9,9,9,11,10,10,10,10,8,9,8,8,7,7,7,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,2,2,2,2,1,1,1,0,1,2,2,3,6,6,7,6,4,3,3,2,3,3,3,3,4,5,5,5,6,6,6,5,5,5,5,4,4,4,4,3,3,3,3,2,3,2,2,3,3,2,2,3,4,3,3,4,4,4,4,6,5,5,6,6,6,6,7,6,7,7,7,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,3,4,5,5,5,5,5,5,6,6,6,6,7,6,6,7,7,6,6,6,6,6,6,5,6,6,5,6,6,5,5,4,3,4,4,3,3,4,3,3,4,4,3,4,5,4,4,5,5,4,5,6,6,6,6,5,5,5,5,5,4,5,5,4,4,4,5,4,3,4,4,3,4,4,4,4,5,5,5,5,4,4,5,4,4,5,5,5,4,6,5,5,6,6,6,5,6,7,6,6,6,6,6,5,6,6,6,7,6,6,7,7,6,6,7,8,8,9,8,7,8,7,8,7,7,7,7,7,7,7,7,7,6,7,7,6,6,6,7,6,6,7,7,6,7,7,7,6,7,8,7,7,7,7,7,7,8,9,11,10,12,14,13,14,14,16,17,19,20,19,23,22,23,20,21,22,22,24,22,24,23,23,26,26,25,25,26,25,26,26,26,26,25,26,26,24,24,26,26,25,27,25,25,25,26,25,23,26,26],[28,28,28,28,28,29,28,27,28,27,27,26,27,25,26,25,26,27,24,26,26,24,26,26,24,26,27,24,26,26,24,27,27,27,25,28,26,27,27,27,28,27,26,26,26,26,24,24,26,23,22,22,24,21,19,22,21,18,19,19,17,15,13,11,10,9,9,8,8,7,8,8,8,8,7,7,7,8,7,8,7,7,8,6,7,7,6,6,6,7,8,8,7,8,9,9,9,10,10,10,10,10,11,11,11,11,12,12,12,12,11,11,10,10,11,11,11,11,11,11,11,10,11,11,11,10,10,11,10,10,11,10,9,10,10,11,10,9,9,10,9,9,9,9,9,9,10,9,8,10,9,9,9,8,9,10,9,10,9,10,9,9,10,10,9,9,10,10,9,9,10,10,9,9,10,9,9,10,10,9,9,8,9,9,8,8,9,8,7,8,8,8,7,8,8,8,9,8,8,9,8,8,8,9,8,8,7,7,7,6,8,8,6,7,8,7,7,8,8,7,7,8,7,7,7,8,8,8,8,8,8,8,9,9,10,10,9,10,11,11,9,10,10,10,9,9,9,9,8,9,9,8,7,8,9,9,9,9,9,7,7,7,7,7,7,6,5,6,6,4,6,6,5,4,5,6,6,6,6,6,5,5,4,5,5,5,4,5,6,6,7,7,7,7,8,8,7,7,7,8,8,8,8,8,9,9,9,9,10,10,9,10,11,10,10,11,11,12,11,10,10,10,10,9,9,9,10,9,9,9,10,10,10,10,11,10,11,12,14,15,16,15,15,17,17,17,17,17,18,19,20,22,22,21,24,25,26,25,26,25,24,26,25,23,24,25,25,24,24,26,27,26,28,27,27,28,27,27,28,28,28,28,28,28,28,28,29,28,28,28,29,28,28,28,28,27,27,28,27,28,27,27,28,25,25,26,26,24,24,22,23,22,21,19,20,18,16,15,13,12,11,10,11,11,10,11,9,11,10,11,11,11,12,12,12,13,13,13,13,13,14,14,14,15,15,15,15,14,14,12,13,13,14,13,14,14,17,16,15,15,15,16,14,14,13,13,13,13,14,12,12,12,12,11,10,11,10,10,9,10,11,9,10,10,10,10,10,11,11,11,11,11,12,13,13,12,12,12,11,10,10,10,9,9,8,8,8,8,7,7,8,7,6,7,7,6,6,6,5,6,5,5,4,4,3,3,3,2,2,2,1,1,0,1,2,3,5,6,7,7,5,4,4,4,4,6,5,5,6,7,8,9,7,7,9,8,7,9,8,6,6,6,5,5,5,5,5,4,5,5,3,4,5,3,3,5,5,3,4,5,5,5,5,6,6,6,7,7,7,7,8,8,9,9,8,7,8,7,7,7,7,6,6,5,6,6,5,5,4,6,5,4,4,5,5,3,4,5,4,4,5,5,4,3,5,5,4,5,6,5,6,7,8,7,7,7,9,8,8,9,9,10,9,9,10,9,9,10,8,9,9,8,8,8,8,8,8,8,7,6,5,7,5,4,5,6,4,4,6,5,4,5,6,6,5,8,7,7,8,7,8,8,9,8,7,8,9,7,7,9,8,7,6,6,8,7,7,5,6,6,6,7,5,6,7,7,7,8,6,7,7,7,6,7,7,7,7,8,8,9,9,8,9,8,10,10,10,9,8,9,8,8,10,8,9,9,10,8,9,10,9,9,9,10,10,10,10,10,10,9,10,10,10,10,10,9,11,11,9,9,9,9,9,8,8,9,9,8,9,9,9,7,9,9,9,8,9,9,9,9,10,9,9,9,11,12,12,12,14,15,15,16,16,17,19,19,19,20,24,22,23,22,23,22,23,25,24,24,26,24,26,26,26,26,27,26,27,27,27,27,25,27,27,25,26,27,27,26,26,26,26,27,27,25,25,26,27],[29,29,28,29,29,29,29,28,28,28,27,27,28,27,27,27,27,27,25,26,26,26,26,26,25,26,26,25,26,26,25,27,27,27,26,28,27,27,27,27,28,27,26,26,27,26,24,23,25,24,21,21,24,22,20,22,21,19,20,20,19,15,14,12,10,11,12,9,10,9,9,10,10,10,11,9,9,10,9,8,9,10,9,7,9,10,7,10,10,10,10,12,11,12,13,12,13,14,13,13,15,14,14,15,16,15,16,17,16,16,16,15,14,15,15,15,16,16,16,15,15,15,15,16,16,15,15,16,14,14,15,15,12,15,14,16,15,14,13,14,14,13,13,14,14,13,14,13,12,14,13,13,12,13,13,13,13,14,12,14,13,11,12,12,13,12,12,13,13,12,14,14,13,14,15,13,13,15,15,15,13,13,14,14,14,14,12,12,13,13,12,11,12,12,12,13,12,12,12,12,11,12,11,11,11,10,9,10,10,10,11,11,10,11,11,12,11,12,12,12,11,12,13,11,12,12,12,9,12,12,12,12,11,12,13,13,13,14,14,14,14,13,14,15,14,12,13,14,12,12,12,13,13,12,13,13,14,13,12,12,12,12,12,13,11,11,10,11,11,8,10,9,8,8,8,8,10,10,8,9,9,8,7,7,8,10,7,8,10,9,9,10,12,11,11,11,12,13,11,11,11,11,12,14,14,12,13,15,13,13,14,16,14,15,16,17,15,16,15,15,14,13,13,13,12,11,13,11,11,12,13,12,12,12,13,11,13,13,15,16,16,16,17,17,18,19,19,19,20,22,21,24,24,23,25,26,27,26,27,26,25,27,26,24,26,26,27,26,26,27,28,28,29,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,29,29,29,28,28,28,28,28,29,28,28,28,27,28,26,26,27,26,25,25,23,23,23,22,21,21,19,19,17,15,15,15,13,15,15,14,15,15,15,15,15,15,16,16,17,16,16,17,17,16,16,18,16,17,17,16,17,17,17,17,16,16,16,17,16,17,18,19,18,17,17,17,18,16,16,15,16,17,16,16,16,16,15,16,15,16,15,14,14,14,15,15,14,15,16,16,14,16,15,16,16,16,16,17,17,17,16,16,17,16,15,16,14,14,14,14,13,14,13,12,13,12,12,12,13,12,11,11,11,9,11,11,9,8,8,7,6,6,6,6,4,3,2,1,0,1,3,5,6,8,8,7,6,7,6,7,7,8,8,8,10,11,10,9,10,11,11,10,12,11,8,8,9,9,8,9,9,7,6,6,7,4,5,5,5,4,6,7,6,6,7,9,8,8,10,10,11,11,12,13,14,14,13,15,15,14,13,14,13,12,12,12,11,10,10,12,11,9,10,8,9,10,10,7,10,6,5,6,5,5,7,5,7,7,5,5,6,7,9,8,7,9,8,10,11,9,11,11,11,11,13,12,12,11,12,12,12,13,13,12,12,12,11,9,11,9,10,10,9,8,7,6,7,6,5,7,7,6,5,7,7,7,7,9,8,8,10,10,10,10,11,14,12,13,11,11,10,10,10,10,11,10,9,9,9,11,9,8,8,10,7,7,9,8,7,9,8,9,8,8,9,10,9,8,10,10,9,10,12,10,10,11,12,12,11,12,14,11,10,13,14,10,10,13,11,11,13,13,10,12,15,12,11,13,14,14,15,15,15,15,13,15,13,15,13,14,13,12,15,12,12,11,13,13,14,13,14,14,11,14,14,16,15,15,14,15,15,14,14,15,15,16,15,16,15,15,16,17,17,18,19,19,21,20,20,22,22,23,22,25,24,25,24,24,24,25,27,25,26,27,25,27,26,28,27,27,26,28,28,27,28,27,28,27,26,27,28,28,26,28,26,27,27,28,27,26,28,28],[29,29,28,29,28,29,29,28,28,28,27,27,28,26,27,26,27,27,26,27,26,24,26,26,24,26,26,24,25,26,24,27,27,27,26,27,26,26,26,26,27,26,26,26,26,26,24,23,25,23,24,22,22,23,21,22,21,20,21,21,19,16,15,14,12,12,12,12,11,13,12,12,13,12,11,12,13,12,13,11,12,14,13,11,11,12,10,11,11,12,14,14,13,16,15,15,16,16,16,15,16,17,16,16,17,16,17,17,17,16,17,17,17,16,17,18,17,17,17,17,17,16,17,17,16,15,16,17,15,16,17,15,16,17,16,17,15,16,15,15,15,16,16,16,16,16,16,15,16,15,15,15,16,15,15,16,16,15,15,16,15,16,15,16,16,16,15,16,17,15,15,16,16,15,16,15,14,16,16,16,15,16,16,16,17,16,14,15,16,16,13,13,14,15,15,13,13,13,11,14,13,9,10,13,10,9,10,11,10,10,13,10,10,13,14,12,13,14,15,12,13,16,15,13,15,15,16,14,15,15,16,15,15,14,16,15,15,17,16,17,15,15,16,16,16,15,16,16,15,16,16,15,16,15,15,14,16,15,15,16,14,14,13,15,14,11,10,11,10,10,12,9,9,10,8,9,9,9,11,9,9,9,10,10,11,11,11,11,11,11,11,12,15,14,13,14,14,14,13,13,14,14,13,14,14,14,14,16,14,15,15,15,15,16,15,16,15,17,16,15,15,15,14,15,14,13,14,13,15,14,14,12,12,12,13,14,14,14,14,17,16,17,18,19,18,18,18,20,21,20,22,23,23,24,26,25,27,24,26,26,24,27,25,24,25,26,26,26,26,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,28,28,28,28,28,27,28,28,28,28,28,27,28,26,26,27,26,26,27,24,25,25,23,23,21,21,20,18,17,17,16,13,14,15,16,15,14,16,17,16,17,16,17,17,16,16,17,17,15,17,18,17,16,17,17,17,18,16,17,17,17,16,16,17,17,18,20,19,18,18,18,17,16,16,15,16,17,16,16,16,16,17,15,16,15,16,14,15,14,14,17,15,17,16,16,16,16,16,16,16,17,16,16,17,16,15,17,18,16,17,16,17,17,15,15,14,15,15,14,15,15,16,14,15,16,11,13,10,10,13,15,10,10,11,8,8,9,7,6,7,6,4,3,1,0,1,4,6,9,7,8,10,8,7,9,10,9,9,10,11,11,12,10,10,11,11,11,12,10,9,10,9,9,8,8,8,9,7,9,9,8,7,9,8,6,9,9,8,9,10,12,10,11,11,12,11,13,14,14,15,14,14,15,15,15,14,14,14,14,12,12,13,10,12,14,10,9,9,9,10,9,9,8,9,6,6,6,7,6,6,6,7,6,6,7,7,6,9,8,10,11,12,13,13,12,14,15,14,15,16,16,14,15,16,15,15,15,14,13,14,14,11,11,13,11,12,12,11,10,8,7,10,8,7,9,9,7,7,9,10,9,9,10,10,10,11,13,11,11,13,13,14,14,13,14,13,13,11,9,13,12,10,11,10,11,9,7,9,10,7,7,11,7,7,11,10,11,11,7,10,12,10,8,11,12,9,12,13,13,13,12,13,13,11,12,13,11,12,12,13,12,10,12,11,11,13,12,11,13,13,12,13,14,15,13,15,14,15,14,14,15,13,14,13,14,14,14,15,14,15,14,15,14,13,13,15,15,15,13,14,15,14,16,15,16,16,16,16,17,17,15,15,16,15,16,16,17,17,18,19,19,20,20,22,23,22,23,23,26,26,26,25,25,26,25,27,25,26,27,25,27,26,27,28,28,27,28,28,28,28,28,28,28,26,27,28,28,28,28,28,27,28,29,28,27,28,28],[30,29,29,29,29,29,29,28,28,28,28,26,28,26,27,27,27,27,25,27,25,24,26,25,23,25,26,24,25,25,24,26,27,27,25,27,26,27,27,26,27,26,26,26,26,26,24,23,25,24,21,22,24,22,19,22,22,20,21,23,21,18,18,18,15,17,17,16,17,16,17,16,17,19,18,17,19,19,18,16,17,19,17,15,16,18,13,17,14,17,18,18,18,20,18,18,19,21,20,19,21,20,20,21,22,21,22,23,22,21,22,22,22,21,22,22,21,22,21,22,22,22,23,23,22,22,23,22,21,21,22,21,20,21,21,21,20,19,19,20,21,19,19,20,20,20,20,20,19,20,20,21,20,20,20,21,20,20,20,22,22,19,20,22,20,19,21,21,20,20,21,21,20,21,21,20,20,20,21,22,21,20,19,20,20,20,19,19,19,19,18,16,18,18,18,17,16,18,15,16,15,14,13,15,14,14,14,12,13,15,16,15,15,17,18,16,17,19,19,17,17,19,20,17,19,20,19,17,19,19,18,19,18,19,20,22,21,20,20,21,22,21,21,22,21,21,20,21,20,20,20,20,19,19,18,19,19,19,18,18,18,20,18,18,18,16,15,15,15,12,14,14,12,11,11,12,13,13,12,12,12,14,13,13,15,15,12,15,16,15,14,17,20,19,18,19,18,19,18,19,17,18,19,18,18,19,19,18,20,19,19,21,20,20,21,20,21,21,20,19,20,19,18,17,18,18,17,16,17,17,17,18,17,17,17,17,18,18,17,19,19,20,20,20,20,21,21,21,23,23,23,25,26,25,27,28,28,27,28,27,26,27,28,26,27,27,28,27,27,27,27,29,29,28,28,28,28,28,28,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,28,29,29,29,29,28,28,29,28,28,28,27,26,26,24,26,25,24,24,23,23,21,20,20,19,19,18,19,19,20,19,19,20,19,21,19,20,22,22,19,22,23,22,20,21,23,22,21,23,23,21,23,22,23,21,22,22,24,23,24,23,25,24,23,24,23,23,23,22,20,20,23,21,21,21,21,20,21,21,21,22,17,20,17,19,22,19,20,20,21,19,20,21,22,20,21,21,22,22,21,21,21,22,22,20,20,19,20,19,20,18,19,19,18,17,17,17,16,17,17,16,17,16,15,14,15,12,12,11,9,8,9,8,7,7,7,5,5,2,1,0,1,6,7,7,7,8,9,9,11,12,12,12,12,16,16,16,15,14,16,17,14,18,16,13,14,16,13,12,15,15,12,11,14,11,9,9,13,9,9,11,13,10,11,13,15,12,14,16,16,15,16,17,18,17,18,18,18,18,19,18,18,17,18,18,16,17,17,14,16,17,12,13,11,11,11,10,9,9,8,7,7,8,8,9,8,11,11,9,10,12,12,15,14,16,15,15,18,18,17,20,19,19,19,19,19,19,18,18,19,18,19,19,17,18,19,17,15,17,16,16,16,15,14,14,12,14,11,9,13,13,9,8,12,13,8,11,14,12,11,15,15,15,15,16,16,17,17,17,17,17,18,16,14,16,16,12,12,11,15,12,10,11,15,10,9,15,13,12,15,14,16,16,13,14,16,14,13,15,16,14,14,17,16,17,17,16,17,15,16,20,17,16,18,18,15,14,19,17,15,18,18,17,18,18,16,17,17,17,17,18,20,19,18,19,18,18,18,16,18,17,18,20,18,19,16,19,18,18,17,19,18,18,19,19,18,19,18,17,18,19,18,18,19,18,20,20,21,18,20,20,19,21,22,22,23,24,24,24,25,25,26,25,28,27,28,27,27,27,27,28,27,28,29,28,29,28,29,29,29,28,29,29,29,30,29,29,29,29,29,29,29,29,29,29,28,29,29,29,28,29,29],[29,29,29,29,29,29,29,28,28,27,27,26,27,25,26,26,26,26,25,26,25,24,26,25,25,26,26,25,26,26,26,27,27,28,27,28,27,27,27,27,28,27,26,27,28,27,26,25,26,25,24,24,25,24,22,24,25,23,24,24,23,21,21,19,19,19,19,18,19,19,20,20,20,21,19,20,21,19,20,19,21,20,20,17,18,19,15,18,16,18,20,19,20,21,24,21,22,24,24,23,25,24,24,25,25,24,25,24,24,23,24,24,25,23,23,24,24,25,25,25,25,23,25,25,24,24,25,25,23,22,24,24,21,23,23,22,24,22,21,24,23,22,24,24,23,22,24,24,22,23,24,23,22,23,23,23,24,23,23,23,24,21,23,24,22,21,24,23,21,23,24,24,22,23,24,22,22,24,24,25,22,22,23,24,22,22,22,22,20,21,23,20,19,20,20,19,20,20,17,18,18,16,16,17,17,15,16,15,16,17,18,17,16,18,20,18,18,21,21,19,20,23,22,20,21,23,22,21,22,23,21,22,22,23,23,24,24,25,24,25,22,24,25,25,23,24,24,23,22,24,24,22,23,23,21,22,23,22,21,20,21,21,21,21,21,18,18,18,17,12,14,15,15,13,13,13,15,16,13,15,15,14,15,14,16,16,13,16,18,17,17,21,21,22,20,22,22,21,22,22,20,22,23,21,22,23,24,24,25,24,25,25,24,25,24,24,24,24,24,23,24,23,24,21,19,22,23,19,21,22,21,21,18,20,19,19,20,19,18,19,20,21,21,21,22,22,22,21,23,24,25,25,26,26,27,28,28,26,28,28,26,27,27,27,27,27,27,27,27,28,29,28,28,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,29,29,30,30,29,29,29,29,29,29,29,29,28,29,29,28,29,28,28,28,27,27,27,26,26,25,25,24,22,23,22,23,22,22,23,24,23,23,23,25,24,24,24,24,24,23,24,24,24,22,24,24,23,23,25,24,23,24,23,24,24,24,24,24,25,25,24,26,25,24,25,25,24,25,24,24,24,25,25,24,24,24,23,24,24,24,24,23,23,21,23,24,23,24,24,25,24,24,23,24,24,23,23,22,23,22,23,23,25,24,24,24,23,24,23,23,21,23,23,20,19,22,21,19,19,19,19,19,17,16,16,18,15,14,14,13,10,11,10,9,8,10,8,6,7,4,1,0,2,4,5,7,11,12,11,12,13,17,14,15,18,19,19,16,16,19,18,17,19,18,15,16,18,15,12,15,16,13,11,15,13,10,13,14,13,11,14,14,13,13,16,17,17,17,19,19,19,19,21,20,21,22,22,23,23,21,22,20,20,22,21,20,19,19,18,17,18,14,14,16,17,14,11,14,13,10,9,12,10,9,11,11,13,11,11,13,14,13,17,14,17,17,18,20,19,20,21,22,21,22,22,23,22,23,21,21,22,20,19,19,20,20,17,17,20,19,18,18,18,15,16,14,17,14,11,15,16,11,13,16,16,12,15,19,19,18,18,21,19,18,19,19,21,20,21,20,19,21,19,19,19,17,17,15,17,18,14,13,16,17,13,15,16,15,15,16,17,18,18,17,16,18,18,17,17,19,18,17,20,20,19,19,19,19,17,19,20,17,18,19,19,16,17,21,18,18,21,20,19,21,22,20,21,21,22,21,23,23,22,23,22,21,21,22,20,20,21,20,21,20,21,18,20,21,21,20,22,22,21,21,22,21,21,21,23,22,23,23,24,23,22,24,24,24,23,23,22,22,23,24,23,23,25,25,25,26,26,27,25,28,27,28,28,28,28,27,29,28,28,29,28,29,29,30,29,30,29,30,30,29,30,29,30,30,29,29,30,30,29,29,29,29,29,30,30,29,29,29],[29,29,29,29,29,28,29,28,27,27,27,26,27,24,26,26,26,26,24,26,25,24,25,25,24,25,26,25,26,26,26,27,28,27,27,28,27,28,28,28,28,27,27,27,28,28,26,25,27,26,24,25,26,25,23,26,26,24,25,26,25,22,23,22,21,22,22,20,21,21,21,21,21,24,22,22,21,22,22,20,22,22,20,19,20,22,16,20,17,21,21,21,23,23,23,22,22,25,25,24,25,25,25,26,26,25,26,26,26,26,26,27,27,26,27,27,25,26,26,27,27,26,27,27,26,26,27,26,25,25,26,26,24,25,25,25,26,23,24,25,26,22,24,25,24,23,25,24,22,24,24,24,24,24,25,24,25,25,24,26,26,23,24,25,24,24,25,26,24,25,25,25,25,25,25,24,24,26,26,27,25,24,25,25,24,24,24,23,23,23,24,21,22,22,22,22,22,21,19,19,20,15,16,17,18,15,16,17,17,18,20,18,17,23,22,21,21,22,22,21,21,23,23,21,23,24,24,21,23,24,23,24,23,25,24,26,25,25,25,26,27,26,26,26,26,25,26,25,25,25,25,24,24,24,23,24,24,24,23,24,23,24,23,23,23,20,20,21,21,15,17,16,15,13,12,13,14,16,15,16,15,15,16,15,18,19,17,19,20,20,20,22,23,23,22,23,23,24,24,24,23,23,24,23,23,24,24,24,25,25,25,27,26,26,26,26,27,26,25,25,25,25,24,22,23,23,24,21,23,24,22,24,21,22,22,19,22,23,19,22,22,23,23,24,24,24,24,24,26,26,26,27,28,28,28,29,29,28,29,28,28,28,29,28,28,29,29,28,28,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,29,30,29,29,29,29,28,28,27,28,28,27,27,27,26,26,25,25,24,25,25,25,26,26,25,25,26,24,26,26,25,27,27,25,27,27,27,26,26,27,26,25,26,27,26,27,27,27,25,27,27,27,27,27,27,28,28,28,28,28,27,27,27,26,25,27,26,27,26,26,26,25,25,25,27,22,25,23,24,26,25,24,26,26,24,25,26,26,25,26,26,25,26,26,26,26,26,26,26,26,25,26,24,25,23,24,24,22,22,23,22,21,22,22,21,22,19,18,19,19,15,13,16,15,11,11,12,10,8,10,9,8,8,6,3,1,0,2,3,6,8,11,10,12,15,16,16,16,19,20,20,17,18,20,20,19,20,20,17,18,19,15,13,16,18,13,11,14,16,11,13,16,13,13,17,19,15,18,20,20,20,21,21,22,22,22,23,23,23,23,24,24,24,24,24,23,22,24,23,23,22,22,20,21,20,15,16,18,18,16,14,16,16,14,12,16,14,14,15,16,17,14,12,17,17,14,18,14,19,20,18,21,22,21,23,22,22,22,23,23,23,23,22,22,22,22,23,21,21,21,20,18,20,19,19,20,19,19,19,19,21,18,14,19,19,16,18,20,19,17,20,22,21,20,21,22,21,22,22,24,23,24,23,23,23,24,21,22,23,22,18,21,19,21,20,16,20,21,19,18,20,18,19,20,22,20,21,19,21,21,22,21,22,22,21,21,23,23,23,22,22,22,20,22,25,22,22,23,24,21,20,26,23,21,24,24,22,22,25,23,22,22,25,24,25,25,25,24,25,25,25,25,22,24,23,23,24,23,24,22,26,24,24,24,24,23,23,24,24,24,24,23,23,24,24,23,24,24,23,25,24,25,24,25,23,23,25,25,26,25,27,27,27,28,27,28,28,29,29,29,28,29,28,29,29,29,29,30,28,29,29,30,29,30,29,30,30,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30],[29,29,29,29,29,28,28,28,27,27,27,26,27,26,26,26,27,28,25,27,27,25,27,27,25,26,27,26,26,27,27,28,28,29,28,29,28,28,28,28,29,28,28,28,28,28,27,25,27,26,24,26,26,26,24,26,26,24,25,27,26,24,24,23,23,23,23,23,22,24,22,25,22,24,22,23,22,22,22,22,22,23,21,20,20,21,17,19,17,20,22,22,22,23,23,23,24,24,24,23,26,25,25,26,27,25,25,26,26,24,25,26,26,26,26,26,26,27,27,26,27,26,26,26,26,25,27,26,25,24,25,25,23,23,24,23,23,21,22,23,24,22,23,24,22,23,24,23,21,25,24,23,23,25,24,24,25,24,25,25,26,23,25,26,25,24,25,25,23,25,26,26,23,26,26,24,24,26,25,25,23,22,22,23,22,22,21,21,21,20,22,20,19,20,21,20,20,18,16,19,18,15,14,17,16,15,15,15,16,17,18,16,15,19,20,19,21,21,21,19,20,22,23,20,23,23,22,21,23,24,23,24,24,24,25,26,26,26,26,26,26,26,26,26,25,25,25,25,23,24,23,23,22,23,21,23,24,22,21,20,20,21,20,20,20,20,19,18,18,16,15,15,13,11,13,11,14,15,12,16,15,13,16,17,17,15,16,20,20,19,20,21,21,22,22,22,22,22,23,23,23,23,24,22,24,24,25,25,26,25,25,27,26,26,26,27,26,27,26,25,26,25,24,23,23,25,26,22,23,24,25,25,22,23,23,23,24,24,22,23,23,25,26,25,26,27,26,26,27,27,26,27,29,28,28,29,29,28,29,29,29,29,28,28,29,29,29,29,28,29,30,29,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,28,29,28,29,28,28,28,27,27,26,25,26,24,24,25,25,26,26,26,24,26,24,26,25,26,26,27,25,27,26,26,25,25,26,25,25,26,25,24,25,25,26,25,24,25,26,26,26,26,27,26,25,27,26,25,26,25,24,26,27,26,26,26,26,25,26,26,26,27,23,25,22,26,26,24,25,26,26,24,26,26,26,25,25,25,24,25,24,24,24,24,25,24,25,25,24,24,24,21,23,22,21,22,22,20,20,21,19,17,20,17,14,16,18,15,16,17,14,11,12,14,12,9,12,11,11,12,8,7,4,2,0,2,3,6,9,11,12,13,16,16,15,18,18,18,18,17,18,20,19,20,19,16,18,19,15,15,16,17,15,15,18,16,14,16,17,17,18,19,16,18,20,19,19,19,20,21,21,20,21,22,22,23,23,22,23,23,24,23,23,22,22,22,21,19,18,18,20,20,16,16,19,19,18,16,18,20,13,16,21,17,16,18,18,19,17,19,18,18,19,18,17,18,21,20,20,22,22,24,23,23,23,24,23,24,23,23,23,21,22,22,20,21,20,20,20,20,21,21,21,21,20,21,18,22,18,18,20,21,18,18,21,19,18,20,20,20,20,20,22,20,21,21,23,23,24,20,21,23,24,20,21,23,22,21,21,19,21,20,21,20,22,18,19,22,21,20,22,22,22,22,22,24,22,22,21,23,22,21,23,23,23,23,24,24,24,22,24,25,23,24,24,24,22,23,26,24,24,25,25,24,24,27,25,23,23,26,24,26,26,25,25,26,26,25,26,24,24,25,25,25,23,24,20,22,24,24,23,24,25,23,22,24,23,22,24,23,22,22,23,24,22,23,24,24,24,22,23,23,23,23,24,24,25,26,26,25,25,26,27,26,28,27,28,27,28,27,27,29,28,27,29,27,28,28,30,29,29,28,30,29,29,30,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,30,29],[29,29,29,29,29,29,29,29,28,27,28,27,28,26,27,26,27,27,26,28,27,26,27,27,26,26,27,27,27,28,26,28,28,29,28,29,28,29,29,28,29,29,28,28,29,29,27,26,28,27,25,26,27,26,24,27,26,25,26,27,26,23,24,22,24,23,24,24,24,25,23,24,24,23,21,24,24,22,23,23,21,22,22,20,17,20,19,20,19,18,21,20,20,22,23,22,22,24,24,22,24,24,24,22,24,24,23,24,24,22,23,24,24,24,25,25,24,25,25,25,25,24,25,25,24,22,25,25,23,22,24,23,21,21,22,21,21,18,21,23,22,20,22,22,20,23,24,23,22,23,24,22,24,23,23,24,25,24,23,25,25,23,25,26,23,23,26,25,22,24,25,24,22,24,25,22,24,25,24,24,22,22,22,22,21,20,20,21,19,19,20,18,14,17,18,17,18,13,13,14,14,12,11,15,14,13,15,13,14,16,16,14,15,18,18,15,16,19,18,16,20,21,20,20,22,23,22,23,24,23,23,24,23,23,24,25,23,25,24,25,23,24,25,23,24,25,25,23,23,24,23,22,22,23,20,21,21,19,21,19,20,19,18,18,18,16,17,15,16,13,14,14,12,10,11,8,12,11,9,12,12,14,14,16,17,17,16,20,16,17,17,21,20,20,23,23,22,23,23,23,25,24,24,24,25,25,24,26,25,25,24,26,26,25,26,25,26,25,25,25,25,25,24,22,22,24,25,24,23,24,24,25,24,23,23,24,23,24,23,23,24,24,24,25,25,25,26,25,26,27,27,27,28,28,28,29,30,29,30,29,28,29,28,27,28,29,28,29,28,28,30,29,30,30,30,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,29,30,29,28,29,28,28,28,27,27,27,25,25,24,24,25,25,24,23,25,26,24,25,25,26,25,25,25,25,25,23,26,25,24,24,24,26,25,24,25,24,24,24,24,24,23,24,24,25,24,25,25,26,26,26,25,26,23,25,24,24,24,25,25,25,24,25,25,26,25,25,26,24,24,23,25,26,25,25,25,25,23,24,24,24,23,24,24,22,23,23,22,23,24,24,23,23,23,23,23,22,22,23,23,20,21,23,20,19,22,18,16,18,15,15,14,17,14,13,13,14,11,13,14,12,9,14,13,12,12,10,8,7,5,2,0,1,4,7,9,13,12,12,14,14,18,17,18,18,17,19,20,20,21,18,15,18,19,19,17,20,20,16,16,22,14,14,19,19,15,15,21,20,16,20,17,19,21,20,20,20,21,23,23,21,24,23,22,24,24,23,23,23,23,21,20,21,21,17,18,18,17,16,15,17,20,15,15,19,21,15,16,21,16,17,18,19,19,19,21,18,20,21,21,21,19,21,22,23,21,22,23,22,24,24,23,24,24,24,24,22,23,22,22,21,22,22,20,21,22,21,21,22,22,22,22,20,22,23,21,20,20,20,22,20,18,22,20,21,21,22,21,20,21,21,23,24,23,24,20,21,23,23,19,21,22,21,19,20,19,21,18,18,20,22,20,18,22,22,22,23,23,24,22,21,24,24,22,22,25,24,21,23,25,23,24,24,24,24,22,23,25,22,24,24,23,22,22,26,24,24,24,25,24,24,25,25,25,25,25,24,25,24,24,25,25,26,24,24,23,23,23,23,23,23,23,19,22,23,23,23,23,23,22,22,23,23,21,22,23,22,21,22,24,22,21,24,22,23,22,22,21,21,22,23,22,22,24,26,24,26,26,27,26,28,27,28,27,28,27,27,29,27,28,29,27,28,28,30,29,29,28,30,29,29,30,30,29,29,28,29,30,30,28,29,29,29,30,29,29,28,29,29],[29,29,29,29,29,28,29,29,27,27,27,25,27,26,27,26,27,28,26,28,27,26,27,27,27,26,27,26,27,28,26,28,28,29,28,28,28,28,28,28,29,28,28,28,28,27,26,24,27,25,24,24,25,24,23,25,24,22,23,23,22,19,19,18,18,19,18,17,16,18,16,17,17,17,16,17,16,17,16,15,14,16,14,14,13,12,12,14,14,13,14,14,12,16,14,13,14,17,16,14,17,16,16,15,18,17,18,19,18,17,18,19,18,19,18,18,18,20,20,20,20,17,19,20,17,16,18,18,15,16,16,15,13,16,15,17,15,13,14,15,13,13,14,15,13,13,16,16,14,15,17,15,15,17,16,17,16,17,18,19,18,17,18,19,17,17,18,19,17,18,18,18,16,18,17,16,16,18,17,17,16,15,15,14,14,14,14,13,12,12,13,13,10,12,13,13,14,11,10,12,11,8,11,12,11,10,10,8,10,10,11,9,8,12,12,10,10,12,12,11,12,16,14,13,15,17,15,15,16,17,15,17,17,17,18,19,18,19,20,19,19,19,20,18,18,18,18,18,17,18,16,16,16,16,15,16,15,14,15,13,14,13,12,12,12,10,11,11,9,9,10,9,6,7,8,7,9,8,7,8,8,8,7,9,11,9,10,12,13,11,13,15,13,15,15,16,15,17,17,18,18,18,18,18,19,18,19,19,20,20,20,22,19,20,21,21,21,22,20,21,20,20,19,18,18,17,21,18,17,18,19,21,16,18,19,19,21,20,18,20,20,21,21,23,22,23,24,24,24,24,25,25,27,26,27,27,27,27,28,26,27,27,25,26,27,27,28,27,26,28,29,29,30,28,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,28,29,29,29,29,29,28,29,29,28,29,29,28,29,29,29,29,28,27,28,26,27,26,25,24,23,23,22,21,21,19,18,20,20,21,20,21,19,22,22,22,23,22,21,23,21,21,21,22,20,19,21,20,19,20,19,20,21,22,20,21,21,19,21,20,20,20,22,22,20,23,21,21,21,20,17,20,22,20,20,21,20,19,20,20,20,22,18,20,18,21,22,19,20,21,21,20,21,20,20,21,20,19,20,19,18,18,19,20,20,20,20,19,18,18,16,16,17,16,15,16,17,13,12,15,13,13,14,13,12,10,11,11,9,9,11,8,7,10,9,6,8,10,11,9,8,7,7,5,3,1,0,1,4,6,7,6,7,10,9,13,12,14,13,13,13,14,14,14,13,14,14,13,12,12,13,12,12,12,11,10,9,11,11,10,12,11,11,10,13,12,12,13,14,15,13,15,16,15,16,17,17,16,19,19,19,16,16,16,14,15,13,13,13,12,14,14,12,12,12,15,13,11,12,13,10,11,12,11,12,13,15,13,13,12,14,13,14,14,15,13,15,15,15,16,15,17,16,16,16,16,16,17,17,17,18,16,17,16,14,17,15,15,16,15,16,16,15,16,15,16,15,18,14,14,16,16,14,16,16,14,12,15,15,13,14,15,15,14,15,15,18,16,19,14,16,17,15,13,14,15,14,13,13,14,15,13,13,15,15,14,14,15,14,14,15,15,16,16,16,16,17,15,16,17,16,16,17,18,17,17,18,19,19,16,20,21,19,19,21,18,16,16,21,18,17,19,20,18,19,22,19,18,19,22,19,21,20,21,20,22,22,19,21,20,18,19,19,21,17,19,16,17,18,17,17,19,19,16,17,19,18,16,19,19,17,15,20,19,16,18,20,18,17,17,18,17,18,19,20,22,22,22,21,22,23,22,25,25,26,26,25,26,26,26,26,29,26,26,28,26,29,28,28,27,29,28,29,29,29,29,28,28,29,27,27,28,28,28,29,28,28,29,29,28,28,29,30],[28,29,28,28,29,28,29,28,27,27,27,26,27,25,26,25,27,27,25,27,26,24,26,26,25,26,27,25,27,26,24,27,27,28,27,27,27,27,28,27,28,27,27,26,27,27,25,24,25,24,22,23,24,22,21,23,22,20,20,20,19,17,16,14,13,12,12,11,10,11,9,10,10,9,8,10,8,8,7,8,9,7,7,6,5,5,5,6,5,5,7,6,7,7,7,7,8,8,8,8,8,8,9,9,9,10,10,10,10,11,11,11,9,9,10,10,10,11,11,11,11,9,10,10,9,10,10,9,9,10,9,8,7,8,8,9,8,7,8,8,8,7,7,8,8,7,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,10,10,8,9,10,8,9,9,9,8,9,10,9,8,9,10,9,9,8,8,9,8,8,8,8,8,7,6,7,6,6,6,6,6,6,6,5,6,6,6,5,6,5,5,5,4,4,4,5,4,5,5,6,5,5,7,7,6,7,8,8,7,9,9,9,8,8,9,8,9,9,10,11,11,10,10,11,10,10,10,11,11,9,10,10,10,9,10,9,8,9,9,10,9,8,8,8,7,7,8,7,7,8,6,6,7,7,5,6,7,3,4,4,3,6,4,3,4,3,3,4,4,4,5,5,6,6,6,6,7,7,7,9,9,8,8,9,9,10,10,10,10,10,11,11,11,11,12,12,12,12,13,13,12,13,11,11,12,12,12,11,13,11,11,12,12,11,12,12,12,13,12,13,13,15,15,16,17,18,18,18,20,19,19,20,21,22,22,22,23,25,25,25,25,27,25,27,24,25,25,23,24,25,24,24,25,25,25,27,26,28,26,28,27,27,28,28,27,28,28,27,27,28,27,28,27,28,28,28,28,28,27,28,26,27,28,27,28,28,26,28,26,26,27,26,26,25,24,25,23,24,22,22,20,18,17,15,14,12,13,13,12,12,12,11,12,13,14,14,14,12,14,14,13,13,13,13,13,14,14,14,15,15,15,16,14,14,14,15,13,14,12,15,14,17,16,15,15,16,14,14,12,13,14,13,14,13,13,12,12,13,12,12,13,12,12,12,12,13,11,12,13,14,12,13,13,12,12,13,12,13,13,13,13,13,13,12,12,11,12,10,10,9,8,10,10,8,9,10,7,7,8,6,6,7,5,5,6,6,4,4,5,6,5,3,5,4,3,4,5,5,6,6,6,7,6,5,3,1,0,1,2,3,3,3,4,4,5,5,6,5,6,7,7,7,7,6,6,6,6,6,5,6,5,4,5,5,3,4,5,4,5,5,5,6,6,5,6,6,7,7,7,8,8,8,8,9,9,9,9,10,10,10,8,8,9,8,7,7,7,6,6,6,6,5,4,5,7,5,6,5,7,5,6,7,6,7,8,7,8,8,7,8,8,8,7,8,7,7,8,7,7,7,8,8,8,8,7,8,9,8,8,9,8,8,8,8,9,9,8,9,9,10,10,9,10,8,9,8,9,7,7,8,8,8,7,9,7,7,8,8,8,8,8,9,8,8,9,9,10,9,9,8,10,9,8,9,8,8,8,8,8,8,8,8,10,9,9,9,9,9,9,9,10,9,9,10,9,10,10,10,11,9,10,11,9,10,9,10,10,10,10,10,11,10,12,10,11,11,10,11,11,11,11,12,11,12,12,11,10,12,12,11,12,11,12,12,11,12,11,11,12,10,11,12,11,10,10,9,10,9,9,9,9,10,9,9,9,11,9,10,9,10,10,10,11,9,10,11,10,10,10,11,12,14,13,16,16,15,17,17,18,19,20,20,21,24,24,23,23,24,24,23,27,24,25,26,24,27,25,27,27,27,25,27,27,27,28,26,27,27,25,25,27,26,26,27,26,26,28,27,26,25,27,27],[29,29,28,28,28,28,29,28,27,27,27,26,27,25,26,25,27,28,26,27,26,26,27,27,25,27,28,26,28,26,26,28,28,29,28,28,28,28,28,28,29,27,27,27,28,27,25,24,25,24,22,22,22,21,19,22,21,19,20,18,17,15,13,10,10,9,8,8,7,7,6,6,6,6,5,6,5,5,5,5,5,4,4,3,3,4,3,4,3,4,5,5,4,5,5,6,6,6,6,6,7,6,7,7,8,7,9,9,8,9,9,8,7,7,8,8,8,9,8,9,9,7,8,8,8,7,8,8,7,7,8,7,6,7,7,7,7,6,6,6,5,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,5,6,7,6,6,7,6,6,6,7,6,6,6,7,6,7,7,7,8,6,6,7,6,6,6,6,6,5,6,6,5,5,5,5,6,5,5,5,5,5,5,4,4,4,4,3,3,4,3,4,3,4,4,4,5,4,4,5,4,4,5,6,5,6,6,6,5,5,6,6,6,7,8,8,9,8,8,8,8,7,7,8,7,7,7,7,7,7,7,7,6,7,7,7,7,7,7,7,6,6,6,6,6,5,5,6,5,4,3,4,3,3,3,3,2,3,3,2,3,3,3,3,2,3,3,3,4,5,5,5,5,6,7,5,6,7,7,6,6,6,6,7,7,7,7,8,7,8,8,8,9,8,9,9,9,9,8,8,9,8,8,8,8,8,8,8,8,8,9,9,9,9,9,10,12,12,12,15,16,16,15,15,18,16,17,17,19,18,19,20,21,22,22,23,23,26,25,25,23,23,25,24,22,24,24,25,24,23,24,26,26,27,25,27,26,26,27,27,27,27,26,27,26,27,27,27,27,27,27,27,27,28,27,27,27,27,27,27,27,27,26,27,24,25,25,25,24,24,22,22,21,21,19,19,17,16,14,12,11,10,9,9,10,8,9,8,9,10,9,10,10,10,10,11,11,11,11,11,11,12,12,11,13,14,13,13,12,12,11,11,11,11,12,13,13,14,14,13,13,12,12,12,11,11,11,11,11,10,10,9,9,9,9,10,9,8,9,9,8,8,8,10,8,9,8,9,8,9,9,8,9,9,11,10,10,10,9,9,8,9,8,8,7,7,7,6,7,7,7,7,6,7,6,5,6,5,5,4,5,5,4,3,3,4,3,3,3,4,2,3,4,4,5,5,5,7,6,6,4,2,1,0,1,1,4,2,3,3,4,4,4,4,5,6,6,5,5,5,5,6,5,4,4,4,3,3,3,3,2,3,3,3,3,3,4,3,4,5,5,5,5,5,5,7,6,6,7,7,6,7,7,7,8,7,7,8,6,7,7,6,6,5,6,5,5,4,5,6,5,6,5,5,5,5,5,5,6,6,6,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,8,7,7,7,6,6,5,4,4,5,5,5,5,5,5,6,5,6,6,7,6,7,6,6,7,6,8,7,7,6,6,7,7,6,6,6,6,6,5,6,6,6,6,7,6,6,6,6,6,6,7,6,6,7,6,7,6,7,6,7,6,7,8,7,8,8,8,7,8,8,9,8,8,8,7,7,8,8,8,7,8,8,8,8,9,8,8,8,8,8,8,9,8,9,9,8,9,8,9,9,8,8,9,9,8,7,6,8,8,7,7,7,7,7,7,7,7,6,7,8,8,7,7,8,7,7,7,7,9,8,9,10,11,12,13,13,13,14,14,15,16,18,20,19,21,21,22,21,21,22,22,24,22,23,25,23,25,25,26,25,25,24,27,26,25,27,25,26,26,25,25,26,26,26,25,25,25,26,26,26,23,25,26],[28,28,29,28,28,29,29,28,29,28,27,26,28,26,26,25,27,27,26,27,26,26,27,26,26,27,27,26,28,27,26,28,28,28,27,28,28,28,28,28,28,27,26,27,27,27,25,24,26,24,22,23,24,22,20,23,21,19,20,19,17,14,13,9,9,7,6,6,5,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,2,3,3,3,3,4,3,4,4,4,5,4,4,5,5,4,5,5,5,6,6,6,6,7,7,6,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,6,5,5,5,5,5,5,5,6,5,5,4,4,5,5,4,5,5,4,4,5,5,4,4,5,5,4,4,4,5,5,5,5,5,4,5,4,5,4,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,4,4,4,4,4,4,3,4,4,5,5,4,4,4,4,4,4,4,4,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,4,4,3,4,5,5,4,4,5,5,5,5,5,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,4,3,3,3,3,3,2,3,2,3,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,7,7,7,7,7,8,7,8,11,11,12,14,16,17,16,16,19,19,18,19,20,20,20,21,22,24,23,23,25,26,26,26,24,25,25,24,25,26,25,25,26,25,25,27,26,27,26,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,27,27,26,27,27,27,27,27,26,27,27,26,26,25,24,25,22,22,22,20,19,19,16,15,14,11,10,9,8,8,8,7,8,7,8,8,8,8,8,9,9,9,9,10,10,9,10,10,10,10,11,11,11,11,11,10,11,10,10,10,10,11,11,12,13,10,11,10,10,10,9,9,9,9,9,8,8,8,8,7,8,8,7,7,7,7,7,7,7,7,7,8,7,7,7,7,7,7,8,8,9,9,9,8,8,7,7,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,5,5,5,3,3,3,4,3,5,3,2,2,3,2,2,2,3,3,4,4,5,7,6,6,5,3,1,1,0,1,2,2,2,2,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,3,2,1,2,3,2,2,3,3,3,3,4,3,5,4,5,5,6,4,5,5,5,5,5,5,6,6,5,5,5,5,4,5,4,4,5,4,4,4,4,3,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,4,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,6,5,6,5,4,5,4,4,4,3,4,4,5,4,4,4,4,4,4,5,5,5,5,5,4,5,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,6,6,6,6,7,7,7,7,7,7,7,7,7,6,6,7,6,6,7,7,6,6,7,7,6,8,7,8,8,7,8,7,7,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,5,5,6,6,5,6,6,6,6,6,6,6,6,8,9,10,10,12,13,13,13,14,14,16,17,19,20,23,22,22,21,22,23,22,24,21,24,25,24,25,26,26,25,25,25,26,25,25,27,25,25,26,24,24,26,27,26,26,26,25,27,26,25,23,25,26],[28,28,28,28,28,28,28,28,28,27,27,26,27,25,26,25,27,27,26,28,27,25,28,27,25,27,28,25,27,27,25,27,28,28,26,28,27,27,27,26,28,26,26,26,27,26,24,23,25,23,20,22,23,20,19,22,21,19,20,20,17,15,12,9,9,9,7,7,6,6,7,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,2,3,2,3,3,3,3,4,4,4,4,5,4,5,6,5,5,6,6,6,7,8,7,8,8,7,6,6,6,7,7,8,7,8,7,7,7,7,6,7,7,6,6,6,6,6,5,5,6,6,5,5,4,5,5,4,4,5,5,4,5,5,5,5,6,6,5,5,5,5,5,5,6,6,5,5,6,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,6,6,5,5,5,5,5,5,5,4,5,5,4,4,4,4,6,5,5,4,5,5,4,4,5,4,4,4,3,2,2,3,3,3,3,3,3,3,3,4,4,4,5,5,4,5,6,6,5,6,6,5,6,6,7,7,8,7,7,8,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,7,6,6,6,5,5,5,4,4,5,4,4,4,4,3,3,3,3,2,3,3,3,3,2,2,2,2,2,2,3,3,3,3,4,4,5,5,6,5,6,6,6,6,6,6,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,9,9,8,8,8,8,8,7,7,7,8,7,8,8,8,8,9,8,10,12,12,11,16,15,16,15,16,17,18,17,18,19,18,20,20,21,23,22,23,24,25,25,25,24,24,25,23,23,25,24,25,24,23,24,26,26,27,26,26,27,27,26,27,27,27,27,27,27,26,28,28,27,27,27,28,28,28,27,27,27,27,27,27,27,27,27,27,26,26,26,26,24,24,23,23,21,21,20,19,18,15,14,12,10,10,8,8,8,9,8,8,8,9,9,8,9,10,10,9,10,11,10,10,11,12,11,12,13,13,12,13,11,12,11,10,11,11,12,12,12,14,14,13,14,13,12,11,11,10,10,11,11,10,9,9,9,9,8,9,8,8,8,7,8,8,8,7,8,8,7,8,8,9,8,8,9,9,10,10,10,9,9,8,8,7,7,7,7,7,6,6,6,5,5,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,3,3,4,4,5,6,6,6,5,3,2,1,1,0,1,2,2,2,2,3,3,3,4,4,4,4,5,3,3,4,4,3,3,4,3,2,2,3,2,2,3,3,3,3,3,4,3,4,4,5,4,4,5,5,5,5,6,5,6,6,6,7,7,6,6,5,5,5,5,5,4,4,4,4,4,3,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,5,5,4,5,5,5,5,5,6,5,5,6,5,6,5,6,5,6,6,6,6,6,5,5,5,4,4,4,5,5,4,5,5,5,4,5,5,5,5,5,6,5,5,5,6,6,6,6,5,6,6,5,5,6,6,5,5,5,6,5,5,5,5,5,5,6,6,5,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,8,8,7,7,7,7,7,8,7,7,7,8,7,7,8,7,7,7,7,7,8,8,8,8,8,8,7,9,8,8,8,8,8,7,7,6,7,7,7,7,7,7,6,6,7,6,6,6,7,6,6,7,7,7,6,7,6,7,7,8,9,10,10,12,14,13,13,15,17,18,19,20,21,22,22,23,22,22,22,23,25,23,25,25,24,27,26,26,25,26,25,28,27,26,27,27,26,27,26,27,26,26,26,27,26,27,27,27,26,25,25,26],[29,29,29,29,29,29,29,29,28,28,28,27,28,27,27,27,28,28,27,28,27,27,28,28,27,28,28,26,28,27,26,28,28,28,27,28,28,28,28,27,28,27,26,27,27,26,24,23,24,23,21,22,22,20,20,21,20,18,20,20,18,15,13,11,10,10,9,8,8,8,8,7,8,7,7,7,6,6,6,6,6,5,5,4,3,3,3,3,3,3,4,3,3,4,5,4,5,5,5,5,6,6,6,6,8,7,8,8,9,9,9,9,7,7,8,9,9,9,10,10,9,9,9,9,8,8,8,8,7,7,7,6,6,6,6,6,6,5,4,6,5,5,5,6,5,4,6,6,5,6,6,7,6,7,6,6,6,7,7,7,7,6,8,8,7,7,8,7,8,9,9,8,8,9,8,7,9,9,8,7,7,7,7,6,6,6,5,5,5,5,5,4,4,5,5,5,6,5,5,6,5,5,4,5,5,4,4,4,2,2,2,3,2,3,4,4,4,4,4,4,4,6,6,5,6,8,7,7,7,9,8,9,9,9,9,10,10,9,10,10,9,10,10,10,10,9,9,10,10,9,8,8,9,8,8,8,7,7,7,7,7,6,6,6,5,5,5,5,4,4,4,4,3,3,4,3,4,3,3,3,3,3,3,3,3,4,4,4,5,5,6,7,7,7,7,8,8,8,9,8,7,9,9,8,9,9,10,10,10,11,11,12,11,11,10,10,11,11,11,11,10,10,10,10,9,9,10,9,9,10,10,10,10,10,11,13,13,14,13,16,16,16,16,17,18,19,20,20,21,20,22,23,25,24,25,25,27,25,26,25,25,26,24,23,25,25,25,25,25,25,27,26,27,26,28,28,27,28,28,28,27,28,28,27,27,28,28,27,28,27,28,28,28,28,27,26,26,27,27,27,27,27,27,26,26,26,26,24,25,23,23,23,22,21,20,17,16,15,14,13,11,11,11,11,11,11,10,11,10,11,11,12,12,11,11,12,13,12,12,13,14,13,13,15,14,13,14,12,13,12,12,12,13,13,14,14,16,15,15,15,14,15,14,13,13,13,13,13,12,12,12,11,11,11,11,11,10,11,10,10,11,10,10,10,12,10,10,10,11,10,10,11,10,11,11,11,11,11,11,11,9,10,9,8,9,8,8,8,8,8,8,7,7,7,7,6,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,4,4,5,5,7,6,7,7,4,3,3,1,1,0,1,1,2,2,3,4,4,4,5,5,5,5,4,3,5,4,3,3,4,3,3,3,3,3,2,3,3,3,3,4,4,4,5,6,6,5,5,7,7,6,7,8,8,8,9,8,9,9,9,8,8,8,7,7,6,6,5,5,6,5,5,5,5,6,5,4,5,5,5,4,5,5,5,5,5,6,5,5,5,5,5,5,4,4,5,5,6,5,5,4,6,6,5,6,6,7,7,6,7,7,7,7,6,8,6,6,6,7,8,7,7,7,6,6,5,6,5,5,5,6,5,5,6,6,5,6,6,6,6,6,7,7,7,8,8,8,9,8,7,9,8,7,7,8,7,6,7,7,8,7,6,7,7,7,6,7,7,7,8,7,8,7,7,8,8,7,8,8,8,7,8,8,9,8,10,9,8,8,9,10,10,8,10,9,9,8,10,9,8,11,9,9,9,10,9,9,10,10,10,10,10,10,10,9,10,10,10,9,9,9,10,10,9,8,8,9,9,8,8,9,9,8,8,9,8,8,8,9,9,9,9,10,9,9,10,9,9,9,10,10,11,11,13,14,14,14,14,16,17,18,19,19,22,22,21,20,21,21,21,24,22,23,23,22,26,25,25,24,26,23,26,26,25,26,26,26,26,24,25,26,26,26,27,26,25,26,26,25,23,25,26],[29,29,29,29,29,29,29,29,29,29,28,28,28,27,28,27,28,29,26,29,28,26,28,28,26,27,28,26,27,28,26,27,28,29,27,28,27,27,28,27,29,27,27,27,28,28,25,25,26,24,22,24,24,22,22,24,22,20,22,22,21,17,16,13,13,12,12,11,10,10,10,9,9,7,7,8,7,6,6,6,6,6,5,6,5,5,3,4,3,4,5,4,4,6,6,6,6,7,7,7,7,8,8,8,9,9,10,11,10,11,11,10,9,9,9,9,10,11,11,11,11,10,10,10,10,9,9,9,8,8,9,8,7,8,8,8,8,7,7,8,8,6,7,7,6,6,7,7,6,7,6,6,7,7,7,7,7,8,8,7,7,7,8,8,8,7,8,8,7,8,9,7,7,9,9,7,8,9,9,9,7,6,7,7,7,7,7,7,7,6,7,7,6,6,6,7,8,7,6,7,6,6,5,6,6,5,4,4,3,2,4,4,3,4,5,4,6,6,5,5,5,6,6,6,6,8,6,6,7,8,8,8,9,10,9,10,11,10,11,11,9,10,10,10,9,10,10,9,9,9,10,8,9,9,8,8,8,7,8,7,7,7,7,6,6,6,6,6,5,5,6,5,4,5,6,4,6,4,4,3,4,3,4,3,6,4,5,7,5,6,6,6,7,8,7,8,8,8,9,9,9,10,11,10,11,11,11,11,13,13,12,14,14,13,13,14,14,14,14,13,14,13,12,11,11,11,12,12,12,13,12,13,14,13,14,15,15,16,16,17,18,19,20,22,21,22,23,24,24,24,26,26,26,26,27,27,28,27,28,28,26,27,26,25,27,27,27,27,27,27,28,28,29,28,29,28,28,28,28,28,28,28,28,28,28,29,29,28,29,29,29,29,29,28,28,28,28,29,28,28,28,28,29,28,27,28,27,24,26,23,24,24,22,21,22,19,20,18,17,16,16,14,13,12,14,14,12,14,13,14,13,14,14,15,15,15,15,15,15,15,17,16,17,17,17,17,16,15,15,15,15,15,15,16,16,17,17,17,17,17,17,17,16,15,15,15,15,16,15,14,14,15,15,13,14,14,12,12,11,14,15,13,12,14,14,12,14,13,13,12,13,14,13,14,14,13,13,12,13,13,12,12,10,10,10,8,10,10,8,9,10,8,8,8,8,7,7,7,7,6,6,6,5,5,6,5,5,5,6,5,6,6,6,6,6,7,8,8,8,7,5,4,3,3,2,1,0,1,2,2,3,4,4,4,5,5,6,5,4,4,5,4,4,4,5,4,4,5,4,4,5,6,5,5,5,6,5,5,7,6,6,6,7,8,8,8,8,9,9,10,10,10,12,12,11,11,10,11,9,9,8,9,7,7,8,8,7,6,7,8,7,6,7,8,8,7,7,8,9,8,7,9,8,7,7,8,7,6,6,5,6,5,5,5,5,6,6,6,6,6,7,8,8,6,8,8,6,8,8,9,7,7,8,9,8,8,9,8,9,9,7,6,8,7,7,7,8,8,8,7,7,8,8,8,8,10,9,9,10,10,12,11,12,11,10,11,11,10,10,11,10,9,10,10,12,10,9,10,10,11,10,11,11,10,10,11,10,9,10,11,11,10,11,12,11,11,12,12,11,11,12,13,12,11,13,13,14,11,13,13,12,11,13,14,11,13,13,12,12,14,14,11,12,13,13,13,14,13,12,13,12,12,12,13,12,13,14,14,12,12,10,12,13,11,12,13,13,11,11,13,11,11,11,12,12,10,13,12,11,11,14,11,11,11,12,12,13,13,14,16,16,16,16,18,19,20,22,21,24,25,23,22,24,24,24,26,24,25,26,24,27,27,27,26,27,26,27,27,27,28,27,27,27,25,26,27,27,27,28,26,27,27,28,26,24,27,26],[27,28,28,28,28,28,28,28,28,27,27,27,27,27,27,26,28,28,26,28,27,26,28,28,26,27,28,26,27,28,26,27,28,28,27,28,28,27,28,27,28,27,27,26,27,26,23,24,25,23,22,23,23,20,21,22,20,19,20,20,17,15,13,10,10,9,7,7,7,6,7,6,6,6,5,5,4,4,5,4,4,4,3,3,3,3,3,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,8,8,7,7,6,7,7,7,7,7,7,8,6,6,7,7,6,6,7,6,6,6,6,5,6,6,6,6,5,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,5,6,6,5,5,6,5,5,5,6,5,5,6,6,5,6,6,6,6,5,5,5,5,4,5,5,5,4,4,5,4,4,4,4,5,5,4,4,5,4,4,4,5,4,4,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,5,6,7,7,7,8,7,7,8,7,7,7,7,7,6,6,7,6,6,6,7,5,6,6,6,7,6,6,6,5,5,5,5,5,4,3,4,4,3,3,4,3,3,3,4,3,3,3,3,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,9,9,9,9,9,9,10,9,9,10,9,8,8,8,8,9,9,9,9,9,9,11,9,11,12,12,13,15,16,16,16,16,19,19,18,20,20,20,21,22,23,24,25,25,25,26,25,26,26,25,26,24,23,25,25,25,25,25,25,27,26,28,26,27,28,27,27,27,27,28,28,27,27,27,28,28,27,27,27,28,28,28,28,27,26,27,27,27,28,27,27,27,25,25,26,25,24,24,22,22,22,21,19,19,17,16,15,12,12,11,10,10,9,10,9,9,10,9,10,10,11,11,11,11,11,12,12,12,12,13,13,14,15,14,14,14,13,13,12,11,12,12,12,14,13,15,15,14,15,14,14,13,12,12,12,12,12,12,11,11,11,10,9,10,10,8,8,8,10,10,8,8,9,9,9,9,9,9,9,10,10,10,11,12,11,10,10,9,9,8,8,7,7,6,6,7,6,6,6,6,5,5,6,5,5,5,5,4,4,5,4,4,4,4,3,3,3,4,3,3,3,4,5,5,6,9,8,7,7,4,3,3,2,2,1,1,0,1,1,2,3,3,3,3,3,3,4,3,3,4,3,3,3,3,2,2,3,3,2,2,3,3,3,4,4,4,4,5,5,5,4,5,5,5,5,6,6,6,6,7,7,8,8,7,6,7,7,6,6,6,6,5,5,6,5,5,5,5,6,5,5,5,5,5,4,4,5,5,5,4,5,4,5,4,4,4,4,4,3,3,4,4,3,4,4,5,5,4,4,5,5,5,5,6,5,5,5,5,6,5,5,5,6,6,6,6,6,6,5,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,7,6,7,6,6,6,7,7,7,7,7,7,7,7,8,7,7,8,8,8,8,7,8,9,8,8,9,10,10,8,9,9,9,8,9,8,8,9,9,9,8,9,9,8,8,9,9,9,9,10,9,9,9,9,10,9,9,9,10,10,9,9,8,10,9,8,9,9,9,8,8,8,8,7,8,8,7,7,8,8,7,8,9,8,7,8,9,10,11,11,12,14,15,13,14,16,18,19,20,20,23,23,22,21,22,22,22,24,23,24,25,24,26,26,26,25,26,25,27,26,26,27,26,26,27,25,25,26,27,26,27,26,26,27,27,26,24,26,26],[28,28,28,28,28,28,29,28,28,27,27,26,28,26,27,26,27,28,25,28,27,25,27,27,25,25,27,25,26,27,25,26,29,28,25,28,27,25,27,25,27,25,25,24,26,26,21,22,24,22,19,21,22,19,18,22,19,17,18,18,16,14,12,9,9,8,7,7,6,5,6,5,5,4,4,4,4,4,4,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,5,6,6,6,7,7,6,6,6,6,6,7,6,7,7,6,7,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,5,4,4,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,5,5,6,5,6,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,3,3,3,3,3,3,4,3,3,4,4,4,5,5,4,4,5,5,5,5,6,6,7,7,7,6,7,6,7,6,6,6,6,6,6,6,6,6,5,5,5,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,6,6,7,7,7,9,8,8,8,8,9,9,8,8,8,8,8,7,7,8,8,7,7,8,8,8,8,9,10,12,12,12,14,15,15,14,15,16,16,16,18,18,18,19,20,21,22,22,24,24,26,24,25,25,24,25,23,22,24,24,23,24,24,25,26,26,27,26,27,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,28,27,27,27,27,25,27,27,27,27,26,26,26,25,24,26,25,23,23,23,22,21,21,20,18,16,15,14,12,10,10,8,9,8,8,8,8,9,9,10,9,10,10,10,10,10,12,10,11,11,13,12,11,13,13,13,13,12,12,11,11,11,12,12,13,14,13,14,13,14,13,12,13,12,11,10,11,11,10,10,10,10,10,8,9,9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,10,11,11,10,10,10,8,8,8,7,7,6,6,6,6,6,5,6,6,6,5,5,6,5,5,5,4,4,4,4,4,4,3,3,3,3,4,3,3,3,4,4,4,5,6,7,6,6,4,3,2,2,2,2,1,1,0,1,1,2,2,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,5,5,5,6,6,6,6,6,7,7,6,7,6,6,6,6,6,5,6,5,5,5,4,4,4,5,5,4,4,5,4,4,4,4,4,5,4,4,4,4,4,4,4,4,3,3,3,3,4,3,3,3,4,4,3,4,5,5,5,4,5,5,4,4,4,5,5,5,4,5,5,5,5,5,5,4,4,4,3,4,4,4,4,4,5,4,4,5,5,5,5,6,5,6,6,6,7,7,7,6,6,7,6,6,6,6,6,6,6,7,7,6,5,6,6,6,5,6,5,5,6,6,6,6,5,6,6,5,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,7,7,8,7,7,7,7,7,7,7,7,8,7,7,7,7,7,8,8,8,8,8,9,8,8,8,8,8,9,9,8,8,8,8,8,7,8,8,7,7,7,8,7,7,7,7,7,7,8,8,7,7,7,7,7,7,8,9,10,11,12,13,13,13,14,15,16,18,19,18,21,22,21,20,21,21,22,24,21,23,24,22,26,24,25,25,26,24,26,26,24,26,25,26,24,23,24,25,26,25,27,25,25,26,26,25,23,24,25],[28,28,28,28,28,28,28,28,27,27,26,26,27,26,27,26,27,27,26,28,26,26,27,27,26,27,27,26,27,27,25,27,28,28,26,28,27,27,28,27,27,26,26,26,26,25,22,22,24,20,20,20,22,19,18,21,18,18,18,16,15,13,11,9,9,8,7,7,7,6,6,6,6,6,5,5,5,5,5,5,5,4,3,3,3,3,3,3,2,4,4,3,3,4,5,4,4,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,6,6,6,7,7,7,7,7,8,7,7,7,6,7,7,7,6,7,6,6,5,6,6,6,5,4,4,5,5,4,5,5,5,4,6,5,4,5,6,6,5,6,5,5,6,6,6,6,6,6,6,6,6,5,6,6,6,7,6,6,6,6,7,6,7,7,7,7,6,6,6,6,5,6,6,5,5,6,6,5,5,6,5,6,5,5,5,5,5,4,4,4,4,4,4,2,2,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,6,6,5,6,6,6,6,6,7,7,7,7,7,8,7,7,7,8,8,7,7,8,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,5,5,6,5,5,6,4,4,5,5,4,4,5,5,5,5,3,3,3,3,3,2,3,4,4,3,4,5,5,5,6,6,6,6,7,7,6,7,6,7,7,7,7,7,8,8,8,9,9,10,10,10,10,10,11,11,10,9,10,9,9,8,8,8,9,8,8,9,9,9,9,10,11,11,12,12,13,14,14,13,14,17,16,16,18,18,17,19,20,22,23,22,25,24,26,24,26,24,24,24,23,22,24,24,23,24,24,24,26,25,27,26,27,27,27,27,27,27,27,27,26,27,27,27,27,27,27,27,28,27,27,27,26,27,26,27,26,27,27,26,27,25,24,25,25,23,24,23,20,21,19,19,18,17,15,15,12,12,10,9,9,9,10,10,9,11,10,11,11,11,13,12,12,12,13,13,13,14,14,14,14,15,16,15,14,14,14,13,13,13,14,14,15,15,16,16,16,16,15,15,15,14,13,13,13,13,13,12,12,11,11,10,10,11,9,10,8,10,10,10,10,11,10,10,10,10,10,10,11,11,11,12,12,12,11,10,10,9,9,9,9,8,8,7,7,8,6,6,7,7,6,6,7,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,4,4,4,5,6,9,8,7,6,5,4,3,3,2,2,2,1,1,0,1,1,2,3,4,5,4,4,3,3,3,4,2,2,3,2,2,2,3,2,3,3,3,3,3,4,4,4,5,5,5,5,5,5,6,6,6,7,7,7,7,8,8,9,7,8,7,7,7,7,7,7,6,5,6,6,6,5,5,6,5,5,5,5,5,4,5,5,5,5,5,5,5,4,5,5,4,4,3,3,4,4,4,4,4,4,5,5,5,5,6,5,5,6,5,5,6,5,5,5,5,5,5,5,6,5,6,6,6,5,4,5,4,4,5,5,5,4,6,5,5,5,6,6,6,6,7,6,7,7,7,8,8,8,7,8,7,6,6,7,7,6,7,6,7,6,6,6,6,6,6,6,6,6,7,7,7,6,6,6,7,6,6,7,7,6,7,8,8,8,8,8,8,8,8,9,9,8,9,8,8,7,8,8,8,8,8,7,8,9,8,7,8,8,9,9,10,10,9,9,9,9,10,9,9,9,9,10,9,9,8,9,9,9,9,9,9,8,8,9,8,8,9,9,8,8,9,9,9,8,9,8,8,8,9,9,11,11,13,13,14,14,14,16,17,19,20,19,22,21,22,21,21,21,21,23,23,23,24,22,24,25,25,25,26,24,27,26,25,26,25,25,26,25,25,26,25,26,25,26,25,26,25,25,23,24,25],[29,29,28,28,29,29,29,29,28,27,27,27,28,27,27,27,27,28,26,28,27,25,27,27,25,26,28,26,26,27,25,26,28,28,26,27,27,26,27,26,28,26,26,25,26,25,22,23,24,22,20,22,22,20,19,21,19,18,19,19,17,16,14,12,11,10,11,10,9,9,9,9,8,8,8,7,7,7,6,6,6,6,5,4,4,4,4,4,3,3,4,5,4,5,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,10,10,9,8,8,8,9,10,10,10,10,10,9,10,9,9,9,8,9,7,8,8,7,7,8,7,8,6,6,5,6,6,5,6,6,6,6,6,6,5,6,7,6,6,6,7,6,7,7,7,7,7,6,7,7,7,7,7,8,7,8,8,8,8,8,8,8,9,9,8,8,8,8,8,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,4,5,6,6,4,5,4,4,4,2,4,3,3,4,4,5,4,4,6,5,5,6,6,6,6,8,8,7,8,8,8,8,9,9,9,9,9,9,10,10,9,10,10,9,10,9,10,10,9,10,10,9,9,9,9,9,9,9,9,9,8,8,8,8,7,7,8,6,6,5,7,6,6,6,6,6,6,5,5,3,4,4,5,4,4,5,5,5,6,6,7,7,8,9,8,8,9,9,9,9,9,9,9,10,10,10,11,11,11,11,12,14,12,12,12,14,15,13,13,13,13,12,12,11,10,11,12,11,10,11,12,11,11,12,12,14,14,14,15,15,16,16,18,18,18,18,20,21,20,21,23,24,24,24,26,26,27,26,27,26,25,26,25,24,25,26,25,26,26,25,27,27,28,26,28,28,28,27,28,28,28,28,28,28,27,28,28,28,27,27,28,28,28,28,27,27,27,26,28,28,28,27,27,26,26,26,27,24,24,24,23,23,22,20,21,19,17,17,15,14,13,13,12,13,13,13,13,14,14,14,14,14,16,16,15,15,17,15,15,17,18,16,17,17,18,17,18,17,17,16,17,16,17,17,18,18,17,18,19,18,17,17,18,17,15,16,17,16,16,16,15,14,14,14,13,15,13,13,11,14,13,13,13,13,13,13,14,13,13,12,14,14,14,15,14,13,14,14,13,12,12,12,11,10,10,10,10,10,8,9,10,9,9,9,9,8,8,8,7,8,8,8,6,6,8,5,6,7,7,6,4,6,5,7,6,6,8,7,9,7,6,5,4,4,3,3,2,2,1,1,0,1,2,3,3,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,5,5,5,6,6,5,6,8,7,7,9,9,8,9,9,9,9,9,10,10,10,11,11,11,10,10,10,10,9,10,10,9,8,9,9,8,8,8,10,8,7,8,8,8,7,8,8,8,8,8,7,7,7,7,7,6,6,5,5,5,5,6,5,5,5,6,6,6,6,6,6,7,6,6,7,7,7,6,6,6,6,7,7,8,8,7,8,8,7,6,7,6,7,7,7,7,8,9,8,9,9,9,10,10,9,10,10,10,10,11,11,11,11,11,11,10,10,10,10,10,10,9,10,10,9,10,10,10,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,11,11,11,11,12,11,11,11,10,11,12,11,11,11,11,10,10,11,10,11,11,11,10,12,12,11,11,11,12,12,13,13,13,13,12,13,12,12,12,12,12,12,12,12,12,11,12,11,11,12,12,12,11,11,12,11,12,12,12,12,11,13,12,11,11,13,11,11,11,12,12,14,14,15,16,17,16,17,18,20,20,22,21,23,23,23,23,24,22,23,24,24,24,26,24,26,26,27,26,27,26,27,26,27,28,27,27,28,27,27,27,28,28,28,28,27,28,27,27,25,26,27],[27,28,27,27,27,27,27,27,27,26,26,25,26,25,26,25,25,27,24,26,26,24,26,26,24,25,26,25,25,26,24,25,27,28,25,26,26,25,27,26,26,25,25,24,25,23,21,21,22,20,19,20,20,18,18,19,18,17,18,18,16,15,13,12,11,11,11,10,10,10,10,10,10,10,9,9,9,9,8,8,8,7,7,6,6,5,5,5,4,4,5,5,4,5,5,5,5,6,6,6,7,7,6,7,8,7,8,8,9,9,9,9,9,9,10,10,10,10,10,11,10,10,10,9,9,9,9,8,8,8,8,7,7,8,7,7,6,5,5,6,6,5,6,6,6,5,6,7,6,6,8,8,8,8,7,7,7,8,8,9,8,8,9,9,8,10,8,10,9,9,9,9,10,9,9,9,10,10,9,9,8,8,8,7,8,8,7,6,6,7,6,5,6,6,6,6,5,5,6,6,5,5,6,6,4,6,5,4,3,3,2,4,3,3,4,5,4,5,6,6,6,7,8,8,8,10,10,9,9,10,10,10,9,10,10,11,10,10,10,10,10,11,10,10,11,11,10,11,10,10,10,11,10,10,9,9,10,10,9,9,9,9,10,9,8,8,9,7,7,7,8,6,6,7,7,6,6,5,6,4,5,4,6,5,5,6,7,6,7,9,10,9,10,11,10,10,11,10,10,11,11,11,11,11,12,12,13,13,12,13,14,16,14,14,14,15,17,14,15,14,14,14,13,13,12,12,13,13,12,12,12,12,12,13,13,12,13,14,14,14,14,14,16,16,16,18,19,18,19,21,22,22,24,24,24,26,26,25,26,25,24,26,24,23,24,25,25,25,25,24,27,27,28,26,27,28,28,27,28,28,28,28,28,28,27,27,28,27,27,27,28,27,27,28,27,27,26,27,27,27,27,26,26,26,25,26,26,22,24,23,22,23,20,21,20,19,17,18,16,15,14,14,13,14,14,15,14,14,15,16,16,16,16,16,15,17,18,17,16,18,19,17,17,18,18,17,18,18,18,17,18,18,18,18,19,19,19,19,19,18,17,17,18,16,16,17,17,16,17,17,15,15,15,15,15,16,15,14,14,15,14,15,15,15,15,15,16,15,15,14,15,15,15,15,15,15,14,15,15,13,13,12,13,11,12,12,12,11,9,11,11,11,9,10,10,9,9,9,9,8,9,8,7,8,8,7,6,8,7,6,5,7,6,6,7,6,8,7,8,7,6,5,5,5,4,3,3,3,3,1,1,0,1,1,3,4,3,4,4,3,3,4,3,3,4,4,4,4,4,6,5,5,6,6,8,8,7,9,10,9,10,10,11,10,11,11,10,11,12,11,11,12,11,13,12,12,13,12,11,11,12,10,10,10,10,9,9,8,10,10,8,9,10,9,8,9,9,8,8,8,8,8,7,8,8,7,6,6,6,6,6,6,7,6,7,7,7,7,6,7,8,7,7,6,6,5,5,5,5,6,6,6,6,7,7,8,8,9,8,8,7,9,8,8,9,10,9,10,10,9,11,11,10,13,11,10,11,12,11,12,12,11,11,11,12,13,11,10,11,10,10,10,10,11,10,9,10,11,10,10,11,10,9,10,10,11,11,11,10,11,11,12,11,11,11,11,11,11,12,11,12,12,12,10,11,13,11,11,12,12,10,10,11,11,11,13,12,11,13,14,11,12,12,13,13,14,14,14,14,13,14,13,13,13,12,13,12,13,12,12,10,12,12,12,12,12,13,12,12,13,13,12,12,13,13,12,13,14,12,11,14,13,12,12,13,11,14,14,16,16,18,17,18,19,19,20,21,21,23,23,23,23,24,22,22,25,24,24,26,24,25,24,27,25,26,25,27,27,26,28,26,26,26,27,26,27,27,26,27,27,26,27,27,25,24,25,26],[29,29,28,29,29,29,29,29,29,28,28,27,28,27,27,27,27,28,26,28,27,26,28,27,26,26,27,26,27,26,25,27,27,27,26,27,26,26,27,25,27,24,25,23,25,24,21,22,23,20,19,21,20,19,17,20,19,17,17,17,16,14,12,11,10,10,9,9,9,9,9,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,5,6,6,6,6,7,6,6,7,8,7,7,8,8,8,8,9,9,8,8,8,8,9,8,9,9,10,9,9,9,8,9,9,9,9,8,8,8,8,7,7,7,7,7,6,6,6,6,6,6,6,7,6,6,7,7,7,7,7,7,8,7,7,7,7,7,7,7,7,7,7,8,7,7,8,8,7,8,8,8,8,9,9,8,9,9,8,9,8,8,8,7,7,7,7,7,7,7,6,6,6,7,6,6,6,5,5,6,6,6,5,6,4,4,4,4,4,4,3,4,5,5,5,6,6,5,7,6,6,7,8,7,8,8,8,7,8,8,8,8,9,10,9,9,9,9,9,9,9,9,9,10,9,9,9,10,9,9,9,9,9,10,9,10,10,9,9,9,9,9,8,7,8,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,5,5,5,6,5,6,6,7,7,8,7,8,8,8,9,9,9,9,10,10,9,10,10,10,10,10,10,10,10,11,11,13,12,13,12,13,13,13,12,12,11,11,10,10,10,11,11,10,10,10,11,11,11,11,12,12,14,13,15,14,14,14,15,16,15,17,17,16,18,20,21,21,23,22,24,24,26,24,25,24,24,24,23,23,25,24,24,25,24,24,26,27,27,26,27,28,27,27,28,28,28,27,27,26,27,28,28,27,27,27,27,27,28,26,27,27,27,26,27,27,27,25,27,26,25,27,26,23,25,22,23,22,21,20,19,18,17,17,15,13,11,12,11,11,11,12,11,11,14,13,12,14,14,14,14,15,16,15,15,14,18,16,17,17,16,16,18,17,17,15,15,16,17,16,19,18,16,18,18,18,17,17,18,16,14,14,15,14,14,15,13,14,13,12,15,13,11,11,10,11,12,12,11,12,12,12,12,13,15,13,14,14,15,15,15,13,14,13,13,12,12,12,11,11,11,10,9,11,9,10,11,9,9,10,10,9,8,8,8,8,8,7,7,7,8,8,6,7,7,7,6,5,6,7,7,6,8,7,8,7,6,5,4,5,4,4,5,4,3,2,2,1,0,1,2,3,3,4,3,2,4,3,2,4,3,4,3,4,4,4,5,5,6,7,7,7,6,7,7,7,8,9,8,8,9,9,9,10,10,10,10,10,10,11,11,11,11,10,10,9,9,10,9,9,9,10,9,9,9,8,9,8,9,9,8,7,7,7,7,7,7,6,7,7,7,6,6,5,5,4,4,5,5,5,5,6,6,6,6,7,7,7,6,5,6,5,5,6,6,5,5,6,5,5,7,7,7,7,7,7,6,6,7,7,7,7,7,8,7,8,9,8,9,9,10,9,9,10,10,10,9,10,10,10,11,10,11,12,10,10,10,11,10,9,9,9,8,9,9,9,8,9,8,8,8,9,9,8,9,9,10,10,10,10,10,10,10,9,10,11,10,10,11,10,10,11,10,10,11,10,9,10,10,10,10,10,10,10,10,12,10,10,10,12,11,12,12,12,11,11,11,11,12,10,10,11,12,12,11,12,12,12,11,11,12,11,10,10,12,11,11,12,11,11,11,11,11,12,10,10,13,11,12,11,12,12,14,14,15,16,17,17,18,20,20,21,23,22,26,24,25,25,25,24,25,25,25,26,28,26,27,27,29,27,27,26,29,28,27,28,28,27,28,28,28,28,28,28,28,28,27,28,28,28,27,27,27],[29,29,28,29,29,29,29,29,29,28,28,27,28,27,28,27,28,28,27,28,27,26,28,27,26,27,28,26,27,28,25,27,28,28,26,28,27,26,27,26,27,26,26,25,26,24,23,23,25,22,21,22,23,20,21,22,20,19,21,20,17,15,14,12,11,11,10,10,10,10,10,9,9,8,9,10,9,9,8,7,8,8,6,6,6,7,5,5,4,5,6,5,5,6,8,7,7,8,9,8,8,9,8,8,9,10,9,9,9,10,10,9,9,9,9,9,10,10,10,11,10,9,10,10,9,9,9,9,8,8,9,8,7,8,8,8,8,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,10,8,7,9,9,8,9,9,9,9,9,9,9,10,9,9,9,8,9,9,10,9,9,9,9,10,9,10,9,8,8,8,8,8,8,7,7,7,7,7,6,7,7,7,7,7,6,7,6,5,6,6,5,6,5,4,3,4,4,4,4,5,5,5,5,6,7,6,7,7,7,9,9,8,9,9,9,8,9,9,9,10,11,10,9,10,11,10,9,10,11,10,10,11,11,10,10,10,10,9,9,10,10,9,9,10,10,9,9,9,8,8,7,8,8,8,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,6,8,7,8,8,9,9,8,9,9,9,9,10,10,9,10,10,10,11,12,11,10,11,13,12,14,14,14,14,14,15,14,13,13,13,13,12,12,11,12,12,11,12,12,12,12,12,12,13,13,12,13,15,16,16,15,16,19,18,18,21,20,20,22,23,24,25,24,27,26,27,25,27,26,25,27,23,23,27,25,25,26,25,26,28,26,28,28,28,29,29,28,28,28,28,28,28,28,28,29,29,29,29,28,29,29,28,28,27,28,27,29,28,29,28,28,28,26,25,26,27,24,24,23,23,22,22,21,19,18,17,18,15,15,14,12,12,11,13,13,12,14,13,16,14,15,16,16,16,16,18,16,16,17,18,17,17,18,20,18,18,18,18,17,17,17,18,18,19,20,20,20,20,19,19,17,18,18,16,17,18,17,16,16,16,15,13,14,14,15,13,13,12,15,15,14,15,15,15,14,15,15,15,14,15,16,15,16,16,16,15,15,14,13,14,13,12,11,12,10,11,12,9,10,11,9,9,10,10,8,9,8,7,7,7,7,7,7,7,6,6,6,7,6,6,6,7,6,7,8,11,10,9,8,7,5,5,6,4,4,4,4,3,2,3,1,1,0,1,2,5,4,3,2,4,4,2,5,5,6,4,5,6,5,7,8,8,8,6,7,7,7,8,8,8,8,9,9,9,9,9,10,10,11,11,10,13,12,12,11,10,11,11,10,10,9,9,8,9,9,8,8,8,9,8,7,8,8,7,7,8,7,8,7,8,8,8,7,8,7,7,6,8,7,7,9,8,8,7,7,8,8,7,7,8,8,7,7,8,7,7,8,6,7,7,6,7,8,7,7,8,8,8,8,8,7,7,8,8,9,8,8,9,8,8,8,8,9,9,9,10,10,10,10,11,11,11,12,10,12,11,9,10,10,10,8,10,9,9,10,9,9,9,9,9,9,9,9,10,11,10,9,9,10,10,9,10,10,10,10,11,10,12,11,12,11,11,11,10,12,11,11,10,11,11,10,11,11,12,11,11,11,12,13,11,10,11,11,12,12,13,13,12,12,12,12,13,13,12,13,13,14,12,11,10,12,13,12,12,13,13,10,12,14,12,11,12,13,12,12,13,13,11,12,12,12,12,12,13,13,15,15,17,17,19,18,19,20,22,22,23,22,25,23,25,24,25,24,23,25,25,25,27,25,26,27,27,26,27,25,28,27,27,28,27,27,27,27,27,27,28,27,28,28,27,27,28,27,26,27,26],[28,28,27,27,28,28,28,28,28,27,27,26,28,27,27,26,27,27,25,27,26,24,26,27,25,25,27,25,25,26,24,25,27,27,25,27,26,25,26,25,26,25,25,24,24,23,21,22,23,20,20,21,21,19,18,20,18,18,18,18,16,15,13,12,12,11,12,12,10,12,10,11,10,9,10,11,9,9,9,9,8,8,7,7,7,6,5,5,4,5,5,6,5,6,7,7,7,8,9,8,9,9,9,9,10,10,10,10,10,11,10,10,10,11,11,10,11,12,12,12,12,11,12,12,11,10,11,10,10,9,10,9,9,9,9,10,9,9,8,8,8,8,8,9,8,8,8,9,8,8,9,8,9,9,8,8,9,9,9,9,9,8,9,9,9,10,9,10,10,10,10,11,12,11,10,10,10,11,10,11,10,10,10,9,9,9,9,8,9,9,8,7,9,8,8,8,8,7,8,8,7,6,7,7,6,6,5,5,4,4,4,6,5,6,7,7,6,7,8,9,7,9,9,9,10,10,9,11,10,10,10,11,11,10,11,11,12,11,11,11,11,12,12,12,12,12,12,11,11,12,11,10,11,11,11,10,10,10,11,10,10,10,10,10,9,10,10,9,9,9,9,8,8,8,8,8,7,7,7,5,7,5,7,6,7,8,9,8,9,9,11,11,10,10,10,10,11,12,12,13,12,11,12,13,13,13,15,15,14,14,16,17,15,16,18,16,18,16,15,16,14,14,13,13,13,12,14,13,12,12,13,13,12,13,13,14,13,14,14,14,14,15,16,16,16,16,18,18,18,21,21,21,23,22,23,24,25,25,25,24,24,24,25,23,24,24,25,24,24,25,26,26,27,26,26,27,27,27,27,27,26,26,26,26,27,27,27,26,27,27,27,27,27,26,26,26,25,27,26,27,26,25,27,25,23,25,26,22,23,23,20,22,20,20,20,19,18,17,16,15,14,15,14,16,14,15,17,17,20,17,17,17,18,18,18,18,20,17,17,19,21,18,19,21,21,20,20,19,20,18,19,19,19,18,20,21,21,21,21,20,19,19,19,19,17,18,20,18,18,18,17,16,17,16,19,18,17,17,15,17,16,17,17,16,17,17,17,15,18,16,16,16,16,17,16,17,16,16,16,14,16,14,15,14,12,12,13,13,11,12,13,12,11,12,11,11,11,11,10,10,10,10,8,8,9,8,8,8,8,8,7,8,8,9,7,8,10,9,10,9,8,8,7,6,5,5,4,4,4,3,3,2,2,1,0,1,2,4,2,3,4,4,4,5,4,5,5,7,6,8,8,8,7,8,9,10,8,9,10,10,10,11,11,11,12,12,12,12,12,13,14,13,15,16,15,13,14,12,12,13,12,12,12,11,11,11,9,11,11,11,10,10,11,11,9,11,10,10,10,9,9,9,9,9,10,9,9,7,8,7,7,8,8,7,7,7,8,8,7,7,8,9,8,7,7,7,6,4,5,5,6,6,6,7,8,8,9,10,9,10,8,10,8,9,10,11,10,11,11,11,11,12,11,12,13,12,13,12,13,14,14,13,14,12,14,13,12,12,13,12,12,13,12,12,11,12,12,12,11,12,11,11,11,12,11,11,11,11,12,12,12,13,14,13,13,14,13,13,13,13,13,13,13,13,13,15,12,12,14,13,12,13,12,11,13,13,13,12,13,15,12,13,13,15,15,17,15,15,15,14,15,13,15,14,14,13,13,14,13,14,11,14,13,14,13,14,15,12,13,14,15,14,14,15,14,14,16,16,14,14,16,15,15,14,15,13,16,17,18,18,19,20,20,20,22,22,23,22,25,24,25,24,25,24,24,26,26,25,27,26,25,25,27,26,26,26,27,27,27,28,27,27,27,27,27,27,27,27,28,28,27,27,27,26,25,26,26],[27,28,27,28,28,28,28,27,28,27,26,26,26,26,26,26,26,26,25,26,25,24,26,25,24,26,26,25,26,26,24,26,27,27,26,26,25,26,26,26,26,25,25,24,25,24,21,22,23,20,21,21,20,19,19,19,17,17,17,17,15,13,11,10,8,8,8,7,7,7,7,7,7,7,7,7,7,6,6,5,6,6,5,4,5,5,5,3,4,4,4,4,5,5,6,5,6,6,6,6,7,7,7,7,8,8,7,8,8,9,8,8,8,8,8,8,8,8,9,9,9,9,8,8,8,8,8,8,7,7,7,7,7,7,7,8,7,7,6,6,6,6,6,6,6,6,6,6,6,7,7,6,7,6,6,6,7,7,7,7,7,6,7,7,6,7,7,6,8,7,7,8,8,7,7,7,8,9,8,8,7,8,8,7,7,7,7,7,7,7,7,6,7,6,6,7,6,6,7,6,6,7,6,6,5,6,5,5,5,5,4,5,5,5,5,6,6,5,6,6,7,6,6,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,9,8,8,8,9,8,9,9,9,9,9,9,8,8,9,9,9,9,9,8,8,8,8,8,7,7,7,7,7,7,7,6,6,6,7,7,6,6,6,6,5,5,6,6,5,5,5,6,6,6,6,7,7,6,7,7,7,8,8,8,8,7,8,8,8,9,9,9,10,10,10,10,12,11,12,13,12,12,13,12,12,12,12,11,10,10,9,9,10,9,8,9,9,9,9,10,10,10,11,12,13,13,13,14,15,16,15,16,17,16,17,19,19,19,21,21,22,23,24,24,25,23,22,24,24,22,24,24,24,25,24,23,26,25,26,25,26,27,27,27,27,26,26,26,26,26,27,27,27,27,28,27,28,26,27,27,25,26,26,27,27,27,27,26,26,24,24,24,25,22,22,22,20,20,19,19,17,16,15,15,14,13,12,11,10,11,11,11,11,12,12,13,12,12,14,15,14,14,16,14,14,15,16,15,16,18,18,16,17,15,17,16,16,17,16,16,17,17,18,17,16,17,16,14,15,15,15,13,15,15,14,13,14,13,12,13,13,13,12,11,11,12,12,12,12,13,12,13,13,13,13,13,13,14,14,14,15,15,14,14,13,11,12,11,11,10,9,9,10,10,8,9,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,6,5,5,5,5,6,6,6,8,8,8,8,7,6,6,5,5,5,5,4,4,4,3,2,3,2,1,0,1,1,1,1,2,2,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,6,6,6,6,6,6,7,8,7,8,8,9,9,9,9,11,11,10,10,10,10,9,9,9,8,8,7,7,8,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,4,4,4,4,3,5,4,5,6,6,6,5,5,5,5,5,6,5,5,4,4,4,4,4,4,4,4,5,6,6,6,7,6,6,5,6,5,5,6,7,6,6,6,6,6,6,7,8,7,8,8,8,8,9,9,9,9,8,8,9,8,8,8,8,8,7,7,8,8,7,6,7,7,7,6,7,7,6,7,7,7,7,6,7,8,8,8,8,8,8,8,9,9,9,9,10,9,8,9,9,9,8,9,9,8,9,9,8,8,9,9,8,10,10,9,8,10,10,10,11,11,11,11,11,10,9,11,10,11,11,10,11,10,9,9,9,11,10,9,10,10,8,9,11,10,10,10,11,11,10,11,12,10,10,11,11,11,11,12,12,14,15,17,16,17,16,17,18,19,21,21,19,23,21,22,22,22,22,22,25,24,24,24,24,25,24,24,23,24,23,24,26,25,25,23,25,24,25,24,26,26,25,26,26,24,24,25,24,23,23,25],[28,28,27,28,28,28,28,27,27,27,26,26,27,26,27,26,27,27,26,27,26,25,27,26,25,26,26,24,25,26,23,26,27,26,25,26,25,25,26,25,25,23,24,23,23,22,21,21,22,20,19,20,20,19,19,20,18,18,18,17,15,13,10,9,7,7,6,6,6,5,6,5,5,5,5,5,5,5,5,4,5,4,4,3,4,4,4,3,4,4,4,5,5,4,5,6,5,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,7,7,7,7,8,8,9,9,9,7,8,9,7,8,8,8,7,8,8,7,7,8,8,8,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,6,6,6,6,6,6,6,5,5,6,6,5,6,6,6,6,7,7,7,7,7,7,7,8,8,7,7,7,7,7,6,6,7,7,6,7,7,6,6,7,7,7,7,6,6,6,6,5,6,6,5,5,5,4,5,5,4,4,5,5,5,5,4,5,5,5,5,6,6,5,5,6,6,5,6,6,6,6,7,7,7,8,8,8,9,8,8,7,9,8,7,8,8,8,7,8,8,7,7,8,8,8,8,8,8,7,7,7,6,6,6,6,6,6,6,5,6,6,6,5,6,6,6,6,5,5,5,4,5,4,4,5,5,4,5,6,5,5,6,6,6,6,7,7,6,6,6,7,7,7,7,8,8,7,8,9,9,10,10,11,11,11,12,11,10,9,9,8,8,8,7,8,8,7,7,8,8,7,8,9,9,10,11,11,13,14,13,13,14,15,14,16,18,17,17,20,21,19,23,22,22,24,25,24,26,24,23,25,24,22,24,24,24,25,24,25,27,25,26,27,26,27,28,27,27,27,27,27,27,27,27,27,28,27,27,26,27,27,27,27,26,26,25,27,26,27,27,26,26,26,24,25,24,22,22,22,21,20,19,18,17,16,14,14,12,11,10,10,9,10,10,10,10,11,10,12,11,11,12,13,12,14,14,13,13,13,16,14,15,16,17,17,15,16,16,15,14,16,14,16,17,16,17,18,16,17,14,15,15,14,13,12,14,13,12,12,12,12,11,11,11,12,10,9,9,10,10,10,10,11,10,10,10,12,12,11,12,13,13,13,14,14,13,13,12,12,11,11,10,9,8,8,8,8,7,7,9,8,7,7,8,8,7,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,5,5,6,9,7,7,6,6,5,5,4,4,4,4,3,3,3,4,3,3,2,1,1,0,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,8,8,9,8,9,8,8,7,8,7,7,7,7,6,6,7,7,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,4,3,3,4,4,4,5,5,5,5,5,5,4,4,4,3,3,4,4,4,3,4,5,5,5,5,5,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,8,7,7,8,7,6,7,7,7,7,7,6,7,6,6,6,6,5,6,6,5,6,6,6,6,5,6,6,6,6,6,7,7,7,7,7,7,7,8,8,7,8,9,10,8,7,8,8,7,8,7,7,7,8,7,7,9,7,7,7,8,8,9,10,10,8,9,9,8,10,9,9,9,10,10,9,9,8,10,9,9,9,10,9,7,8,10,8,8,10,10,8,9,10,10,9,10,11,10,10,9,11,11,12,14,15,16,17,17,19,19,20,21,22,22,23,22,23,23,23,22,24,25,25,26,25,24,26,26,26,25,26,25,27,26,26,27,26,26,25,26,28,26,26,27,27,27,26,26,27,25,24,24,26],[28,28,27,28,28,28,29,27,28,27,26,26,27,27,27,26,27,26,26,27,26,25,27,26,25,26,26,25,26,26,25,26,27,27,26,27,26,25,26,26,27,25,25,24,25,24,22,22,24,21,21,22,21,19,20,21,18,17,19,18,15,13,11,9,8,7,6,6,6,5,6,5,5,5,5,4,5,4,4,4,4,4,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,6,7,7,7,7,7,6,6,6,6,6,6,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,5,6,7,7,6,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,7,6,6,5,5,6,6,5,5,6,6,5,5,5,5,5,6,6,6,6,5,5,6,6,5,5,5,5,5,4,4,4,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,5,5,5,6,7,7,7,6,7,7,7,6,7,7,7,6,7,7,6,6,7,6,6,6,7,7,7,7,7,7,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,3,4,3,3,4,4,4,4,5,5,4,5,5,6,5,6,6,6,5,6,6,6,7,7,7,7,8,8,9,8,9,9,10,10,10,10,10,9,9,9,8,8,8,7,8,8,8,7,8,8,8,9,9,9,10,10,11,13,14,14,13,15,15,14,15,18,17,17,19,21,20,21,22,23,23,25,22,25,24,24,25,24,22,24,25,24,25,25,25,27,25,27,27,27,28,27,27,27,27,28,28,27,27,27,27,27,27,28,27,28,28,28,27,26,27,27,27,27,27,28,27,27,26,25,25,25,24,23,23,22,21,20,19,18,16,15,14,12,10,10,9,9,9,9,9,9,10,10,11,11,10,11,12,12,13,14,12,12,14,15,13,15,16,16,14,15,15,15,14,13,15,14,15,16,17,16,16,16,16,15,14,14,13,13,12,13,13,13,11,11,11,10,11,10,10,8,8,9,9,9,9,9,10,10,10,10,12,11,11,12,13,12,13,13,13,12,12,11,10,10,9,8,8,7,7,7,7,6,7,7,7,6,7,7,6,6,6,5,5,5,5,5,4,5,4,4,5,5,4,3,4,4,5,5,6,7,7,7,7,6,5,4,4,3,3,3,3,3,2,3,3,3,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,7,7,7,7,7,7,7,6,5,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,2,2,3,3,2,3,3,4,4,3,4,4,4,4,4,4,3,3,3,3,4,4,3,4,4,5,5,5,5,5,4,4,4,3,4,5,5,4,5,5,5,6,6,5,6,6,6,6,7,7,7,7,7,8,7,7,7,8,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,5,6,6,6,7,7,7,7,7,7,8,7,8,8,8,8,7,8,8,8,8,8,7,7,8,7,7,8,8,7,8,8,8,7,8,8,8,8,9,10,8,9,9,8,9,9,8,9,9,9,8,8,8,8,8,8,8,8,8,7,8,9,9,8,8,9,9,8,9,9,8,9,10,9,9,9,10,10,12,13,16,16,16,15,18,19,19,21,22,23,24,23,24,24,24,23,25,25,25,25,25,25,27,26,26,25,26,25,27,26,26,28,26,27,26,26,26,26,26,26,27,27,26,26,27,25,26,25,25],[29,29,29,29,29,29,29,29,28,28,28,27,28,27,28,27,28,28,27,28,27,26,27,27,26,27,27,26,27,27,25,27,28,28,27,27,26,26,27,26,27,26,26,25,25,24,22,23,23,21,21,21,20,19,18,20,18,18,19,17,15,13,10,8,7,7,6,5,6,5,5,5,5,5,4,5,4,4,4,3,4,3,3,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,5,6,7,6,7,7,6,6,5,6,6,6,6,6,7,7,6,6,6,6,6,7,6,6,6,6,6,6,5,6,6,6,6,5,4,5,5,4,5,5,4,4,5,5,5,5,5,5,5,4,5,4,4,5,4,5,4,5,5,5,5,4,5,5,5,5,5,5,5,5,6,5,6,6,6,6,5,5,6,6,5,5,5,5,5,5,6,4,5,5,5,5,5,5,4,5,5,5,5,4,4,4,4,3,3,3,3,4,3,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,7,6,6,7,7,6,6,7,6,6,6,6,6,6,6,6,5,6,6,6,6,7,7,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,6,7,7,7,7,8,8,8,9,9,9,9,10,10,9,9,8,8,8,8,8,7,7,7,7,6,7,8,7,8,8,9,9,10,11,12,13,14,13,15,15,15,16,18,17,17,20,21,21,23,22,24,24,26,24,26,24,23,25,24,23,24,25,24,24,25,24,27,26,27,27,27,28,28,28,27,27,28,28,28,28,28,28,28,27,28,27,28,27,27,28,27,27,27,27,27,28,27,26,27,26,24,25,26,23,24,22,21,22,21,19,19,15,15,14,11,10,9,8,8,9,9,8,8,10,9,11,10,10,11,12,11,12,14,13,12,14,14,14,14,15,16,15,15,15,15,14,14,14,14,15,15,16,16,16,16,15,14,14,14,13,13,12,13,12,11,12,11,11,9,9,9,10,8,8,8,9,9,8,9,10,10,9,9,11,9,9,11,12,11,12,12,12,11,10,9,9,8,8,7,7,6,7,6,7,6,6,6,6,5,6,6,5,5,5,5,5,5,4,4,4,4,3,3,4,4,3,3,3,4,4,4,4,7,6,7,6,5,4,3,3,3,3,3,3,3,2,3,2,3,3,3,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,7,7,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,3,3,2,2,2,3,3,2,3,3,3,4,3,4,4,4,3,3,3,3,3,3,3,3,3,4,3,4,5,4,4,4,5,4,4,4,3,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,7,6,7,6,6,7,7,6,6,6,6,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,6,6,6,6,7,7,6,7,7,7,7,7,8,8,7,7,7,7,7,8,6,6,7,7,7,7,8,7,7,7,7,7,8,9,9,8,8,9,8,9,8,8,8,9,9,8,7,7,9,8,8,7,8,8,7,7,8,8,7,8,8,8,7,8,8,7,8,9,8,7,8,9,10,11,12,14,14,16,15,17,18,20,21,22,21,23,23,25,23,24,23,23,25,25,24,27,25,26,26,28,26,27,26,27,28,27,28,27,27,27,26,28,27,27,27,28,28,27,27,27,27,26,25,27],[29,29,28,28,28,29,29,28,28,27,27,27,28,27,27,27,28,27,26,28,27,25,28,27,25,27,27,25,26,26,24,27,27,28,26,27,27,26,27,25,27,25,25,25,25,25,22,22,24,22,21,22,22,21,19,21,19,18,17,17,14,12,10,8,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,5,5,5,5,5,6,5,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,6,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,5,5,5,4,5,5,4,4,5,4,5,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,6,6,6,6,6,6,5,6,6,5,5,6,6,5,5,6,5,5,5,6,6,5,6,6,6,5,5,5,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,3,3,4,4,3,4,5,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,8,7,7,7,7,6,5,6,6,5,5,6,6,6,6,7,8,9,8,9,11,12,12,13,13,14,14,14,15,16,16,18,19,19,21,21,23,23,25,22,25,22,21,25,22,21,23,24,24,24,23,25,25,26,26,25,27,27,27,27,27,27,27,27,26,26,26,27,27,27,27,27,27,27,27,26,27,26,27,27,26,27,27,26,27,24,24,24,24,22,23,20,21,20,20,18,16,14,13,12,10,9,8,7,7,7,7,7,7,7,7,8,8,8,9,9,8,9,10,9,9,11,11,10,11,13,13,12,13,11,12,11,10,11,10,11,11,12,13,13,12,11,11,10,11,10,10,8,10,10,9,8,9,9,7,8,7,7,7,6,7,7,7,6,6,8,7,7,7,8,7,7,9,9,9,10,10,10,9,9,8,8,7,7,6,6,6,5,6,6,5,6,6,6,5,5,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,3,3,4,4,4,6,6,6,7,4,4,3,3,2,3,3,3,2,2,2,2,2,2,2,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,5,6,6,5,5,5,4,4,4,5,5,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,3,4,3,3,3,4,4,4,4,3,3,3,3,3,3,3,4,3,4,5,5,4,4,4,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,5,6,6,6,6,6,6,6,5,6,5,5,6,6,5,6,7,6,5,6,7,6,7,7,7,7,7,7,6,7,7,7,7,8,7,7,7,6,7,7,6,6,7,6,6,6,7,7,6,6,7,6,6,7,7,6,7,7,7,7,7,8,8,10,10,11,13,14,12,14,15,18,18,19,18,22,21,21,22,21,21,22,24,24,24,24,21,26,25,25,24,25,24,26,25,25,26,24,25,24,25,25,25,26,27,26,25,26,24,25,26,24,24,26],[28,28,27,28,28,28,28,27,28,27,27,27,27,27,27,27,27,27,28,28,27,26,27,27,26,27,27,25,26,26,24,27,27,27,26,27,26,25,26,25,27,26,25,24,25,24,20,23,23,20,19,22,21,19,20,21,18,18,18,17,14,12,10,8,6,6,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,4,5,5,5,5,5,6,5,5,5,6,5,5,5,5,4,5,5,5,4,5,5,6,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,4,3,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,4,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,5,5,5,5,5,5,4,5,4,4,4,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,4,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,6,5,5,5,6,5,4,5,5,5,4,5,5,4,5,6,6,5,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,3,3,3,3,3,4,3,3,4,4,4,4,4,5,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,7,6,6,6,6,5,5,6,5,5,6,5,6,6,6,7,8,9,10,12,12,12,12,13,14,13,14,16,16,16,17,20,19,21,21,22,23,25,23,25,24,22,25,23,22,24,24,22,24,23,24,26,23,26,26,26,27,26,26,27,26,26,26,26,26,26,27,27,27,27,27,28,26,27,26,26,26,26,26,26,26,27,26,27,25,23,23,23,21,21,20,19,19,18,17,16,14,13,12,10,9,7,7,6,6,7,7,6,7,7,8,7,8,8,8,8,9,10,9,9,10,12,10,12,12,12,11,12,11,12,10,10,11,10,11,12,12,12,13,11,11,11,10,10,9,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,7,7,6,6,7,7,7,7,8,7,8,8,9,9,10,10,9,9,9,8,8,7,7,6,6,5,5,6,5,4,5,6,5,5,5,5,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,2,3,3,4,4,5,7,6,6,6,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,5,5,5,6,5,5,5,4,4,4,5,4,4,4,4,4,4,3,4,4,3,3,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,6,6,5,6,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,3,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,6,5,5,6,6,6,6,7,7,7,6,6,6,7,6,7,7,7,7,7,6,6,7,7,7,6,6,6,6,6,7,6,6,7,6,6,6,7,7,6,7,7,6,7,6,8,8,10,10,12,13,13,13,15,16,18,19,20,21,22,21,21,21,22,20,23,24,24,25,25,23,25,25,26,25,25,24,27,26,25,26,26,25,25,25,26,26,26,25,26,27,25,25,26,24,24,24,24],[28,28,28,28,28,28,29,28,28,27,26,27,27,26,26,27,26,26,26,27,26,26,26,26,25,27,26,26,28,26,25,27,27,28,27,27,26,27,27,27,27,26,26,25,26,25,23,22,24,21,22,21,22,20,19,20,18,17,18,17,14,12,10,7,6,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,5,5,4,4,3,4,4,3,3,4,3,3,4,3,3,3,4,3,3,3,4,3,3,4,4,3,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,5,4,4,4,4,4,4,3,4,4,4,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,2,3,3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,6,6,6,6,7,8,9,9,11,13,13,13,14,14,14,14,16,16,16,17,20,19,20,21,23,23,24,23,24,22,21,24,21,21,23,23,23,22,22,23,26,24,27,25,26,27,27,26,27,27,27,27,27,27,27,28,28,27,27,26,28,27,27,27,26,26,26,26,26,27,26,26,26,25,25,25,24,23,22,21,22,19,19,17,17,15,13,12,9,8,7,6,6,6,6,6,6,6,6,7,7,7,8,8,8,9,10,9,9,10,11,10,10,12,12,11,12,11,11,11,10,10,10,10,11,12,12,12,12,11,10,10,10,9,9,8,9,9,8,8,8,7,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,7,7,7,7,8,8,9,9,9,8,7,7,6,6,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,4,4,4,6,6,6,5,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,4,4,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,5,5,5,5,5,6,5,5,5,6,5,5,5,5,5,6,6,6,6,6,7,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,5,5,6,6,5,6,5,5,5,6,6,5,5,6,5,5,6,7,7,9,10,11,13,13,12,14,15,16,19,19,19,22,21,23,22,23,21,22,24,23,24,24,24,26,26,26,25,25,25,26,26,26,28,26,26,26,25,26,26,25,25,26,25,25,26,27,25,23,25,26],[29,29,29,29,29,29,29,28,29,27,27,27,28,27,28,26,28,28,26,28,27,25,28,27,25,27,28,26,27,28,25,27,28,28,26,27,27,26,27,26,27,26,26,25,26,25,23,22,24,22,22,22,22,21,20,21,20,19,17,18,15,12,9,7,6,5,4,5,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,4,4,5,4,4,5,4,4,4,4,4,4,4,5,5,4,4,3,4,4,3,3,4,3,3,3,4,3,3,4,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,5,5,5,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,6,6,6,7,8,9,9,12,12,13,13,13,14,15,15,16,17,18,19,20,20,22,22,23,23,25,23,25,24,23,26,22,22,25,25,23,24,24,25,27,25,27,26,27,28,27,27,27,27,27,27,27,27,27,27,28,27,28,27,28,28,28,27,27,27,26,26,27,27,27,26,26,25,25,25,24,23,23,22,21,20,19,19,18,14,13,11,9,8,7,6,6,6,6,6,6,6,6,7,6,6,7,8,7,8,9,8,9,10,10,10,10,12,12,12,11,10,11,10,9,10,9,10,11,12,11,12,12,11,11,9,10,10,9,8,9,9,8,7,7,7,6,6,6,6,6,5,5,6,6,5,5,6,6,6,6,7,6,6,7,8,8,9,9,8,8,7,6,6,5,5,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,4,6,6,6,6,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,4,4,4,3,3,3,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,4,4,4,4,4,4,4,4,3,3,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,6,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,6,6,6,6,6,6,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,7,8,9,9,10,12,13,11,13,14,16,17,19,19,22,21,21,21,22,22,22,24,22,23,24,23,27,26,26,24,26,25,26,26,25,27,25,26,27,25,25,26,27,26,26,26,26,26,27,25,23,24,25],[28,28,28,28,28,29,28,28,28,27,27,26,27,27,27,26,26,27,25,27,26,25,27,27,25,27,27,25,26,26,24,27,27,27,26,27,25,26,26,26,26,25,25,25,25,25,22,22,22,21,20,21,21,20,18,20,19,18,16,16,15,12,9,7,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,4,4,5,5,5,5,6,6,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,5,4,4,4,4,4,3,3,4,3,3,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,5,4,4,4,5,5,5,5,5,5,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,4,4,4,4,4,5,4,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,4,5,5,4,4,5,5,5,5,6,6,7,9,9,10,11,12,11,13,14,13,14,15,16,16,17,20,19,21,21,22,23,25,23,25,23,23,24,23,21,24,24,23,24,23,24,25,24,26,25,27,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,26,27,27,26,25,26,26,25,26,26,25,26,24,24,24,23,22,22,19,20,19,17,17,15,13,12,11,10,8,7,6,5,5,6,6,6,6,6,7,7,7,7,7,7,8,9,8,8,9,9,9,9,10,10,11,10,9,10,9,9,9,9,9,9,10,11,11,10,11,10,9,9,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,6,5,5,6,6,6,6,7,6,6,7,7,8,8,8,8,8,7,7,6,6,6,5,5,5,4,4,5,4,4,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,4,6,6,6,5,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,2,1,1,1,1,1,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,2,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,4,4,3,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,5,4,4,5,5,4,5,5,5,4,4,5,5,6,6,6,6,6,5,5,6,6,6,6,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,7,8,9,11,11,12,11,12,15,15,17,19,18,22,21,20,20,21,21,22,24,22,24,24,21,26,24,25,24,25,24,26,25,24,26,25,25,24,24,24,26,26,25,26,26,25,25,25,25,23,25,25],[28,28,27,28,28,29,28,27,28,27,26,27,27,26,26,27,27,27,27,27,26,25,27,26,25,27,26,26,27,26,24,27,27,28,27,27,27,27,27,27,28,25,25,25,26,26,22,23,24,21,21,22,22,19,19,20,18,18,17,17,15,13,10,7,6,5,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,5,5,6,6,8,9,10,11,13,12,13,14,15,14,15,16,18,18,17,20,20,20,21,23,22,24,24,25,23,23,24,22,21,24,23,23,23,23,23,26,23,26,25,26,26,26,26,26,27,27,27,27,27,26,27,27,26,27,26,27,26,27,27,26,27,26,26,26,26,26,26,27,25,24,24,24,22,21,21,19,19,18,17,16,14,12,11,9,7,7,5,5,5,6,5,5,6,6,6,6,6,7,7,7,7,8,7,8,8,9,9,9,10,10,10,10,9,10,9,8,8,8,8,9,10,10,11,10,10,9,8,8,8,7,7,8,7,6,6,7,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,8,8,8,7,7,6,5,5,5,4,4,4,4,4,4,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,4,6,6,6,6,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,4,3,3,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,5,4,4,4,4,5,5,5,5,6,5,5,5,5,6,5,5,6,5,6,5,5,6,5,5,5,5,5,4,5,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,6,7,8,9,10,11,11,11,12,14,15,17,19,18,21,21,21,20,21,19,23,23,22,24,23,24,26,25,26,24,25,24,26,25,25,27,25,24,26,24,25,24,26,26,25,26,25,26,25,25,23,24,25],[29,29,29,29,29,29,29,28,29,28,28,28,28,27,27,27,27,28,26,28,27,26,28,27,26,28,27,26,28,27,26,28,28,28,27,28,27,27,28,27,28,26,26,26,26,25,23,23,24,22,22,22,21,20,20,20,18,18,17,17,15,12,10,7,6,5,4,4,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,4,3,3,2,3,3,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,2,3,3,3,3,4,4,4,5,4,5,5,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,3,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,5,4,4,5,5,4,4,5,5,5,5,6,7,9,9,9,12,14,13,13,14,15,15,15,18,17,18,18,21,20,22,21,23,24,25,24,26,24,22,24,23,22,24,24,24,24,23,23,27,25,27,27,27,27,27,27,27,26,27,27,27,27,27,27,27,27,28,27,28,27,27,27,27,27,27,27,26,27,27,26,27,26,25,25,25,23,23,22,21,20,18,17,16,14,12,10,9,7,6,5,6,5,5,5,5,6,6,6,6,6,7,7,7,7,8,7,8,8,9,9,9,10,10,10,10,9,9,9,8,8,8,9,9,10,10,10,10,9,9,8,8,8,7,7,7,7,7,6,6,6,6,6,5,5,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,7,7,8,7,7,7,6,5,5,5,5,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,6,6,6,5,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,4,5,5,5,6,6,5,5,5,5,5,5,5,6,6,6,5,5,5,6,5,5,5,5,4,4,5,4,4,5,5,4,4,5,5,4,5,5,5,4,5,6,7,8,9,10,11,11,11,12,14,15,17,19,19,22,22,21,20,21,21,20,23,22,22,24,22,25,25,25,25,26,25,26,25,26,27,25,25,26,24,25,26,26,26,26,25,25,25,25,24,23,25,25],[29,28,28,28,28,28,28,27,28,27,26,26,26,25,26,26,26,26,25,26,25,24,26,26,24,25,26,24,26,25,24,26,27,26,26,26,26,26,26,25,26,24,25,24,25,25,22,22,24,22,20,21,22,21,19,20,20,18,16,17,14,12,9,6,6,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,4,5,4,4,4,3,4,4,3,4,4,4,4,4,5,6,8,8,8,11,12,12,12,12,13,13,14,15,16,16,17,18,18,21,21,21,23,24,23,24,22,22,23,22,21,22,23,23,23,23,23,25,23,25,25,25,25,26,26,26,26,26,26,26,25,26,26,26,26,26,26,26,25,26,26,25,26,25,25,25,26,25,25,25,23,23,23,23,23,21,20,20,18,18,17,15,14,11,10,8,7,6,5,5,4,5,5,4,5,5,5,5,5,6,6,6,6,7,6,6,7,7,8,8,8,8,8,8,8,8,7,7,7,7,7,8,8,9,9,8,8,8,7,7,7,7,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,7,7,6,6,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,3,3,4,6,5,6,5,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,2,3,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,4,5,5,4,5,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,4,5,6,7,7,9,10,10,9,11,12,13,14,16,16,19,18,19,18,18,19,18,21,19,21,21,20,23,22,24,22,24,22,24,23,23,24,22,23,23,22,23,24,24,24,24,24,24,24,24,24,21,22,25],[28,28,28,28,28,29,28,27,28,26,27,27,27,27,26,26,26,27,25,27,26,24,26,26,23,26,26,24,26,25,24,26,27,27,25,27,25,26,27,26,26,25,24,25,25,25,21,22,23,21,19,21,22,18,18,20,18,17,17,17,15,12,9,7,5,5,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,4,4,4,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,3,3,3,4,3,3,4,4,4,4,5,5,6,8,8,10,12,12,12,12,14,13,15,16,17,17,16,19,18,20,19,21,22,23,23,23,22,22,23,23,20,22,23,23,23,22,22,24,24,26,24,25,24,25,25,25,24,24,24,24,25,26,25,25,25,26,26,27,26,26,25,25,24,26,26,24,25,24,23,26,24,23,23,22,21,20,19,19,18,17,16,14,13,11,9,8,6,5,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,7,7,7,7,7,8,8,8,9,8,7,8,7,7,6,6,6,6,6,6,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,7,7,7,6,6,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,3,3,4,5,5,6,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,2,3,3,4,4,3,3,3,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,3,3,4,4,3,3,4,4,4,5,5,5,4,4,4,5,5,4,4,5,5,4,4,4,5,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,5,6,7,8,9,10,10,10,11,12,13,15,18,17,20,18,19,18,19,18,19,21,19,21,22,20,24,23,24,23,25,24,26,23,24,25,23,23,23,22,23,23,24,23,24,23,23,24,23,23,21,23,24],[28,28,27,28,27,29,28,27,28,27,27,27,26,26,27,26,27,26,26,26,26,25,26,26,24,26,26,25,27,26,24,26,26,27,27,27,26,27,27,26,27,26,25,25,25,25,23,22,24,21,21,21,22,19,19,20,19,17,17,18,14,12,10,7,6,5,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,2,3,2,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,4,4,4,5,6,8,8,9,11,13,14,12,14,15,15,15,17,17,17,17,19,19,20,20,21,22,24,22,23,22,21,23,20,21,23,22,22,23,22,23,25,22,25,25,25,25,26,26,26,25,26,26,25,26,26,26,26,26,26,26,27,26,26,26,25,25,25,26,25,26,25,25,26,24,25,23,24,23,22,20,20,19,18,16,15,13,11,9,8,6,5,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,8,8,8,7,7,7,7,7,6,7,7,7,8,8,7,7,7,7,7,6,6,6,6,6,6,5,5,5,4,4,4,4,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,5,4,4,4,3,3,3,2,3,3,3,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,3,3,4,6,6,6,5,4,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,4,3,3,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,2,3,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,5,6,6,7,8,10,10,9,11,12,13,15,17,17,20,20,19,17,19,19,20,22,20,22,22,23,25,24,24,23,25,24,25,24,24,26,23,24,25,24,22,25,25,24,24,24,23,25,24,24,21,24,23],[28,28,28,28,28,28,28,27,28,27,27,27,26,26,26,25,26,27,25,26,26,25,26,26,24,26,26,25,27,26,24,26,27,27,27,27,27,27,27,27,27,26,26,26,26,25,24,23,24,22,22,22,21,20,19,20,18,17,16,16,13,11,8,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,2,3,2,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,3,3,4,4,4,4,5,6,7,8,8,11,11,12,11,13,14,13,14,16,16,17,19,20,19,22,21,21,23,24,22,23,22,21,22,21,22,22,22,23,24,22,21,25,23,26,25,25,25,25,26,26,25,25,25,25,25,26,25,25,25,26,26,26,25,25,25,25,25,25,25,24,25,24,24,25,24,23,23,24,22,21,20,19,19,17,15,15,13,11,9,7,6,5,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,7,7,7,6,6,6,7,7,8,8,8,8,7,7,6,6,7,6,6,6,6,5,5,5,5,4,4,4,4,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,5,5,4,4,3,3,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,2,2,2,3,5,5,5,5,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,3,4,3,3,3,3,3,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,2,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,4,3,3,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,5,5,7,7,8,10,10,9,11,12,13,14,16,16,20,19,18,17,18,19,19,22,19,21,21,21,24,23,23,24,25,24,26,24,25,25,23,24,24,22,22,25,26,24,24,24,23,24,24,24,20,23,25],[28,27,28,28,28,28,28,27,27,27,26,26,26,25,26,24,26,26,24,26,25,23,26,25,23,26,26,24,26,26,23,26,27,26,25,27,26,26,27,26,26,25,25,25,25,25,23,22,24,22,20,21,22,20,17,20,19,16,17,16,13,11,9,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,3,2,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,3,4,4,3,4,3,3,3,3,3,3,3,3,3,3,4,3,4,5,6,7,8,9,11,11,11,12,13,13,13,15,15,16,16,17,18,20,20,21,22,22,22,23,21,21,22,22,22,22,22,23,22,22,22,23,24,26,24,24,24,24,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,25,25,25,24,25,25,24,25,24,23,24,23,23,22,22,21,20,18,20,17,17,15,13,13,11,9,7,6,5,4,4,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,6,6,6,6,6,6,7,7,7,7,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,6,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,3,3,5,5,6,5,3,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,3,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,8,9,9,9,10,11,12,14,15,16,18,17,18,16,18,16,17,20,19,21,20,20,23,23,22,22,23,22,23,23,22,23,21,22,21,21,20,22,22,22,22,23,24,23,24,22,20,22,23],[28,27,28,28,27,29,28,27,28,27,26,28,27,26,26,25,25,27,25,26,27,25,27,26,25,27,27,25,27,26,25,27,27,27,27,27,27,27,27,27,27,27,26,26,26,26,23,24,25,23,21,22,23,20,18,20,20,16,17,17,14,13,9,7,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,3,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,8,8,10,12,13,13,14,16,15,15,17,17,17,17,19,19,20,20,21,22,24,24,24,21,21,22,21,22,23,22,23,22,22,21,25,24,26,24,25,25,25,25,26,26,25,25,25,26,26,26,26,25,26,26,26,25,26,26,25,26,26,26,25,25,24,25,26,25,25,23,24,22,21,19,20,19,17,16,15,13,11,9,7,6,5,4,3,3,4,4,3,4,3,4,4,4,5,5,5,5,6,5,6,6,6,6,6,6,7,7,7,7,7,6,6,6,6,6,6,7,7,7,7,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,6,6,6,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,2,2,2,3,3,5,5,6,4,3,2,2,2,1,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,7,7,8,9,9,9,10,12,12,14,15,17,18,18,18,16,17,18,18,21,19,22,20,22,24,23,22,22,23,23,24,22,23,24,22,22,23,22,22,23,24,23,23,23,23,23,23,23,20,23,23],[28,28,28,28,28,29,27,27,28,27,26,27,26,26,26,26,26,27,26,26,27,26,26,26,26,26,26,26,27,26,26,27,26,28,27,27,26,27,27,27,27,27,26,26,26,25,23,23,23,22,22,21,21,19,18,20,18,17,17,17,14,12,9,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,1,1,2,2,1,2,2,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,5,6,7,9,9,11,13,13,12,14,15,15,15,17,17,16,17,19,20,20,20,21,21,23,23,24,21,21,22,21,21,23,22,23,22,22,22,25,23,26,25,25,25,26,26,26,25,25,25,25,25,26,26,26,26,26,26,27,25,26,26,25,25,25,26,25,25,24,24,25,24,24,23,24,24,22,21,21,19,17,17,15,14,11,9,7,5,4,4,4,3,4,3,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,7,6,7,6,7,7,7,6,6,6,5,6,7,6,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,5,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,3,6,5,7,4,3,2,2,1,1,2,2,1,2,2,2,2,2,2,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,4,5,6,6,8,9,9,9,10,11,12,14,16,17,19,20,19,17,18,19,19,22,19,22,21,22,24,24,22,22,24,24,24,23,23,24,22,23,25,22,21,24,25,24,24,24,23,24,24,23,21,24,25],[28,28,28,28,28,28,28,27,28,27,27,26,26,25,26,24,26,27,25,26,26,25,26,26,25,26,27,26,27,26,25,27,27,28,27,28,27,27,27,27,28,27,27,26,26,25,23,23,24,22,22,21,22,20,19,20,18,17,17,16,13,11,8,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,2,2,1,1,2,1,1,1,2,2,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,5,7,7,8,11,12,12,11,13,14,13,14,16,17,16,18,18,20,22,19,21,22,22,24,23,22,22,22,21,22,22,22,22,22,22,21,24,23,25,24,24,24,24,25,26,25,25,24,25,25,25,26,25,25,26,25,27,25,26,25,26,25,25,26,24,25,24,24,24,24,23,23,24,22,21,20,20,18,17,16,15,14,12,9,7,6,5,4,3,3,4,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,6,6,6,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,5,5,6,4,3,2,2,1,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,3,3,3,3,2,3,3,4,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,3,4,3,3,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,3,3,3,4,5,6,6,7,9,9,9,10,12,13,14,17,17,19,19,18,17,19,18,18,20,19,20,22,20,23,23,23,23,23,23,24,23,23,25,24,23,24,22,22,24,24,23,24,24,23,24,24,23,21,24,24],[28,27,27,27,27,28,27,27,27,26,26,26,26,24,25,23,25,26,24,25,25,23,26,25,24,26,26,25,27,26,25,26,26,27,26,27,26,26,26,26,26,26,26,25,25,24,23,23,23,22,21,21,21,19,17,18,17,16,16,15,13,11,8,6,5,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,4,5,6,7,8,9,11,12,11,13,14,14,13,14,16,16,16,17,17,19,19,20,20,21,22,22,20,21,23,21,20,21,21,23,21,22,21,24,23,25,24,24,24,24,25,25,24,25,24,24,24,24,25,25,25,25,25,26,24,25,25,25,25,24,25,24,24,24,23,24,23,22,21,21,22,20,19,19,17,16,15,13,13,10,9,7,5,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,6,6,6,6,6,7,6,6,5,5,5,5,5,6,6,7,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,2,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,5,5,5,4,3,2,2,1,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,3,3,4,4,3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,3,2,2,3,3,3,2,3,4,5,5,6,7,9,9,9,10,11,12,14,15,16,17,17,18,16,16,18,18,20,19,21,19,21,23,23,22,22,24,22,22,21,22,23,20,21,22,20,21,22,22,22,23,22,21,23,23,23,20,22,22],[28,27,27,28,28,28,27,27,28,26,26,27,26,26,26,25,25,26,25,25,26,25,26,26,26,26,26,26,26,26,25,26,26,27,26,26,26,27,27,26,26,26,25,26,25,25,24,22,23,22,21,21,20,19,18,19,18,16,16,16,14,12,9,6,5,5,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,5,7,9,9,11,13,13,12,13,14,14,15,15,16,16,16,17,18,19,18,20,21,21,22,22,21,20,22,20,21,21,21,23,21,21,22,24,23,26,24,24,24,25,25,26,25,25,25,25,25,26,26,26,26,25,25,26,25,25,25,25,26,25,26,25,25,24,24,25,24,24,22,24,23,21,20,20,19,16,15,14,12,10,9,7,6,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,6,6,7,6,6,5,6,5,6,6,6,7,6,6,6,6,6,5,5,5,5,4,5,4,4,4,4,4,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,2,2,2,2,3,5,6,6,4,3,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,4,4,3,3,3,3,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,2,3,2,2,3,3,3,2,3,4,5,6,6,7,9,9,9,10,11,12,15,15,17,18,18,18,17,17,18,19,20,19,22,20,22,24,24,23,23,24,23,22,22,23,24,21,22,23,21,21,23,23,22,23,22,23,22,23,22,20,23,24],[28,28,28,28,28,28,27,27,28,26,27,27,26,26,26,25,26,27,26,26,27,26,26,26,26,27,27,26,27,26,26,26,27,27,27,27,27,27,27,26,27,26,26,26,26,25,23,23,23,22,22,21,21,19,18,20,18,17,18,17,14,11,9,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,2,2,1,1,2,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,5,6,8,9,9,12,14,13,12,14,14,15,15,17,17,17,18,19,19,21,20,21,23,23,22,23,22,21,22,20,21,22,21,23,22,22,21,24,23,27,24,25,24,25,25,25,25,25,25,25,25,24,25,25,25,26,25,27,26,26,26,26,25,25,26,25,25,25,25,25,24,23,23,24,23,22,20,20,19,17,16,15,13,11,9,8,6,5,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,6,7,6,6,6,5,6,5,5,6,6,7,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,2,2,2,3,2,2,2,3,3,2,3,3,3,3,4,4,4,5,5,5,5,4,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,5,6,6,4,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,3,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,2,3,3,2,2,2,2,2,2,3,2,2,2,3,2,2,3,4,5,5,6,7,9,9,9,10,12,12,14,15,16,18,18,17,16,17,18,18,21,19,21,21,21,24,24,23,22,24,22,23,23,24,23,22,22,24,22,22,24,24,23,24,21,23,23,24,23,21,23,25],[28,28,28,28,28,28,27,27,26,26,27,26,26,24,25,23,25,26,24,25,26,25,25,26,25,26,26,26,27,26,25,26,26,26,26,27,26,27,27,27,26,26,26,26,25,25,24,23,23,22,22,22,21,20,18,20,19,17,17,17,13,11,8,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,7,8,8,11,12,13,11,13,14,13,14,15,16,17,18,18,19,21,20,20,21,22,23,23,21,21,22,20,21,20,21,22,22,21,21,23,23,26,24,23,23,24,24,24,24,24,24,25,24,24,24,24,24,24,25,26,24,25,25,25,25,24,25,24,24,24,24,25,23,22,22,22,22,20,19,18,18,17,15,14,13,11,9,7,5,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,4,5,6,6,6,6,5,5,6,5,5,5,5,4,4,5,4,3,4,4,3,3,3,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,4,4,4,5,5,4,4,4,3,3,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,3,3,6,5,6,4,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,1,2,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,6,7,9,9,10,10,12,13,14,16,16,18,19,17,17,18,17,19,21,18,21,21,21,23,23,21,22,23,22,23,23,23,22,22,23,22,21,22,22,23,21,22,22,21,23,24,21,20,23,23],[28,27,28,28,28,28,27,27,27,27,26,26,26,25,26,24,26,27,25,26,26,25,26,27,25,27,27,26,27,26,25,27,27,27,27,27,27,27,27,27,27,26,26,26,25,25,24,23,24,22,22,22,22,20,19,20,18,17,17,17,14,11,9,6,5,5,3,3,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,3,3,3,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,2,2,3,2,2,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,6,7,8,9,10,13,13,12,13,14,14,14,16,16,17,18,18,20,20,20,22,22,23,23,23,22,22,23,21,21,23,22,25,22,23,23,25,25,26,25,25,26,26,25,26,26,26,26,26,26,25,26,25,26,26,26,27,26,27,26,26,26,26,26,25,26,25,25,25,23,24,23,24,23,21,19,20,19,17,15,13,12,10,9,7,6,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,6,6,6,6,6,6,6,6,7,7,6,6,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,5,5,5,5,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,2,3,5,5,6,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,3,4,4,3,3,4,4,3,4,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,3,4,4,3,4,3,4,3,3,3,3,2,2,2,3,2,2,2,2,2,2,3,2,2,3,3,2,2,3,4,5,6,6,7,9,9,9,10,12,12,14,15,16,17,18,18,17,16,18,20,20,19,21,20,21,23,23,22,22,23,22,23,22,22,23,21,22,22,21,22,22,22,23,22,21,21,22,24,22,21,23,23],[28,27,28,28,28,28,28,27,28,26,26,27,26,26,26,25,26,27,26,26,26,26,26,26,26,27,27,26,28,26,26,27,27,28,27,27,27,27,27,27,27,26,26,26,26,25,24,23,24,23,22,22,22,20,18,20,19,17,17,17,14,12,9,7,6,4,3,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,6,7,9,10,11,13,14,12,13,14,14,15,16,17,17,18,18,19,21,21,21,21,23,22,23,22,20,21,21,20,22,22,24,21,23,22,24,24,26,24,25,26,26,26,26,26,26,26,26,27,26,26,26,26,26,26,26,26,26,26,25,26,25,26,25,26,25,25,25,24,23,23,23,23,22,20,20,20,18,15,14,12,10,8,7,6,5,4,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,6,6,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,4,4,4,4,3,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,4,4,4,3,3,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,2,1,2,2,3,3,3,5,5,6,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,2,3,3,3,3,3,4,4,3,4,3,4,3,3,3,4,4,3,4,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,3,3,3,3,3,4,4,4,3,4,4,3,3,3,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,4,6,5,7,8,9,8,9,11,12,14,15,15,18,18,17,16,16,18,18,20,19,22,20,21,23,24,23,22,23,22,23,22,22,24,21,22,24,22,22,23,22,23,22,21,21,22,24,23,19,22,23],[28,28,28,28,28,27,27,27,26,26,26,26,26,24,25,24,25,26,25,25,26,26,25,26,26,25,26,26,26,26,25,25,26,26,26,26,26,26,26,26,25,25,25,25,24,24,23,22,23,22,22,21,21,20,18,19,18,17,17,16,14,11,9,6,5,4,3,3,3,2,2,2,1,1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,3,2,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,7,8,8,11,12,13,12,13,14,14,14,16,16,17,18,18,20,21,20,21,21,22,22,22,21,20,21,20,21,21,21,22,21,21,21,24,24,26,23,23,24,25,24,24,24,24,24,24,24,24,25,24,25,25,25,25,25,25,24,25,25,24,25,24,24,24,24,25,24,23,23,24,22,21,20,19,18,17,16,14,12,10,9,7,5,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,6,6,6,6,6,6,6,5,5,5,4,5,4,5,6,5,6,6,5,6,5,5,5,5,5,4,4,4,4,3,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,4,4,4,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,3,3,5,5,7,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,7,8,9,9,9,13,12,14,15,16,18,18,16,15,17,18,18,20,18,20,20,20,23,23,23,21,23,22,22,22,23,22,21,22,23,20,21,22,22,23,22,21,21,21,23,21,20,23,24],[29,28,28,28,28,28,27,28,27,27,27,26,27,24,25,24,26,26,25,26,27,26,26,27,26,27,27,26,27,26,25,26,27,26,26,27,26,26,27,26,26,26,25,25,25,25,23,22,23,22,21,21,21,20,18,19,18,16,16,15,13,10,8,6,5,4,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,3,2,3,3,3,3,3,3,5,7,7,8,10,11,13,11,12,13,13,13,14,15,17,17,17,19,20,20,20,21,21,22,23,21,21,22,20,20,21,20,23,21,22,22,24,25,27,24,25,25,24,25,24,25,25,25,25,25,24,25,25,25,25,25,26,25,26,25,25,25,24,25,24,24,25,24,25,23,23,23,23,22,21,18,19,18,17,15,13,12,10,8,7,5,4,3,3,2,3,3,2,3,3,3,3,3,3,4,3,3,4,4,4,5,5,5,5,5,6,6,6,5,5,5,4,4,4,5,5,5,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,3,3,2,2,2,2,1,1,1,2,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,3,3,5,5,6,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,3,3,3,3,3,4,4,3,4,3,4,3,3,3,4,4,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,7,8,9,10,10,13,13,14,16,17,18,18,17,17,18,17,19,20,19,22,20,22,24,23,23,22,23,22,23,23,21,23,22,23,22,21,21,21,20,22,22,22,21,22,23,21,21,22,22],[28,28,28,28,28,28,27,27,28,26,26,26,26,25,26,26,26,27,26,26,28,27,27,27,27,27,27,27,28,27,27,27,27,28,27,27,27,27,27,27,27,26,26,26,25,25,25,23,24,23,22,22,21,20,19,19,18,18,17,16,13,11,8,6,5,4,3,3,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,2,2,2,2,3,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,3,2,3,3,3,3,4,4,5,6,8,8,11,11,12,11,12,14,13,14,15,15,16,17,18,17,19,20,20,21,22,22,23,22,22,23,20,20,22,22,24,22,22,23,25,25,27,26,25,26,26,26,26,26,26,26,26,27,26,27,26,26,26,26,27,26,27,26,25,26,25,26,26,26,25,25,25,25,23,24,24,23,21,20,19,19,17,14,13,11,10,8,6,5,4,3,3,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,5,5,5,4,4,4,4,5,5,6,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,3,3,3,2,2,2,2,1,1,1,2,1,1,2,2,1,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,2,1,2,2,3,2,3,4,4,5,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,3,3,3,3,3,3,4,4,3,3,3,4,3,3,3,3,4,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,7,8,8,8,9,12,12,15,17,16,18,19,18,16,16,18,20,21,20,21,21,21,23,23,23,23,23,22,23,23,22,22,20,22,22,20,21,23,21,23,22,22,22,22,23,23,20,22,22],[27,27,28,27,27,28,27,27,28,26,26,26,26,25,26,25,25,27,26,26,27,27,26,27,27,26,26,27,27,26,26,27,27,27,26,27,26,26,27,26,27,26,25,26,25,25,25,23,23,23,22,22,21,20,19,20,19,18,17,17,14,12,8,6,5,4,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,5,5,5,4,4,3,3,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,4,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,3,2,3,3,3,2,2,2,3,2,2,2,3,2,2,3,2,2,3,3,3,4,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,4,6,7,9,9,11,12,14,12,13,14,14,14,16,17,18,17,19,19,20,20,21,21,23,22,23,22,21,23,21,20,22,22,23,22,22,23,25,24,26,25,25,26,26,26,26,25,25,25,25,25,26,26,26,26,26,26,26,26,26,25,26,25,25,26,25,25,25,24,26,24,24,23,24,24,22,21,20,20,18,16,14,12,10,9,7,5,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,6,6,6,6,6,5,5,5,4,4,4,5,5,5,6,6,5,5,6,5,5,4,5,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,1,2,2,1,1,2,1,1,1,2,1,1,2,2,2,2,2,3,3,3,4,4,5,4,3,2,2,2,2,2,2,2,3,3,3,4,3,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,4,4,4,3,3,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,7,8,8,8,9,12,12,15,16,16,18,19,17,16,16,19,18,21,18,21,20,21,23,24,23,21,22,23,23,22,22,22,20,21,23,20,21,22,22,23,22,21,22,21,23,21,20,22,22],[28,28,28,28,28,28,27,28,26,27,27,25,26,25,26,24,26,27,25,25,26,25,25,27,26,26,26,26,26,26,26,25,26,26,25,26,26,26,26,25,26,26,25,25,25,24,23,22,22,23,21,21,21,19,17,19,18,16,17,17,14,10,8,6,5,4,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,3,3,3,3,3,4,4,5,7,8,8,10,12,13,12,12,15,14,14,16,17,17,18,19,20,21,21,21,21,22,22,23,21,20,22,20,20,21,21,22,20,22,21,24,24,26,24,24,24,25,25,24,24,24,24,24,25,25,25,25,25,25,25,26,25,25,25,25,25,24,25,24,24,25,24,24,24,23,23,23,22,21,19,19,18,16,15,13,12,10,9,7,5,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,5,5,5,6,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,4,5,5,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,4,4,3,3,3,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,5,5,6,7,8,9,9,9,14,12,14,17,17,18,18,18,17,17,18,19,20,18,21,21,21,23,23,23,21,22,22,23,22,21,23,21,22,22,21,22,22,21,22,21,21,20,22,23,20,20,22,22],[28,28,28,28,28,27,27,27,26,26,26,26,26,24,26,24,26,27,25,25,27,26,25,27,26,26,27,27,27,26,26,26,27,26,26,26,26,26,26,26,26,26,25,25,25,25,24,22,23,22,21,21,21,19,18,19,18,17,16,16,13,10,8,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,4,4,3,3,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,3,3,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,2,3,3,3,3,3,4,5,7,7,7,10,12,13,11,12,13,13,13,15,15,17,17,17,18,20,20,20,21,22,22,23,22,21,22,21,19,20,21,22,21,21,22,24,25,25,25,25,26,26,26,26,25,26,26,25,26,25,26,25,25,26,25,26,25,26,26,25,25,24,26,25,25,25,24,25,24,23,23,23,22,21,20,19,17,17,15,12,11,9,8,6,5,4,3,3,2,2,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,3,4,4,4,5,5,4,5,5,5,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,3,3,3,4,5,5,3,3,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,7,8,8,9,9,13,12,14,16,16,18,18,18,16,16,18,18,19,19,21,19,20,23,22,22,21,22,21,23,22,20,21,20,21,21,19,21,22,20,21,21,21,19,20,22,19,20,22,20],[27,26,27,27,27,27,26,27,27,25,25,26,25,24,24,25,24,26,25,24,26,26,25,26,26,26,25,26,25,26,25,26,26,26,25,26,26,25,25,25,25,24,24,25,24,23,23,22,22,22,22,21,20,19,19,19,18,17,16,16,13,11,8,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,3,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,4,3,3,3,4,3,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,3,3,3,3,3,4,3,4,5,7,8,8,10,12,12,11,12,13,13,13,15,15,15,15,16,17,19,19,20,21,21,21,22,21,20,21,20,18,20,21,22,20,20,20,23,23,24,24,24,25,25,25,26,25,25,25,24,25,25,26,25,26,26,26,26,25,25,24,25,24,24,25,24,24,24,23,24,23,22,23,23,24,21,21,21,19,17,14,13,12,11,8,7,5,4,3,3,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,5,5,5,5,4,4,4,4,4,5,4,5,5,5,5,5,5,4,5,4,4,4,3,3,3,3,3,3,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,3,3,3,2,2,2,1,1,1,1,1,1,1,2,2,1,2,2,2,1,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,3,3,3,4,4,5,4,3,2,2,2,2,3,3,2,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,4,4,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,6,7,7,7,8,10,10,12,13,15,17,17,18,15,16,16,17,18,17,19,18,20,22,22,22,21,21,21,22,20,21,21,19,20,21,18,20,22,20,20,19,20,20,20,20,19,17,21,18],[27,27,27,27,27,27,26,26,27,26,26,26,25,24,25,25,25,26,26,25,26,26,25,26,26,26,26,26,26,26,25,26,26,26,26,26,26,26,26,26,26,26,25,25,25,24,24,23,23,23,22,22,21,20,19,20,19,17,17,17,14,12,9,6,5,4,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,4,4,3,3,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,3,2,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,4,3,3,4,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,3,3,2,2,2,3,3,3,3,3,3,4,4,4,5,7,8,8,11,12,13,12,13,14,14,14,17,16,17,18,18,18,20,20,20,21,22,22,22,21,19,20,20,19,21,21,23,21,21,21,24,23,27,24,24,25,26,26,26,25,25,25,25,25,25,26,25,26,25,26,25,25,25,24,24,25,24,25,24,24,24,24,24,24,23,23,24,23,21,20,20,19,17,14,13,12,9,8,6,5,4,3,3,2,3,3,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,5,4,5,5,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,4,4,4,4,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,2,3,2,3,3,3,2,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,3,4,5,5,7,7,8,8,8,11,10,12,15,15,18,18,17,15,16,17,17,19,17,19,19,19,22,22,22,21,21,21,23,22,21,22,19,19,21,19,20,21,21,21,20,20,19,21,21,19,18,21,21],[28,28,28,28,28,28,27,27,27,26,27,26,26,25,26,25,25,27,25,25,26,26,25,26,26,25,26,27,26,26,25,25,26,26,25,26,25,25,26,25,26,25,24,24,24,24,23,22,23,23,21,21,21,19,17,19,17,16,16,16,13,11,8,6,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,4,3,3,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,4,3,3,4,4,3,3,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,3,3,3,3,3,4,4,4,5,7,7,8,10,12,13,12,12,13,14,14,15,17,17,17,17,18,20,19,20,21,21,21,21,20,19,21,20,19,20,20,21,20,21,21,23,23,26,24,24,24,25,25,26,25,25,24,24,25,25,24,25,25,26,26,26,25,26,24,25,24,24,25,24,24,24,23,23,22,21,22,23,23,20,20,19,18,16,15,13,12,10,8,7,5,4,4,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,4,4,4,4,3,4,4,4,5,5,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,4,4,4,4,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,4,4,5,5,4,3,2,3,2,2,3,3,2,3,3,4,4,4,4,4,4,4,4,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,3,4,5,6,8,8,8,10,9,13,11,14,16,16,17,19,17,17,17,18,17,20,17,20,21,20,23,22,22,22,21,21,22,22,20,21,20,21,20,19,21,21,20,20,20,21,19,21,21,19,19,20,20],[28,27,28,28,28,28,27,27,27,26,26,25,26,25,26,25,25,27,26,26,27,26,26,27,26,26,26,26,26,26,26,26,27,27,25,26,25,26,26,25,25,24,25,26,24,24,23,22,23,23,22,22,22,20,18,19,18,17,16,16,13,11,8,6,5,4,4,3,3,2,2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,2,3,3,3,3,3,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,2,3,3,4,4,4,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,2,2,2,3,3,3,3,3,3,4,4,4,5,7,8,8,10,12,12,11,12,15,14,14,15,16,16,16,17,19,20,19,20,20,21,21,22,21,20,22,21,20,21,21,23,21,21,22,24,24,26,25,24,25,26,26,27,26,26,26,26,27,26,27,27,27,26,27,27,26,26,26,26,24,25,26,25,26,25,24,25,24,23,24,24,22,21,20,20,19,17,15,13,12,10,8,7,5,4,3,3,2,3,3,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,3,4,4,4,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,4,4,4,4,4,3,3,2,2,2,2,1,1,1,1,1,1,1,2,1,1,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,3,3,3,2,3,3,3,3,3,4,4,4,4,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,5,5,5,5,4,5,5,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,3,4,5,5,6,7,7,8,8,10,11,12,14,15,18,17,17,14,17,17,15,18,15,18,18,19,21,21,20,20,21,19,22,20,20,20,19,20,20,16,18,20,19,18,19,18,18,20,21,17,17,20,17],[27,27,27,27,28,28,27,27,27,26,26,26,26,25,26,25,26,26,26,26,26,26,26,26,26,26,27,26,26,26,25,26,26,27,25,26,26,26,26,26,26,25,25,25,25,25,24,22,24,23,22,21,22,20,19,20,19,18,17,17,14,12,9,7,5,5,4,3,3,3,3,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,5,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,3,2,3,3,3,4,4,4,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,3,3,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,6,7,8,8,11,13,14,12,13,14,14,15,16,16,17,17,18,18,20,20,20,21,21,21,22,20,20,21,20,19,20,21,21,19,20,22,23,23,25,24,24,25,25,26,26,26,26,25,25,25,25,26,25,26,26,25,27,26,26,25,25,24,24,26,25,25,25,24,25,23,22,22,23,22,22,21,20,20,18,15,15,13,12,9,8,6,5,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,6,5,6,5,5,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,3,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,4,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,4,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,5,5,5,7,8,8,8,8,10,10,12,14,14,18,18,17,15,16,18,16,18,17,19,19,19,22,22,21,21,20,21,23,21,21,21,21,20,21,18,20,21,20,20,20,19,18,21,21,18,18,20,19],[28,28,28,28,28,28,27,28,27,26,26,26,26,25,26,26,26,27,26,26,27,26,26,26,26,26,26,27,26,26,25,26,26,26,25,26,25,25,26,25,26,25,24,25,25,24,24,22,23,23,22,22,22,21,20,20,19,20,18,18,15,13,10,8,6,5,4,4,4,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,6,5,6,6,5,5,5,4,5,5,5,4,5,5,4,4,4,5,4,4,5,4,4,5,4,4,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,4,5,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,4,3,3,3,4,3,4,4,5,5,5,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,4,4,4,3,3,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,5,5,6,8,9,11,12,13,14,13,14,15,15,16,18,18,18,18,20,19,21,21,22,21,23,22,22,21,20,22,21,19,21,21,22,20,21,21,24,24,26,24,24,25,26,25,25,25,26,25,25,26,25,26,26,26,26,25,26,26,26,25,25,24,24,25,25,25,25,24,25,23,23,22,24,23,21,21,20,18,18,15,14,13,10,10,7,6,5,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,4,4,4,5,5,6,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,2,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,3,3,4,4,6,4,4,4,3,3,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,4,4,6,6,6,5,4,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,6,5,6,5,5,6,5,5,5,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,4,4,5,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,4,5,6,7,8,9,10,11,10,13,12,15,17,18,19,20,18,17,18,20,18,20,19,21,22,20,22,23,23,22,21,23,24,22,20,23,21,21,22,20,21,21,22,21,22,21,20,21,22,19,19,22,21],[28,28,28,28,28,28,27,27,28,26,26,26,26,25,25,26,24,27,26,25,27,26,26,27,26,26,27,27,26,26,25,26,27,27,25,26,26,25,26,25,26,25,24,25,25,24,24,22,24,22,22,21,21,20,18,20,18,19,18,17,14,13,10,7,6,5,4,4,4,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,7,8,8,11,12,13,12,13,14,14,14,15,15,16,17,17,18,21,19,19,21,22,21,22,21,18,20,20,20,20,20,22,20,21,21,23,24,27,25,24,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,24,25,25,24,25,25,25,25,24,24,23,22,22,23,22,21,21,20,18,18,15,14,13,10,9,7,5,5,4,3,3,3,3,2,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,3,3,4,4,4,4,4,3,3,2,2,2,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,5,5,5,4,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,3,4,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,1,1,1,2,1,1,2,2,1,1,2,3,4,6,6,7,9,10,10,9,11,12,12,15,15,18,17,16,15,17,18,15,19,17,21,20,21,23,22,22,21,20,21,23,22,21,21,20,21,21,19,20,20,20,19,20,20,20,22,22,19,16,20,19],[27,27,27,27,28,27,26,27,26,25,26,25,26,24,25,25,25,26,25,25,26,25,25,26,26,26,27,27,26,26,26,26,27,27,26,27,26,26,26,26,26,25,25,25,25,25,24,22,23,22,23,21,21,20,19,19,18,18,16,17,14,13,10,7,6,5,4,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,7,7,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,5,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,4,3,3,4,3,3,3,4,4,5,5,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,4,4,3,3,3,2,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,6,7,8,9,11,12,13,12,13,14,13,14,16,17,16,17,18,19,21,20,21,21,22,23,23,21,19,21,19,20,20,21,23,20,22,22,24,25,27,25,26,27,27,27,27,27,27,26,27,27,27,27,27,27,26,27,27,26,27,26,26,25,25,26,25,26,26,24,26,24,23,23,24,23,21,21,21,18,18,15,14,13,10,9,7,6,5,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,4,4,4,4,5,5,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,2,1,2,1,1,1,2,2,2,2,2,2,2,2,2,3,3,5,5,5,5,4,3,3,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,5,6,5,4,4,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,5,4,4,4,4,4,5,5,5,5,5,5,6,6,5,6,6,6,6,5,5,6,5,5,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,3,3,3,3,3,3,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,2,2,2,4,5,6,6,8,9,9,10,9,11,12,14,16,17,19,19,17,16,19,19,17,21,17,21,20,20,23,23,20,21,21,22,24,21,21,21,22,21,20,19,19,21,21,19,22,20,19,21,22,18,18,21,19],[28,29,28,28,29,28,28,28,27,27,26,26,26,25,26,25,25,26,25,25,26,26,25,26,26,26,26,26,27,26,26,26,27,27,26,26,25,26,26,26,26,25,25,25,25,25,24,22,23,23,22,21,21,20,17,18,17,17,16,16,13,11,9,7,6,5,4,4,4,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,6,6,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,5,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,3,3,3,4,4,4,5,6,7,8,8,11,11,12,11,12,12,14,14,14,16,15,16,17,18,20,19,20,20,21,21,22,20,18,20,20,19,19,20,23,20,22,21,23,25,27,24,25,26,27,26,26,26,26,26,26,26,26,27,26,26,26,26,26,26,26,25,25,25,25,25,25,25,25,25,25,23,22,22,23,22,20,20,19,17,18,15,14,13,10,9,7,5,4,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,4,4,5,4,3,3,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,3,4,6,6,7,9,9,10,9,12,11,14,14,15,18,18,17,16,17,18,16,21,17,21,20,21,24,24,22,21,21,22,24,22,22,20,21,22,22,18,20,22,23,21,22,21,22,22,24,20,19,22,21],[29,28,28,28,28,28,27,28,27,27,26,26,26,25,26,25,26,26,25,26,26,25,25,27,26,26,26,26,26,26,26,26,27,27,25,26,26,26,26,25,26,25,25,26,25,24,23,23,23,23,22,22,22,22,20,20,19,19,18,17,14,12,9,7,5,5,4,4,4,3,3,2,2,2,2,2,3,3,3,3,2,3,3,2,2,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,3,4,3,3,3,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,3,4,3,3,4,4,3,3,4,4,4,4,3,4,3,4,3,3,3,3,2,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,4,4,3,4,3,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,6,7,8,8,10,12,13,12,14,14,14,14,16,16,17,18,17,20,21,20,21,21,22,22,23,21,22,23,21,21,22,21,23,22,23,22,26,25,27,24,25,26,27,26,26,26,27,26,26,27,26,27,27,27,26,26,27,27,26,26,26,25,25,26,25,26,26,25,25,24,24,24,25,22,22,20,20,19,18,16,15,14,11,9,7,6,4,4,4,3,3,3,2,2,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,3,4,3,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,4,5,5,4,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,5,5,4,3,2,3,2,3,3,3,3,3,4,4,4,4,5,5,5,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,2,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,4,5,6,6,7,9,10,10,9,13,12,15,17,18,18,19,17,17,18,18,17,21,18,22,22,21,23,23,22,21,22,22,24,22,22,21,22,22,22,19,21,22,22,20,21,21,21,21,23,20,19,22,21],[27,28,28,28,28,28,27,27,27,26,26,27,26,25,26,24,26,27,26,26,26,26,26,27,26,26,26,27,27,26,26,26,27,27,26,26,27,26,26,26,26,25,25,25,25,24,23,23,23,22,22,21,22,20,18,20,18,18,17,16,13,11,9,7,5,5,4,3,3,3,3,2,2,2,2,2,3,3,3,3,2,3,3,2,2,3,3,3,3,3,4,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,4,4,3,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,7,7,10,12,12,10,12,14,13,14,15,16,15,16,17,19,21,20,20,20,21,22,22,20,20,22,21,20,20,20,23,22,22,23,25,25,27,25,25,26,26,27,27,27,26,27,26,26,27,26,26,26,26,27,27,26,27,26,26,27,25,26,26,26,26,24,25,24,22,23,24,23,22,21,20,19,18,16,14,12,10,9,7,5,5,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,2,2,1,2,2,2,2,2,3,3,4,5,5,5,4,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,1,1,2,1,1,2,2,2,1,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,2,3,2,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,3,3,3,3,3,4,4,3,3,3,3,4,4,4,4,4,5,4,5,5,5,5,5,5,5,4,5,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,3,5,5,6,7,9,9,9,9,12,13,13,16,16,20,20,18,17,19,19,18,21,18,21,21,20,23,24,22,22,22,22,24,22,22,22,21,21,22,19,22,21,22,20,21,21,21,21,22,20,19,21,20],[28,28,28,28,28,28,28,28,27,28,26,27,27,25,27,25,26,26,26,26,26,27,26,27,27,27,28,28,28,27,27,27,28,28,27,27,27,27,27,27,27,26,26,26,26,25,24,24,23,24,22,21,21,21,18,18,18,17,16,16,13,11,9,6,5,4,4,4,3,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,5,5,4,4,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,4,4,5,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,3,3,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,7,8,8,11,12,12,10,12,13,14,13,15,16,16,17,18,19,21,20,21,21,23,23,23,20,20,22,21,21,21,22,23,21,23,22,25,26,27,25,26,27,27,27,27,27,28,27,28,28,27,28,28,28,27,27,28,27,27,26,26,26,25,27,26,25,26,25,25,24,23,23,24,23,21,21,20,19,19,15,14,13,10,9,7,5,4,4,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,5,5,5,5,5,4,4,4,5,4,5,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,3,3,4,5,5,5,4,3,3,2,2,2,2,2,1,1,2,2,1,1,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,3,3,3,3,3,3,3,3,4,4,5,4,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,4,5,7,7,9,9,9,11,10,12,13,15,15,17,19,19,17,17,18,19,17,20,16,20,20,19,23,23,22,20,21,22,24,22,21,22,20,21,22,19,20,21,20,20,21,20,21,22,23,19,20,22,21],[27,28,27,28,28,28,28,28,26,26,26,25,26,24,26,24,26,26,25,26,26,26,26,27,26,26,26,27,26,26,26,26,27,27,26,26,26,26,26,26,26,26,26,26,25,25,24,22,23,23,22,21,20,20,18,18,18,17,16,16,13,11,9,6,5,5,4,4,3,3,3,2,2,2,2,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,4,3,3,4,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,2,2,3,3,2,3,3,3,4,3,3,3,4,3,3,3,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,4,4,4,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,6,8,8,8,10,11,12,11,12,13,14,13,14,16,16,16,16,19,20,18,19,20,21,21,22,20,19,20,20,20,20,20,23,20,21,21,24,25,27,24,25,26,25,25,26,26,25,25,25,25,26,26,26,26,25,26,26,26,26,25,25,25,25,25,24,25,25,24,24,23,23,23,23,22,21,20,20,19,17,16,15,14,11,9,7,6,5,4,4,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,5,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,2,2,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,3,4,4,5,5,5,4,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,4,5,5,3,3,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,2,3,3,2,2,3,3,3,3,3,3,3,4,3,3,3,3,4,4,4,4,4,5,5,5,5,4,5,5,5,5,4,5,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,4,5,6,7,8,10,10,10,10,13,13,15,16,16,17,18,18,17,18,18,16,20,17,21,19,21,23,24,21,21,22,21,22,21,22,22,21,22,22,20,20,21,22,22,21,21,21,22,23,22,19,21,23],[28,28,28,28,28,28,27,27,27,27,27,26,26,24,26,24,25,26,26,25,26,26,25,26,26,26,27,27,27,27,25,26,27,27,26,27,26,26,27,26,26,26,26,25,25,25,23,23,24,23,23,22,22,20,19,19,18,17,17,18,14,12,9,7,6,5,4,4,4,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,5,5,5,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,3,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,4,3,3,4,4,4,4,4,4,5,7,8,8,10,12,13,12,13,14,15,14,15,17,17,18,19,21,21,21,21,21,22,22,23,21,20,21,20,22,21,21,23,21,22,22,25,25,27,25,25,26,26,25,26,25,26,27,26,27,26,27,27,26,26,26,27,26,27,26,26,26,25,26,25,26,26,25,25,24,23,24,24,23,22,21,20,20,18,16,15,14,11,10,8,6,5,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,6,6,6,6,6,5,5,5,4,4,4,4,5,5,6,6,5,5,6,5,5,4,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,4,4,5,5,4,4,3,3,2,2,2,2,2,2,1,2,1,1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,4,4,4,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,1,2,2,2,2,2,4,5,6,7,8,9,10,10,10,12,14,14,16,15,18,20,17,17,18,19,19,21,19,21,22,21,24,24,22,22,23,23,24,23,23,23,24,22,23,21,23,24,22,22,23,22,22,23,24,22,21,24,23],[28,28,28,28,28,28,27,28,28,27,27,27,27,25,26,25,26,27,26,27,27,27,27,27,27,27,28,27,28,27,26,27,27,27,27,27,27,27,27,27,27,27,26,26,26,26,25,23,24,24,22,20,21,20,19,19,19,18,17,16,13,11,9,7,5,5,4,3,4,3,3,2,2,2,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,6,6,5,5,4,4,5,4,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,3,4,3,4,3,3,3,3,3,3,3,3,2,3,3,3,2,3,2,2,2,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,3,3,3,3,3,4,4,4,4,4,5,7,7,8,10,12,12,11,11,13,14,13,14,16,16,17,17,19,20,19,21,21,22,22,22,21,21,22,20,20,21,22,23,21,22,23,25,26,28,25,26,26,26,26,26,26,26,26,26,26,26,27,27,27,26,26,27,26,27,26,26,26,26,27,25,25,26,25,26,24,24,24,25,23,22,21,21,20,18,16,15,14,11,10,8,6,5,4,4,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,5,5,5,5,5,4,4,4,5,5,6,6,5,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,5,5,4,4,3,3,2,2,2,2,2,2,1,2,1,1,1,2,1,1,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,4,6,5,6,4,3,2,3,2,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,2,3,3,2,2,3,3,3,3,3,3,4,4,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,2,2,2,2,2,3,5,6,6,8,9,10,11,10,13,14,14,16,17,19,20,19,17,19,19,19,21,19,22,21,21,24,24,22,23,23,22,24,22,22,23,22,23,23,22,22,22,22,22,23,22,22,23,23,22,21,24,23],[28,28,27,28,28,27,28,27,26,27,25,25,27,22,27,22,26,25,25,27,25,26,27,27,25,26,27,26,27,26,25,27,27,27,26,26,26,26,27,26,26,26,26,25,24,24,24,23,23,23,22,20,20,20,18,18,17,17,16,15,13,11,9,7,6,5,5,4,4,4,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,5,6,7,7,6,5,5,5,6,5,5,5,5,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,5,4,4,5,4,4,4,4,4,4,5,4,4,5,5,4,4,4,5,5,5,5,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,4,4,3,4,4,4,5,5,5,6,8,8,9,10,11,12,11,12,13,14,14,15,16,16,16,16,19,21,19,20,21,22,22,22,20,20,22,20,20,21,22,23,21,22,23,25,25,27,25,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,26,26,26,26,25,25,26,25,25,26,24,26,25,23,23,23,23,22,21,20,19,18,16,16,14,12,10,8,7,5,4,4,3,4,4,3,3,3,3,4,3,4,4,4,4,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,4,4,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,5,5,5,5,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,4,6,5,6,4,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,4,4,4,5,4,5,5,5,6,6,6,6,5,5,5,6,6,5,5,5,5,5,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,3,3,4,4,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,4,4,3,3,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,5,7,7,9,10,11,10,10,13,14,15,15,17,18,19,17,17,18,19,19,24,18,22,21,21,24,24,21,22,24,23,22,23,23,21,21,22,22,21,21,23,23,22,23,22,22,22,24,21,21,24,23],[27,27,27,27,28,26,28,27,25,26,25,23,26,22,25,22,26,25,23,26,24,24,26,26,24,25,26,24,26,25,25,26,26,27,26,26,26,26,26,26,26,25,25,25,24,24,23,22,22,21,20,20,20,18,17,17,17,16,15,15,12,10,8,6,5,5,4,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,5,5,5,4,5,5,5,5,5,6,5,5,4,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,4,4,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,4,3,3,3,3,4,3,3,4,4,4,4,5,5,6,6,7,8,9,11,11,10,11,12,12,13,13,15,16,16,17,18,21,19,19,21,22,21,22,22,19,20,20,20,19,21,23,20,21,21,24,24,27,25,24,24,25,26,25,25,24,25,25,25,26,25,26,25,26,26,26,25,25,25,25,25,25,25,25,25,24,24,24,23,24,23,24,22,22,19,20,19,18,16,15,13,11,9,7,6,5,4,4,3,4,4,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,5,6,5,5,4,4,4,4,4,5,5,6,6,5,5,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,5,5,4,4,3,3,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,3,3,3,4,5,6,5,4,3,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,1,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,5,5,5,5,4,5,5,5,5,4,4,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,4,6,7,8,9,10,10,10,9,12,13,14,14,14,17,17,15,16,16,18,17,21,17,21,20,19,24,23,21,22,23,22,21,22,21,23,21,22,21,20,20,22,22,21,22,21,22,23,23,21,20,22,24],[28,28,28,28,28,28,28,27,27,27,27,26,26,25,26,25,26,27,25,27,26,26,27,27,26,27,27,25,27,27,25,26,27,27,27,27,26,27,27,27,27,26,26,26,26,26,25,23,24,23,22,21,21,19,18,19,18,17,17,16,13,10,8,6,5,4,4,3,3,3,3,2,2,2,2,2,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,5,5,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,5,4,4,4,4,3,3,4,4,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,4,4,4,5,6,7,7,9,11,12,10,11,13,12,12,14,15,15,15,18,19,20,21,21,22,23,23,24,23,22,23,21,22,22,23,25,22,23,23,26,26,28,27,27,26,26,26,27,26,27,26,27,27,26,27,27,27,27,26,28,27,27,27,26,26,26,27,26,26,26,26,26,24,23,24,24,22,22,19,20,19,18,16,15,14,11,9,8,6,5,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,5,5,5,5,4,4,5,5,5,6,6,5,5,5,5,4,5,5,4,4,4,4,4,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,3,3,4,6,6,6,4,3,2,2,2,2,3,3,3,3,4,4,4,3,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,2,3,2,3,3,4,4,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,5,6,6,7,9,10,10,9,12,13,15,16,17,18,19,17,17,18,20,19,22,20,23,21,22,25,24,23,23,24,23,23,24,24,24,22,23,25,22,22,23,23,24,23,22,24,23,25,23,22,24,25],[28,28,27,28,28,27,28,27,26,26,26,25,26,23,26,23,26,24,24,26,24,24,27,25,24,27,26,25,27,26,25,27,26,27,26,26,26,26,26,26,26,25,26,25,25,25,24,23,23,22,22,20,20,20,18,18,17,17,16,15,13,11,9,6,6,5,4,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,5,6,6,7,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,4,5,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,5,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,3,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,3,4,4,3,3,4,4,4,4,4,5,7,7,7,10,11,12,11,11,13,13,12,14,15,15,15,16,18,19,19,21,20,22,22,22,22,21,22,21,21,22,22,23,21,23,23,25,25,27,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,26,27,26,26,26,25,26,26,25,25,25,25,24,23,23,23,22,21,21,19,18,18,15,14,14,11,9,7,6,5,4,4,4,4,3,3,3,3,3,3,4,4,4,4,4,5,4,5,6,6,6,6,6,6,7,6,6,6,5,5,5,5,5,6,6,7,7,6,6,6,6,6,5,5,5,4,5,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,5,5,4,4,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,1,1,2,2,2,2,2,2,2,3,3,3,4,7,6,6,4,4,3,3,2,3,3,3,3,3,4,4,4,4,4,5,5,5,4,4,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,3,3,4,4,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,7,6,8,10,10,10,10,12,14,15,14,17,18,19,20,15,18,20,20,22,18,23,22,21,24,24,23,23,25,22,24,23,23,23,23,22,23,21,22,23,22,22,22,22,22,23,24,21,22,23,24],[28,27,27,27,27,26,28,27,24,26,24,22,25,20,25,22,25,24,22,25,23,24,26,25,24,25,25,25,26,24,24,26,27,27,26,27,25,26,26,26,26,25,25,26,25,25,24,22,23,22,21,19,20,20,18,18,18,17,15,15,13,11,9,7,6,6,5,5,4,4,4,3,3,3,3,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,6,5,5,5,6,6,6,6,7,7,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,3,3,4,4,3,4,4,5,5,5,5,6,8,8,9,11,11,13,11,11,12,13,12,13,15,16,15,16,18,19,18,20,22,22,21,23,21,21,22,21,20,20,22,23,20,20,22,24,25,27,25,25,25,25,26,25,25,25,25,26,25,26,26,26,26,26,26,26,25,26,26,26,25,25,26,24,25,25,24,25,24,24,24,23,22,21,20,21,19,18,16,16,14,12,10,8,7,6,5,4,4,4,4,3,4,3,4,3,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,6,6,6,5,5,5,5,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,3,3,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,4,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,7,6,6,5,3,3,3,3,3,3,4,4,4,5,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,6,6,6,5,6,6,5,5,5,5,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,3,3,3,4,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,3,3,4,4,4,3,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,4,4,3,4,3,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,5,6,8,8,10,11,11,11,11,13,15,16,16,17,18,19,17,16,18,18,18,23,18,23,23,19,25,23,23,24,24,23,23,24,23,22,23,24,24,21,22,23,25,22,24,23,22,25,25,22,23,24,24],[27,28,27,27,28,28,28,27,26,26,26,23,26,23,26,23,26,25,23,27,24,23,27,25,24,26,26,25,26,26,24,27,27,27,27,27,26,27,27,26,27,26,26,26,26,25,24,23,23,23,22,21,20,18,18,19,18,17,16,16,13,11,10,7,6,5,5,4,4,4,4,3,4,3,4,4,4,4,4,4,4,4,4,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,7,7,6,6,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,4,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,5,4,4,4,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,8,8,8,10,12,12,10,11,12,12,13,13,15,15,15,16,18,19,19,20,22,22,21,23,22,20,22,21,20,20,23,22,21,21,23,25,24,27,25,25,26,26,26,26,26,26,26,26,25,26,27,27,27,26,26,27,27,27,27,27,25,25,26,26,26,26,26,26,24,24,24,23,22,22,19,19,19,18,17,15,14,12,10,8,7,6,5,5,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,6,6,6,7,7,7,6,7,6,6,5,5,6,5,6,7,6,7,7,6,7,7,6,6,6,6,5,5,5,5,4,4,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,4,4,3,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,5,6,7,7,5,4,3,3,3,3,3,3,3,4,4,5,5,4,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,4,4,4,5,4,4,5,5,5,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,6,5,5,5,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,5,6,8,7,9,10,11,10,10,12,14,16,16,17,18,18,17,17,18,18,19,23,19,23,21,20,25,24,22,24,25,23,23,25,25,24,22,24,24,22,21,24,24,24,24,23,23,23,25,24,21,24,25],[28,28,27,27,28,27,28,27,26,26,26,23,26,22,26,23,27,25,23,26,24,22,26,25,23,26,26,24,26,26,24,26,27,28,26,27,26,27,26,26,27,25,25,26,25,24,24,21,23,22,21,20,20,20,17,18,18,17,16,15,13,11,9,6,5,5,4,4,4,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,6,6,5,6,6,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,6,7,8,10,11,12,11,10,12,11,13,14,15,14,15,16,19,19,20,21,20,23,22,22,22,21,22,21,19,21,21,22,21,20,22,23,24,26,25,25,24,25,26,25,25,25,25,26,25,26,26,26,26,26,27,26,26,27,25,25,23,25,26,25,25,24,23,25,22,22,22,22,21,20,17,19,18,17,15,14,14,11,10,8,7,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,6,6,6,5,6,6,7,6,7,7,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,3,3,3,4,6,6,6,5,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,4,5,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,3,2,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,2,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,5,6,8,7,9,10,10,11,10,13,13,15,18,17,18,19,18,16,18,18,19,22,20,21,23,21,24,23,24,24,24,21,24,23,23,24,23,23,24,21,22,24,25,23,24,23,24,23,25,23,23,24,26],[28,28,28,28,28,28,28,27,27,26,26,26,26,25,26,24,26,26,25,26,26,25,26,26,26,26,26,25,27,26,25,26,26,26,26,27,26,27,27,27,27,26,26,26,25,25,25,24,24,23,24,22,21,21,19,20,19,17,18,16,13,11,8,6,5,4,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,4,5,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,3,3,4,4,4,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,4,3,3,3,3,4,3,3,3,4,3,4,3,3,4,6,7,7,10,12,12,10,12,13,13,12,14,15,16,16,17,18,19,20,20,22,22,23,24,23,22,22,20,21,22,21,23,22,22,23,25,25,27,26,26,26,26,26,26,26,26,26,27,26,27,27,27,27,26,26,27,27,27,26,26,26,25,26,26,25,25,25,26,24,23,23,23,22,21,19,19,18,18,15,14,13,11,9,7,6,5,4,4,3,4,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,5,6,5,5,5,5,5,6,6,7,6,6,6,6,5,5,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,4,4,5,5,5,5,4,4,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,4,5,6,6,5,3,3,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,4,3,4,4,4,4,5,4,5,5,4,5,4,5,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,2,2,1,1,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,4,5,6,6,8,9,9,10,10,13,14,15,16,16,19,18,17,18,18,18,19,22,21,25,23,23,26,25,24,24,24,23,25,24,24,25,24,23,24,22,23,24,23,24,23,23,24,25,25,24,22,24,24],[29,28,28,28,28,28,28,27,27,27,26,26,26,25,26,25,26,26,25,27,24,25,26,26,26,27,26,26,27,26,25,26,26,27,27,27,27,27,27,27,27,27,26,27,26,26,25,24,24,23,23,22,21,21,20,19,18,17,17,16,13,12,8,6,5,4,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,4,3,3,3,4,4,5,5,7,9,11,12,11,10,12,12,11,12,14,15,15,16,19,20,20,22,23,23,24,24,24,22,22,22,20,21,23,24,23,23,23,26,26,27,26,27,26,26,27,27,27,27,27,27,27,28,28,27,28,28,28,28,27,28,27,27,26,27,27,27,26,25,25,26,24,24,24,23,23,21,20,20,19,18,16,14,14,10,10,7,6,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,6,6,5,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,4,4,5,5,5,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,2,2,3,3,4,5,6,6,4,4,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,2,2,2,2,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,4,5,6,5,8,8,9,9,10,12,13,15,17,17,20,20,20,17,19,20,19,23,21,23,23,22,25,24,25,24,24,23,25,25,24,25,24,24,24,22,22,24,24,23,23,24,22,25,25,23,22,25,25],[28,28,27,27,28,27,27,27,25,26,25,23,26,23,25,23,25,25,24,26,24,22,26,25,23,25,25,24,26,25,23,26,27,27,26,27,26,27,26,26,27,25,25,26,26,25,25,22,24,23,21,21,21,20,19,19,18,17,16,15,13,11,8,6,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,4,3,3,4,3,3,3,4,3,4,4,4,5,5,5,8,10,12,11,11,10,12,12,12,13,14,14,15,15,19,20,18,21,21,23,21,23,22,21,22,20,18,21,22,22,21,21,23,24,24,26,25,25,26,26,26,27,26,27,26,26,26,26,27,27,27,27,26,26,26,26,25,26,24,26,25,24,25,25,24,26,23,24,23,23,22,22,19,20,19,18,16,14,13,11,9,7,5,4,4,4,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,6,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,5,5,4,4,4,3,4,3,3,3,3,3,3,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,3,3,4,6,6,6,4,3,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,2,1,1,1,2,1,1,2,2,2,2,2,1,2,2,2,1,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,5,6,6,7,8,8,9,10,12,12,14,16,16,18,19,17,16,17,18,19,21,20,23,21,20,24,24,22,22,24,21,23,23,22,23,21,24,23,20,21,24,23,23,23,22,23,22,23,23,22,23,24],[28,28,28,27,27,28,28,27,27,26,26,25,26,25,26,24,26,25,25,26,25,24,26,25,24,26,26,24,26,26,24,27,27,27,26,27,26,27,27,26,27,26,26,26,26,25,25,23,24,22,23,22,22,21,18,20,18,17,17,17,14,11,9,6,5,4,3,3,3,2,2,2,2,2,2,2,2,3,3,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,3,4,3,3,3,3,3,3,3,3,3,3,4,3,4,4,6,7,8,9,12,12,11,12,13,12,12,13,13,13,15,15,17,19,18,20,21,23,22,23,23,23,22,22,21,21,23,24,22,22,23,26,25,27,25,26,26,26,26,26,26,27,26,27,27,27,27,27,27,27,26,28,27,27,26,27,25,26,26,26,26,25,25,25,24,23,23,23,22,22,19,19,19,18,16,15,14,11,9,7,6,5,4,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,5,5,6,5,6,5,6,5,6,5,5,5,5,6,6,6,6,6,5,5,6,6,5,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,2,2,3,3,2,3,3,2,3,3,3,3,3,4,4,5,5,5,5,5,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,2,2,2,3,3,3,5,6,6,5,3,2,2,2,2,3,3,3,3,3,3,4,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,2,2,1,1,2,2,1,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,2,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,5,6,6,8,9,8,9,10,14,14,15,18,17,20,20,19,17,19,19,20,22,20,24,22,22,25,25,24,24,25,23,24,24,24,23,23,25,25,21,22,25,24,24,24,24,25,24,26,24,22,24,26],[28,28,29,28,28,29,27,27,28,27,27,26,26,25,25,25,25,26,26,26,27,27,25,26,26,27,27,26,27,27,24,26,27,27,26,27,26,27,27,27,27,26,26,26,26,25,24,24,24,23,24,22,21,21,20,20,19,19,19,17,14,11,8,5,4,4,3,3,3,2,2,2,2,2,2,2,2,3,3,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,5,5,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,2,3,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,7,6,10,12,12,11,12,14,13,12,14,16,15,16,17,18,20,20,21,22,23,23,23,22,22,22,21,22,22,23,24,23,23,23,26,26,28,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,27,27,27,26,26,25,27,25,25,25,24,25,24,23,23,22,22,21,19,19,18,17,15,13,12,10,8,6,5,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,6,5,6,6,5,5,5,5,5,4,4,4,4,4,4,3,4,4,3,3,3,3,2,2,3,2,3,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,3,3,4,5,6,6,4,3,2,2,2,2,2,3,3,3,3,4,4,3,3,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,4,5,5,6,7,9,9,9,10,13,14,15,18,17,20,19,19,17,19,19,20,23,21,24,23,22,25,25,24,24,25,24,25,25,25,25,24,24,24,22,23,25,24,24,24,24,25,24,27,25,22,25,25],[28,29,29,28,28,28,28,27,27,27,26,26,27,25,26,25,26,26,25,26,25,26,26,25,25,27,26,25,27,26,25,27,27,28,26,28,26,27,27,26,27,27,26,27,26,26,25,22,24,23,22,21,22,22,18,20,20,19,18,17,14,11,8,5,4,4,3,3,3,2,3,2,2,2,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,4,3,4,4,3,4,4,3,3,3,3,3,3,3,4,3,3,3,5,4,5,5,7,9,12,12,10,9,11,13,11,13,14,14,15,15,18,19,20,22,22,22,23,24,24,23,24,22,20,21,23,24,21,23,25,26,27,28,27,27,27,27,27,27,27,27,27,27,27,27,28,27,28,27,27,27,28,27,27,27,25,26,26,26,26,26,25,26,23,23,24,23,22,22,19,21,18,18,16,14,13,10,8,7,6,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,4,5,4,5,6,5,5,5,4,4,3,3,3,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,4,6,6,6,5,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,4,4,4,4,4,4,5,5,5,5,4,5,4,4,4,4,4,4,5,4,4,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,2,2,3,3,2,2,2,2,2,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,5,6,6,7,9,9,9,10,13,14,16,17,17,19,19,19,17,18,19,20,23,21,23,22,22,26,25,23,24,26,23,24,25,24,24,23,25,24,22,22,25,24,24,24,23,24,23,26,23,21,23,24],[27,27,27,26,27,27,27,26,26,25,25,23,26,23,25,24,24,24,23,25,23,23,24,24,23,24,24,22,24,23,22,24,26,25,24,26,25,25,25,25,25,24,24,25,25,25,24,21,23,22,19,19,21,20,17,18,18,17,16,16,14,11,8,6,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,4,4,4,4,5,5,6,7,10,11,11,11,10,11,12,12,12,13,14,13,14,17,17,17,19,20,22,21,23,21,22,21,21,20,20,22,24,21,20,22,23,24,26,24,25,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,24,25,23,24,24,23,24,24,22,24,21,21,22,21,20,20,17,19,18,16,15,13,13,11,9,7,6,5,4,4,3,4,4,3,4,3,4,3,4,4,4,4,4,5,5,5,5,6,6,5,6,6,6,6,6,6,5,5,6,5,6,7,6,7,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,5,5,6,6,6,6,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,5,6,6,5,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,6,6,6,7,9,8,9,10,11,12,14,15,15,18,18,18,15,17,16,17,20,18,21,19,20,23,23,20,22,23,20,23,24,23,21,21,23,21,19,18,22,22,22,22,21,23,21,23,23,19,22,23],[27,28,28,28,28,28,28,28,28,27,27,26,27,25,26,25,26,26,25,25,25,25,25,25,24,26,26,25,26,25,23,26,26,27,26,26,25,26,26,26,26,26,25,26,26,25,23,23,23,22,22,21,20,20,18,20,18,17,17,16,15,12,9,6,5,4,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,6,5,5,5,6,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,5,4,4,5,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,5,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,3,4,4,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,4,3,4,4,5,6,8,7,11,12,12,11,12,13,13,12,14,14,13,14,17,17,17,19,20,20,23,21,23,22,22,22,21,20,22,22,24,21,22,23,26,25,27,25,25,25,26,25,26,25,25,25,26,26,26,26,26,26,26,26,27,26,27,26,25,25,26,25,25,25,24,24,25,22,22,22,21,21,20,18,19,18,16,15,14,12,10,9,7,6,5,4,4,3,4,4,3,4,4,4,4,4,4,5,4,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,5,6,6,6,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,4,3,3,3,4,3,4,4,4,4,4,5,5,6,6,6,6,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,5,6,6,5,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,1,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,2,2,2,2,2,1,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,4,3,3,4,4,3,3,3,4,4,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,4,4,3,4,5,6,7,7,8,9,9,10,10,12,13,15,17,17,20,20,19,18,19,18,19,22,19,23,23,23,24,26,24,23,24,24,24,25,25,24,23,25,25,22,22,25,25,25,25,23,24,24,26,25,22,24,25],[28,28,28,28,28,29,28,28,28,27,27,27,27,25,26,26,26,27,25,26,26,26,25,26,25,26,27,26,27,26,25,27,27,27,26,27,26,27,27,26,26,26,26,26,25,25,24,23,23,22,22,21,21,20,19,20,19,18,18,18,15,12,9,6,5,4,3,3,3,2,3,2,3,2,3,2,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,5,4,4,5,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,4,5,5,5,4,4,4,4,4,4,4,3,3,4,4,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,3,3,4,5,5,6,9,8,11,13,11,12,14,12,11,13,14,12,13,16,16,16,17,20,20,22,22,23,23,22,22,21,22,23,23,25,22,23,24,26,26,28,27,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,26,26,26,25,25,24,24,25,22,22,22,21,21,20,18,19,17,17,15,13,12,10,9,7,6,4,4,4,3,4,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,6,6,6,5,6,5,6,7,6,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,6,6,6,6,5,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,6,7,5,4,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,2,2,3,2,2,2,2,2,3,3,3,2,3,3,3,4,4,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,6,7,7,8,10,10,10,11,13,14,15,18,17,22,20,19,18,20,19,20,22,21,23,23,23,25,24,24,25,25,25,25,25,25,25,24,25,25,23,23,26,25,25,26,23,25,25,26,24,22,24,25],[29,29,28,28,28,29,28,28,28,27,26,26,27,25,27,25,26,26,24,26,25,24,26,25,23,26,26,24,27,25,23,27,27,27,26,27,26,27,26,26,26,25,25,25,24,25,23,22,21,22,20,20,21,21,19,19,19,18,17,17,16,12,10,6,6,5,4,5,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,9,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,7,6,6,6,6,7,7,7,6,6,6,6,6,6,6,5,6,6,5,6,6,5,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,4,5,4,4,5,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,4,5,5,6,6,5,5,5,4,4,4,4,4,4,3,4,4,3,3,4,4,4,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,3,4,4,3,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,5,5,5,6,6,8,8,10,12,12,11,13,13,12,13,14,15,14,16,18,19,19,21,21,24,22,23,21,21,22,21,19,21,22,22,21,22,22,25,25,27,25,26,25,25,26,25,25,25,25,25,25,25,26,27,26,26,26,26,26,27,25,25,24,25,25,24,25,24,23,26,22,22,24,21,20,21,19,20,17,17,15,14,13,11,10,8,7,6,5,5,4,5,5,4,4,4,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,8,7,8,7,7,7,7,7,7,7,8,7,8,9,7,7,7,7,6,7,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,5,4,4,4,5,4,5,5,5,5,5,6,6,7,7,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,3,3,3,4,6,6,6,6,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,5,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,1,1,1,1,1,1,0,1,2,2,2,2,2,2,2,2,3,3,3,4,4,5,4,4,5,5,5,5,6,6,6,6,6,6,6,5,5,5,6,5,5,5,5,6,5,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,4,5,5,4,4,4,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,6,7,8,8,9,10,10,10,11,13,14,15,17,18,20,19,20,18,19,19,19,22,20,21,22,21,24,24,22,24,25,24,26,26,25,25,23,25,23,21,21,24,25,23,23,22,22,24,25,23,21,24,25],[28,28,28,28,28,28,28,28,28,27,27,27,27,25,26,25,27,27,25,26,25,24,26,26,24,26,26,24,26,26,24,27,27,27,26,27,26,26,27,26,27,26,25,25,25,25,23,22,23,21,20,19,21,20,17,18,18,17,17,17,15,12,10,8,6,6,5,5,5,5,5,6,6,6,6,6,5,6,6,6,6,6,6,6,6,5,5,5,6,6,6,7,7,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,8,8,8,9,9,9,10,9,9,8,9,9,9,9,8,9,9,9,9,9,8,8,9,10,9,9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7,8,8,8,7,8,8,8,8,7,8,7,7,7,8,8,8,8,8,8,9,8,8,8,8,8,8,8,8,8,8,8,8,8,7,8,8,8,8,7,8,8,8,9,9,8,8,8,8,8,7,8,7,7,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,7,8,8,8,8,8,8,8,8,9,8,9,9,8,8,8,8,8,8,7,7,8,8,8,8,8,8,8,8,7,7,7,7,6,7,7,7,6,6,6,5,5,6,6,6,6,6,6,6,5,5,5,5,6,5,5,6,6,6,6,7,7,7,7,7,7,7,6,6,7,7,7,8,7,8,8,8,7,8,9,8,8,8,7,8,7,8,8,7,7,7,7,7,6,6,7,6,6,7,6,7,7,7,8,9,9,10,14,12,12,12,14,14,13,14,14,14,16,16,17,18,18,19,20,22,21,23,20,21,22,21,20,22,23,23,21,21,23,25,24,27,25,25,25,26,26,26,26,26,26,26,26,26,26,26,27,25,26,26,26,26,25,25,24,25,25,23,25,23,22,24,22,21,22,20,19,20,18,19,19,17,16,15,14,13,11,10,8,7,6,6,7,7,7,7,7,7,8,7,7,8,8,9,8,10,9,9,10,10,10,10,9,10,10,10,10,10,9,9,9,10,9,10,10,10,11,10,10,10,10,10,9,9,9,9,9,9,8,8,8,7,7,8,8,7,8,7,7,8,7,8,8,8,8,8,8,8,8,8,9,9,9,9,10,9,9,9,9,9,8,8,9,7,7,7,8,7,7,7,7,7,7,6,6,6,5,5,6,5,5,5,5,4,4,4,4,3,4,4,4,3,3,4,4,7,8,9,7,5,5,5,5,5,6,5,5,5,6,6,7,6,6,7,7,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,6,6,6,5,6,6,5,5,5,4,4,4,4,4,3,3,3,3,4,3,2,2,2,1,0,1,1,2,2,3,3,3,3,4,4,4,5,5,5,6,5,6,6,6,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,5,5,4,4,3,4,4,4,4,4,4,4,3,4,4,4,4,5,4,4,4,5,4,4,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,4,3,2,3,3,2,2,3,2,3,3,4,4,4,5,4,4,4,4,4,4,4,4,5,4,4,5,5,4,4,5,6,5,4,5,5,5,4,5,4,4,5,5,5,6,5,5,6,6,6,6,7,7,7,7,5,6,5,6,6,6,5,6,6,6,5,5,6,6,5,5,6,5,5,5,6,6,5,7,6,7,7,7,8,7,7,8,8,8,8,9,10,11,11,12,13,13,12,13,14,15,17,18,18,21,20,21,19,20,20,20,22,21,22,22,22,24,24,23,24,25,23,24,25,24,24,23,25,24,22,22,25,24,23,24,23,23,24,25,23,22,24,24],[28,28,28,28,28,28,28,27,28,27,27,27,27,26,26,26,26,27,26,25,26,25,25,26,25,25,26,25,26,26,24,26,27,27,26,28,27,27,27,27,27,27,26,26,25,24,23,23,23,23,22,20,21,20,18,19,19,18,18,18,16,14,10,7,5,5,4,3,3,3,3,3,3,4,4,4,3,4,4,4,4,4,4,4,4,5,4,4,4,5,5,5,6,6,6,6,7,6,7,7,8,8,8,8,8,8,8,9,8,9,9,8,8,8,7,8,8,8,8,8,8,8,7,8,9,8,8,8,8,7,8,8,7,7,8,8,8,8,7,7,7,7,7,7,7,6,7,7,6,6,7,6,6,6,7,6,6,7,6,6,6,5,5,6,6,5,6,6,6,6,7,6,6,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,6,7,7,7,7,7,7,7,7,7,6,6,6,6,6,5,5,5,5,6,6,6,6,6,6,5,6,6,5,5,6,6,5,5,6,5,4,5,6,5,5,5,6,6,6,7,7,7,7,7,6,7,7,6,6,7,7,6,7,7,6,6,6,7,7,8,7,7,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,4,5,4,4,5,5,4,4,5,5,4,5,5,6,5,4,4,4,5,5,5,5,6,6,5,6,6,6,7,6,6,7,6,6,6,6,6,5,5,5,5,4,5,4,4,5,5,5,5,5,6,6,7,8,11,13,13,12,12,15,15,13,13,14,15,14,16,17,18,20,20,21,23,23,24,23,22,22,22,21,22,22,23,22,21,22,25,25,27,25,25,25,26,26,27,26,26,26,26,26,26,26,26,26,26,26,27,26,26,26,25,24,26,26,25,26,23,23,25,23,22,22,21,20,20,18,19,18,17,16,15,14,12,11,9,7,6,6,5,5,6,6,6,6,6,6,7,7,7,7,8,7,8,8,9,8,8,9,9,10,10,9,9,9,9,8,8,8,9,8,9,9,10,10,8,9,9,8,8,8,8,8,8,8,7,7,7,7,6,6,6,6,6,6,6,6,6,6,7,6,7,7,7,7,7,7,7,8,8,9,9,9,8,8,8,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,4,3,3,3,3,4,4,6,6,7,6,5,4,5,4,4,4,5,4,5,5,5,6,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,4,3,3,3,3,3,4,4,3,3,3,4,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,6,6,5,5,6,5,4,4,5,4,4,4,4,4,4,3,3,3,3,2,2,2,2,1,1,0,1,1,2,2,1,2,2,2,3,3,3,4,4,4,4,5,5,4,5,5,6,5,6,6,5,6,5,6,5,5,5,5,5,5,6,5,4,3,3,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,4,4,4,4,3,3,3,3,2,2,3,2,2,2,2,2,2,3,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,4,4,4,5,4,4,4,4,3,4,4,4,4,5,4,4,4,5,5,6,6,6,6,5,5,5,6,5,6,5,6,6,5,5,5,6,5,5,6,6,6,5,6,6,6,6,6,7,7,6,7,7,7,6,7,7,7,7,8,8,10,10,11,12,12,12,13,14,15,16,18,18,20,19,20,19,20,19,20,22,20,22,22,21,24,25,23,23,25,24,24,24,24,25,23,24,23,22,23,25,24,23,24,22,23,24,25,23,21,23,24],[29,29,29,29,29,29,29,29,29,28,28,29,28,28,27,28,27,28,27,27,28,26,27,27,26,27,28,27,28,27,26,28,28,28,28,28,28,28,28,28,28,27,26,27,26,25,24,22,24,23,23,21,22,22,19,20,20,19,18,18,16,14,11,8,6,5,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,8,6,7,6,7,7,7,7,7,8,6,6,7,7,7,6,7,7,6,6,7,6,6,7,7,7,7,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,6,5,6,6,6,5,5,4,5,5,5,4,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,7,7,7,6,7,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,4,4,5,5,4,5,5,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,5,6,6,6,7,7,7,6,6,6,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,5,4,5,5,4,4,5,5,4,4,4,4,4,5,4,4,5,6,5,6,6,6,6,7,7,6,7,6,6,6,5,5,5,5,4,4,5,4,4,5,5,4,5,5,6,7,8,9,11,12,13,11,12,15,14,12,14,15,16,16,19,20,19,21,22,23,25,24,25,24,23,24,22,23,24,24,25,24,25,25,26,26,28,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,28,27,27,27,27,27,26,26,25,25,26,24,23,24,22,22,21,19,19,19,18,16,16,14,12,11,9,7,6,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,7,8,9,9,9,10,10,10,10,10,9,9,9,9,8,8,8,9,9,10,10,10,10,9,9,9,8,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,9,9,9,9,8,7,7,7,6,6,6,5,5,6,6,5,6,6,6,5,6,5,5,5,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,4,3,4,5,6,6,8,5,5,4,4,4,4,4,4,4,4,5,5,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,5,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,3,3,2,2,2,2,1,2,1,0,1,1,1,1,1,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,3,3,3,3,4,4,3,4,4,4,4,4,5,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,4,4,4,6,5,6,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,7,6,6,7,6,7,6,6,7,6,8,9,10,10,11,12,13,11,13,15,16,17,19,19,22,21,21,20,22,21,21,24,22,23,24,22,24,25,26,24,25,25,26,25,25,27,25,25,25,24,24,26,25,23,25,25,24,26,26,24,23,25,24],[28,28,28,28,28,29,28,28,28,27,27,28,27,27,26,27,27,28,27,27,27,25,27,26,25,27,27,26,27,27,25,27,27,28,27,27,27,28,27,27,27,26,26,26,25,25,24,23,23,22,23,22,21,21,19,19,19,19,17,16,14,12,9,6,6,4,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,4,5,5,5,5,6,6,6,6,6,7,6,7,7,7,7,7,6,6,6,6,6,7,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,6,6,6,6,6,5,5,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,5,5,6,5,5,6,6,5,5,6,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,4,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,4,5,4,4,5,5,6,6,6,6,6,6,6,5,6,6,6,5,6,6,5,5,5,5,5,6,6,6,6,6,6,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,4,4,5,5,4,4,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,7,8,7,11,12,11,9,11,14,12,11,13,13,13,15,17,17,18,19,21,21,23,23,24,22,22,23,21,21,23,22,24,22,22,23,26,25,27,26,26,26,26,26,27,27,26,26,27,27,27,27,27,27,27,27,27,27,27,25,26,24,26,26,23,25,23,22,26,22,21,23,22,21,21,19,18,18,17,16,15,13,12,10,8,7,6,5,5,4,5,5,6,6,6,6,6,6,6,7,6,7,8,7,7,8,9,8,8,9,9,8,9,8,9,8,8,8,8,8,9,9,9,9,9,9,8,8,8,7,7,7,7,7,7,6,6,6,6,5,6,5,5,5,5,5,5,6,5,5,6,6,6,6,7,6,6,7,7,8,8,8,7,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,3,3,4,5,6,6,6,5,4,4,3,4,4,4,4,4,4,5,5,4,4,5,5,4,4,4,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,5,5,5,5,5,5,4,4,5,4,3,3,4,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,0,1,1,1,1,1,2,2,2,3,3,3,3,3,4,4,3,4,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,3,3,4,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,5,5,5,5,5,4,4,5,5,5,5,5,5,4,5,4,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,8,9,9,10,11,11,11,12,14,15,16,17,19,21,20,20,19,20,19,20,22,22,22,23,22,24,26,25,23,25,24,25,25,24,26,25,24,24,24,24,24,24,24,24,24,24,24,26,23,23,24,25],[27,27,27,28,27,28,28,27,28,26,27,27,26,26,26,26,27,27,26,26,26,24,26,26,24,26,27,24,26,26,23,26,27,27,26,26,26,26,26,26,26,25,25,25,25,24,23,22,21,21,20,20,20,19,18,17,18,17,17,16,15,12,10,7,6,5,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,6,7,7,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,7,6,5,5,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,5,4,4,5,4,5,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,6,6,5,5,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,4,3,4,4,4,4,5,5,6,6,5,6,6,6,5,5,6,6,5,5,6,5,5,5,5,5,5,5,5,5,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,6,7,8,9,12,11,10,10,13,12,12,13,14,14,14,16,16,17,17,19,20,21,21,23,21,22,22,20,21,21,22,23,20,22,23,24,23,26,24,24,24,25,25,25,25,25,25,25,25,25,26,26,25,25,25,26,25,26,25,25,24,25,24,23,24,23,23,25,22,21,22,21,19,19,16,17,18,16,16,13,13,11,10,8,7,5,5,4,5,5,5,5,6,5,6,6,6,7,7,6,7,7,7,7,8,8,8,8,9,9,8,9,8,9,8,8,8,8,8,8,8,9,10,8,9,8,8,8,7,7,7,7,7,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,8,8,8,8,8,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,2,2,3,3,4,5,6,7,5,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,0,1,1,1,1,2,2,2,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,5,4,3,3,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,4,3,3,3,4,4,5,5,5,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,7,8,8,9,10,11,12,11,13,13,15,16,16,17,19,18,18,18,19,18,18,21,19,21,22,21,24,23,22,22,23,23,23,23,24,25,22,23,23,22,22,22,23,22,23,22,22,24,24,23,21,23,24],[28,28,28,28,28,29,28,28,28,27,28,28,28,27,27,26,27,27,26,27,27,25,27,27,25,27,27,26,27,27,25,28,28,28,27,28,27,28,27,27,28,27,26,26,26,25,24,23,23,23,23,22,21,21,19,19,19,19,18,17,15,13,10,7,6,5,3,3,2,2,2,2,2,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,5,5,5,4,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,4,4,3,3,3,4,4,4,4,4,4,3,3,3,4,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,5,5,5,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,4,4,5,4,4,4,3,4,4,3,3,4,3,4,4,5,5,7,8,8,10,13,13,12,12,14,14,13,14,15,15,14,17,18,19,19,21,22,24,23,25,22,22,24,23,22,23,24,25,23,24,24,26,26,27,26,26,26,27,26,27,27,27,27,27,27,27,27,27,26,26,27,27,27,27,27,26,26,26,26,25,26,25,25,26,23,22,22,23,21,21,19,20,19,18,17,15,14,12,10,8,6,5,4,4,4,4,4,4,5,4,5,5,5,5,6,6,6,7,7,7,7,7,8,7,8,8,8,8,8,8,7,7,7,7,7,8,8,8,8,8,7,7,7,7,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,7,7,7,7,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,4,5,6,7,5,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,0,1,1,1,1,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,4,5,6,7,9,9,10,11,11,10,12,13,14,16,18,17,20,20,19,18,20,20,19,23,20,22,23,21,24,24,25,24,25,24,26,25,25,26,24,25,25,23,23,25,25,24,26,24,24,25,26,24,22,24,24],[29,29,29,29,29,29,29,29,29,28,28,28,28,28,27,28,27,28,27,27,28,27,27,27,26,27,27,27,27,27,26,27,28,28,28,27,27,28,27,27,27,27,26,26,25,25,24,22,23,23,22,21,21,22,19,20,20,19,19,18,15,13,10,7,7,5,3,5,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,6,7,7,7,7,6,5,6,5,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,5,5,6,5,5,5,5,5,5,5,4,5,5,4,4,4,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,6,8,8,9,11,13,14,13,12,14,14,14,16,16,16,16,18,19,18,21,21,23,24,23,25,24,24,24,23,24,24,24,25,24,25,25,27,27,28,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,27,27,27,26,27,25,25,27,23,23,24,23,22,22,20,19,20,18,16,15,14,11,10,8,7,6,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,8,7,8,9,9,9,9,9,9,9,10,9,9,8,8,8,8,8,9,9,9,10,9,9,9,8,8,7,7,7,7,7,6,6,6,6,6,6,6,5,5,6,5,5,6,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,6,7,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,3,3,4,6,6,6,5,4,4,3,3,3,4,4,3,4,4,4,5,4,4,4,4,4,4,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,3,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,3,3,2,2,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,4,4,4,4,4,3,3,4,4,4,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,6,7,8,10,10,11,12,12,12,12,14,15,16,19,19,21,21,21,19,20,20,20,23,22,22,23,23,25,25,25,24,25,24,26,24,25,26,25,25,25,24,24,25,25,24,25,24,25,26,26,24,22,25,25],[28,27,28,28,28,28,28,28,28,27,27,27,27,27,27,27,27,28,27,28,27,26,27,27,26,27,27,27,28,27,26,28,28,28,27,28,27,27,28,27,28,27,26,26,27,25,24,23,24,23,22,23,22,20,21,21,19,19,19,18,15,13,10,7,6,5,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,5,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,5,6,6,6,5,6,5,5,5,5,5,5,5,5,4,4,5,5,5,5,5,5,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,5,6,5,6,5,6,5,5,5,6,5,6,6,6,7,7,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,5,5,4,4,5,4,4,5,5,6,6,6,5,6,6,6,5,6,6,5,5,6,6,5,5,5,5,5,5,6,6,7,6,6,5,5,5,4,5,5,4,4,5,5,4,4,5,4,4,5,5,5,5,4,4,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,3,4,4,4,4,5,5,6,8,9,9,11,13,13,12,12,15,13,14,16,15,15,17,18,18,18,18,20,21,23,21,24,22,23,22,21,21,22,23,24,22,22,24,26,25,27,25,26,25,27,26,27,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,26,25,26,26,24,26,25,24,26,23,21,24,23,20,21,19,19,19,16,16,15,14,12,11,8,7,6,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,8,8,9,8,9,9,10,9,10,9,10,8,8,8,8,8,9,9,10,10,10,9,8,8,8,8,8,7,8,7,7,6,6,6,6,6,6,5,5,5,5,5,5,5,5,6,6,6,6,6,7,6,7,8,8,8,9,9,8,8,7,7,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,4,3,3,3,3,3,3,3,2,3,3,3,4,6,6,7,6,5,4,4,3,4,4,4,3,4,4,5,4,4,4,4,4,4,3,3,3,3,2,3,2,2,2,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,5,5,4,5,4,4,4,5,4,4,4,4,3,3,4,4,3,3,3,3,3,2,2,3,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,2,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,5,4,3,3,2,1,2,2,2,1,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,4,4,4,3,4,4,3,4,4,3,4,4,4,3,4,4,4,5,5,5,5,5,4,4,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,8,10,10,12,12,12,12,13,14,16,17,17,17,20,18,20,19,19,19,20,21,20,21,23,23,23,24,24,22,23,22,24,24,24,26,24,23,25,23,23,23,23,24,23,23,23,24,25,25,21,24,25],[28,28,28,28,28,29,28,28,28,27,28,27,27,27,27,27,27,28,26,27,27,25,27,27,24,26,27,25,27,27,24,27,28,28,26,27,26,26,27,26,27,25,24,25,26,25,22,23,23,21,20,21,21,17,18,19,17,17,17,17,15,12,10,8,6,5,3,3,3,3,3,3,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,7,8,8,7,6,6,6,7,7,7,7,7,7,6,7,7,6,6,7,7,6,7,7,6,6,7,7,7,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,6,5,5,5,5,5,5,5,5,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,5,6,6,6,7,7,6,6,6,6,6,6,6,6,6,5,5,5,4,5,5,4,4,5,5,4,5,5,5,4,5,5,5,4,5,6,5,5,5,5,5,5,6,6,7,7,6,7,7,6,6,7,7,7,7,6,7,7,6,6,6,6,7,6,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,5,4,5,4,5,5,5,5,5,5,5,5,4,5,5,6,6,6,6,6,7,7,7,7,7,7,7,7,8,7,7,7,7,6,6,5,5,5,5,4,5,5,5,5,6,5,6,8,8,8,10,13,12,11,12,14,14,14,15,16,16,16,19,19,19,20,21,22,24,22,24,22,22,24,21,21,22,24,23,22,23,24,25,24,26,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,25,24,25,25,24,26,24,24,25,23,21,22,21,20,20,18,18,18,16,17,15,14,13,11,9,8,7,6,5,6,7,6,7,7,7,8,7,8,8,8,8,9,9,8,8,10,10,10,10,11,11,10,11,10,11,9,9,9,10,10,11,11,12,12,11,11,10,9,9,9,9,8,9,9,8,8,8,8,7,7,7,7,7,7,6,7,7,7,7,7,7,7,7,8,7,7,8,9,9,9,9,9,9,9,8,8,8,7,7,7,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,4,5,7,7,8,7,5,5,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,3,4,3,3,3,3,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,6,6,6,6,5,6,5,5,5,5,4,5,5,5,4,4,4,4,3,3,3,3,3,2,3,3,2,2,1,1,1,1,1,0,1,1,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,5,5,4,3,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,3,4,4,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,5,5,5,5,5,6,6,5,5,5,5,4,5,4,4,5,4,4,4,5,4,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,6,7,7,6,6,6,6,6,6,6,7,6,7,7,7,7,7,7,7,7,7,7,7,7,9,10,11,11,12,13,14,12,14,15,17,17,18,19,21,19,21,19,20,20,21,24,22,24,23,23,26,25,25,24,25,25,26,25,25,25,24,25,26,24,24,25,25,25,25,25,25,25,26,25,23,25,24],[28,28,28,29,28,29,28,28,28,28,27,27,27,27,27,27,27,28,27,27,26,26,26,26,25,26,27,26,27,27,25,27,28,28,27,27,27,27,27,26,27,26,26,26,26,25,23,23,24,22,22,21,21,18,19,19,17,17,17,18,15,13,11,8,6,6,5,5,5,6,5,6,6,7,6,6,5,5,4,4,5,4,3,4,4,4,3,3,4,4,4,5,4,5,5,5,6,6,6,7,7,7,7,8,8,8,8,9,8,9,9,8,7,8,7,8,8,8,8,9,8,7,8,9,7,8,8,8,7,8,8,8,8,8,9,9,8,8,7,7,7,7,7,7,7,6,7,7,6,6,7,7,6,6,6,6,5,6,6,6,6,5,7,6,6,6,7,6,7,7,7,7,7,7,7,8,8,8,8,8,8,8,7,8,8,8,8,8,8,7,7,7,8,8,7,8,8,8,8,8,7,7,8,8,7,6,6,6,6,6,5,6,6,5,6,7,5,6,6,6,6,7,7,7,6,7,8,7,6,7,7,6,7,7,8,8,8,8,8,8,8,8,9,8,9,8,8,9,8,8,8,8,8,8,8,8,9,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,5,5,6,6,5,6,7,8,7,8,8,8,8,7,9,8,7,8,8,8,8,9,8,8,8,8,9,9,9,10,9,10,9,10,9,9,9,8,8,9,7,7,7,7,7,6,7,7,7,7,7,8,8,10,10,11,13,12,12,14,15,14,15,15,17,17,17,18,19,21,20,23,23,24,23,25,22,23,24,23,22,23,23,24,23,23,24,25,24,27,25,26,26,26,26,27,27,27,27,27,27,27,27,27,26,27,26,27,27,27,27,26,25,26,26,25,25,25,24,27,23,22,24,23,20,21,19,20,20,18,17,17,16,15,14,11,10,8,8,7,9,9,8,9,9,9,10,10,10,10,10,10,10,11,10,11,12,13,11,11,13,13,12,13,12,12,11,11,11,12,11,13,13,14,14,13,12,12,11,11,11,10,10,11,11,10,10,10,10,9,9,10,9,9,10,9,9,10,10,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,10,10,10,9,9,9,9,8,8,9,9,9,9,9,8,8,8,7,8,7,6,7,7,7,7,6,6,6,7,6,6,5,5,4,4,4,5,6,8,8,8,8,7,6,6,6,5,5,5,4,5,5,5,5,5,5,6,5,5,4,4,4,4,3,4,3,2,2,3,3,2,3,3,3,4,5,5,6,7,6,6,6,7,7,8,8,8,7,7,8,8,8,8,8,9,8,9,8,9,7,8,8,8,7,7,7,7,7,8,6,7,6,6,6,5,5,5,4,4,4,4,3,3,3,2,2,3,1,1,0,1,2,2,3,4,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,7,7,5,4,3,3,2,3,3,3,4,6,5,4,6,6,5,5,6,7,6,6,8,8,7,7,8,7,8,7,8,7,7,7,6,6,6,6,5,5,5,4,5,4,4,4,4,4,3,3,4,4,5,5,5,4,6,6,5,5,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,5,7,6,6,7,7,6,6,7,8,7,9,9,9,9,8,8,8,8,8,8,8,8,9,9,8,7,10,9,8,8,8,9,8,8,9,9,9,9,9,9,9,9,10,10,9,9,9,10,9,10,11,12,12,15,15,16,15,16,16,19,19,20,20,22,21,22,22,22,21,22,24,24,24,25,25,25,26,27,25,26,25,27,26,25,28,25,26,26,26,25,25,25,25,25,26,25,26,26,26,24,25,25],[28,28,29,28,29,29,28,28,29,28,28,28,28,28,28,27,28,28,27,28,28,26,28,28,25,28,29,26,28,28,25,28,29,29,27,28,28,27,28,27,28,26,26,25,26,25,21,23,24,21,20,22,22,18,18,20,18,17,18,18,16,14,11,8,7,6,5,4,4,4,4,5,4,4,4,4,3,4,3,3,3,3,2,2,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,6,6,5,5,6,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,5,5,6,5,5,5,5,4,5,5,4,4,5,4,4,4,5,5,4,5,4,5,5,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,4,5,5,6,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,7,7,7,6,6,6,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,4,4,4,4,3,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,7,8,7,8,7,8,7,7,6,6,6,6,5,6,6,6,6,7,7,8,11,10,11,12,15,14,15,15,17,17,17,18,19,18,18,21,21,21,23,23,23,26,24,26,23,23,25,24,22,24,24,25,24,25,25,26,25,28,26,27,26,26,27,26,27,26,26,27,27,27,27,27,27,27,27,27,27,27,27,26,26,27,27,27,26,26,26,26,24,23,24,24,23,23,20,21,21,19,19,17,15,14,13,11,9,8,7,7,7,7,7,7,8,8,8,8,9,8,9,9,9,10,9,9,10,11,10,11,12,12,11,12,11,11,10,10,11,11,10,12,11,13,13,12,12,11,11,10,10,9,9,9,9,9,8,8,8,7,7,8,7,7,7,7,7,7,7,7,7,8,7,8,8,8,8,8,9,9,10,10,10,9,10,9,8,7,7,7,6,6,6,6,6,6,7,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,4,4,6,7,7,8,7,5,4,4,4,4,4,4,3,4,4,4,4,5,4,4,4,3,4,3,4,3,2,3,3,2,2,3,2,2,3,2,2,3,3,3,3,3,3,4,4,5,4,4,5,5,5,5,5,6,6,6,7,6,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,3,4,4,3,3,3,2,2,2,2,2,1,0,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,5,5,4,4,3,2,2,2,3,2,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,6,7,6,6,6,6,6,6,7,6,6,6,5,5,5,5,4,4,4,4,4,3,4,3,3,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,7,7,6,6,7,6,7,6,6,6,6,6,5,5,6,6,5,6,6,5,5,6,6,6,7,7,7,7,7,7,7,7,8,7,7,8,8,7,7,7,8,7,7,7,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,8,9,10,11,12,13,14,14,13,14,16,16,18,20,20,21,22,22,20,21,22,22,24,22,24,24,24,25,26,26,24,25,24,25,25,24,26,24,25,26,24,24,26,26,26,26,26,25,26,26,25,23,25,26],[29,29,29,29,29,30,29,29,29,29,28,29,29,28,28,29,28,29,28,29,29,28,28,28,27,28,28,27,29,27,27,28,28,29,28,28,28,28,28,28,28,27,26,26,26,25,23,23,25,22,22,22,23,19,20,21,19,17,19,19,17,15,12,10,8,7,6,6,5,5,5,5,5,5,5,4,4,5,3,3,4,4,3,3,4,3,3,2,4,4,4,4,5,4,4,5,5,5,5,6,7,6,6,7,7,7,7,8,8,8,7,7,6,6,5,6,7,7,8,7,7,7,7,7,7,8,8,8,7,8,8,7,8,7,8,8,8,8,7,7,7,7,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,5,5,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,7,8,7,7,7,8,7,7,6,6,6,6,6,6,5,6,6,6,6,6,6,6,5,6,6,5,6,6,6,5,5,6,6,5,6,6,6,7,7,7,7,7,7,7,7,8,7,7,7,8,8,7,7,7,7,7,7,8,8,8,8,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,5,6,5,5,6,5,5,5,5,5,5,5,5,6,5,6,6,7,6,6,7,6,7,7,7,7,8,7,7,8,8,8,8,9,8,9,9,9,9,9,9,9,8,9,8,8,7,8,7,7,7,7,7,7,7,8,8,9,11,11,12,13,14,15,15,17,17,17,16,18,19,18,20,21,22,21,22,24,24,26,25,26,25,24,25,24,23,25,25,25,25,25,26,27,26,28,27,27,27,27,27,27,27,27,27,27,27,28,27,28,27,27,27,28,27,28,27,27,26,27,26,26,27,26,26,27,25,24,25,24,22,23,20,20,20,18,18,18,15,14,13,11,10,9,8,8,9,9,8,9,9,9,10,11,9,10,11,10,11,11,11,11,11,12,12,13,13,13,14,13,13,12,12,11,11,11,12,12,12,14,14,12,13,12,11,10,11,10,10,11,11,10,10,10,9,9,9,9,9,8,8,8,9,9,9,9,10,10,10,10,10,9,9,10,10,10,12,11,10,11,11,10,10,9,9,8,8,8,8,8,8,8,8,8,7,7,7,7,6,7,7,6,6,7,6,6,6,6,5,6,5,4,5,4,3,4,4,5,5,7,8,8,7,6,6,6,5,5,5,5,5,5,5,6,5,5,5,6,5,4,4,4,4,3,3,3,3,3,4,3,3,2,3,3,3,4,4,4,4,5,5,4,5,6,6,6,6,7,7,7,7,7,8,7,8,8,8,8,8,8,7,8,7,7,7,6,6,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,2,1,1,0,1,2,2,2,2,3,3,3,3,4,4,3,4,4,4,4,5,4,4,5,4,5,5,5,6,6,5,5,4,3,3,3,3,3,4,4,4,4,5,5,6,5,6,7,6,6,8,7,6,7,8,7,8,7,7,7,8,7,6,7,7,6,6,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5,5,5,6,6,6,7,7,7,7,7,7,7,8,8,8,7,8,9,8,8,8,7,7,7,7,7,7,8,7,7,7,8,7,7,8,8,7,9,9,9,9,9,9,8,9,9,9,9,9,9,9,9,7,10,9,8,9,9,9,8,8,9,8,8,9,9,8,9,9,9,8,9,9,8,8,9,11,11,12,12,13,15,15,14,15,17,18,19,22,21,23,23,23,22,23,23,22,25,23,24,25,24,25,26,26,26,26,25,27,26,27,28,26,26,27,24,25,26,27,26,27,26,25,27,27,26,23,25,26],[28,28,28,28,28,29,28,28,29,27,27,27,27,27,27,27,27,28,27,27,27,27,27,28,27,27,28,26,28,27,26,28,28,29,28,28,27,28,28,27,28,26,26,26,26,24,23,23,24,21,22,21,21,20,19,20,18,17,18,18,15,14,11,8,7,6,5,5,5,4,4,4,4,3,4,3,3,3,2,2,2,2,2,2,2,2,2,1,3,2,2,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,5,6,5,5,4,4,4,4,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,5,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,6,6,7,6,6,6,5,5,6,6,5,5,6,6,6,7,7,8,11,10,10,12,13,14,14,14,16,15,15,16,17,17,18,19,20,21,22,22,23,24,23,25,23,22,23,22,23,23,23,24,24,24,23,25,25,27,25,26,26,26,26,26,27,26,26,26,26,26,26,26,26,26,27,27,27,27,26,26,26,26,27,26,27,26,25,27,24,24,25,23,22,22,20,19,19,18,18,17,15,14,13,10,9,7,7,7,7,6,6,6,7,7,8,7,8,8,9,8,9,10,9,9,10,11,10,10,12,13,12,12,11,12,11,10,10,10,10,11,11,13,13,12,11,11,9,10,10,8,8,9,9,7,8,8,7,7,7,7,7,6,6,6,7,6,6,7,7,7,7,7,8,7,8,8,9,9,10,10,10,9,8,7,7,7,6,6,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,5,7,7,7,6,5,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,3,3,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,4,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,5,4,4,4,4,5,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,2,3,2,2,2,1,1,0,1,1,1,2,2,2,2,2,2,2,2,3,3,4,4,3,4,4,4,4,3,4,4,5,4,4,4,3,2,2,2,2,2,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,5,6,5,6,6,5,6,5,5,5,5,5,4,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,6,6,6,6,6,6,6,6,6,6,7,6,6,7,6,7,6,6,6,7,6,7,7,7,7,6,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,8,9,10,11,12,13,13,13,14,15,16,18,19,19,21,21,21,20,21,20,21,24,22,23,23,23,25,25,25,23,24,23,24,24,23,26,22,23,24,23,24,24,24,24,25,25,24,25,25,23,22,24,25],[28,28,28,29,29,29,29,29,29,28,28,28,28,28,28,28,28,29,29,29,28,28,29,29,28,28,28,28,28,28,27,28,29,29,27,28,27,28,28,27,27,27,26,26,26,26,24,23,24,22,22,22,22,19,20,21,18,19,19,19,17,14,12,10,8,6,6,5,5,4,5,4,5,4,4,4,3,3,3,3,3,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,6,6,5,6,6,5,4,4,4,5,5,5,5,6,5,4,5,6,5,5,6,6,5,5,6,6,5,6,6,7,6,6,5,5,5,5,4,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,6,5,5,6,5,5,6,6,5,5,6,6,6,6,6,7,7,7,7,7,7,7,6,7,7,6,7,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,6,6,5,5,6,5,5,5,6,6,5,5,6,6,5,6,6,5,6,6,6,6,7,7,7,6,6,6,5,5,6,5,6,6,6,5,6,6,5,5,6,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,5,6,5,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,8,8,8,8,8,7,8,7,7,6,7,6,6,6,7,7,7,8,9,11,13,12,14,16,15,17,17,18,18,18,19,19,19,21,22,23,23,24,24,25,26,25,27,26,25,27,24,26,26,25,27,25,25,26,27,27,28,26,28,27,27,27,28,27,28,28,27,28,27,28,28,28,27,27,28,28,28,28,28,28,28,28,26,28,27,26,28,25,25,26,26,24,23,21,21,20,19,18,18,15,15,14,12,10,9,8,8,8,9,8,9,9,9,10,10,10,10,10,10,11,11,11,11,11,12,12,12,12,13,13,13,12,13,11,12,11,12,12,12,12,13,14,12,13,12,12,11,11,11,10,10,10,10,10,9,9,9,8,9,9,8,8,8,9,9,9,9,9,9,9,9,10,9,9,10,11,10,11,11,10,10,10,8,9,8,7,7,6,7,7,7,7,6,7,7,7,6,7,7,6,7,6,6,6,6,6,5,5,5,5,5,4,5,4,4,4,4,5,5,6,7,7,8,7,6,5,5,4,4,4,4,3,4,5,5,5,5,5,5,5,4,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,7,7,7,7,7,7,8,7,7,7,7,7,7,6,7,6,5,6,6,6,6,6,6,5,5,5,5,5,4,4,5,5,4,4,4,3,4,3,3,3,2,2,2,1,0,1,1,1,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,5,3,4,4,5,5,5,4,4,3,3,3,3,3,4,4,4,4,5,4,5,5,6,6,6,6,7,7,7,7,8,7,7,7,7,8,8,7,6,7,7,6,7,7,7,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,8,7,8,7,8,7,8,9,8,8,8,8,7,7,8,7,7,8,8,7,8,9,7,6,7,8,8,9,9,9,8,9,9,8,9,9,9,9,9,9,9,9,8,10,8,8,9,8,8,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,10,11,12,12,13,14,15,14,15,17,18,19,21,21,23,23,23,22,23,22,23,26,25,25,26,25,26,26,27,25,26,25,27,26,26,28,26,26,27,26,27,26,26,26,27,27,26,27,27,26,25,26,26],[28,27,27,27,27,28,28,27,28,26,26,25,26,25,25,26,26,27,26,27,27,26,26,27,26,26,26,26,27,26,26,27,27,28,27,27,27,27,27,26,27,25,25,25,26,24,22,22,23,20,22,20,20,19,19,20,18,18,17,17,15,13,10,8,7,6,5,4,4,4,4,4,4,4,4,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,5,5,5,5,4,5,5,4,4,5,5,4,5,5,5,4,5,5,6,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,6,6,6,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,3,3,4,3,4,3,4,4,4,4,5,4,4,5,5,5,5,5,5,5,6,5,6,6,6,6,7,7,8,7,8,8,8,8,8,7,8,7,7,7,6,6,6,6,6,5,6,6,6,7,7,8,11,10,10,12,13,13,13,14,15,15,15,17,17,16,18,20,20,20,20,22,21,23,23,24,23,21,23,21,21,22,23,23,22,22,23,25,24,26,24,25,26,26,26,26,26,26,26,26,26,24,26,25,25,25,25,26,25,26,25,25,25,25,25,24,25,24,24,26,24,23,24,23,21,21,20,19,19,17,18,16,14,13,13,10,9,8,7,7,8,7,7,8,9,9,9,9,9,9,10,9,10,12,11,10,12,13,12,12,13,14,13,13,13,13,12,12,12,11,12,12,13,13,13,13,13,12,11,12,11,10,10,11,10,9,9,9,8,8,8,8,8,8,8,8,8,8,8,8,9,8,9,9,9,9,9,9,10,10,11,11,11,10,10,9,8,8,7,7,6,6,7,6,6,6,6,6,7,6,6,6,6,6,6,5,6,6,5,5,4,5,5,4,4,5,4,4,4,4,5,5,6,7,7,7,7,6,5,5,4,4,4,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,2,2,2,1,1,0,1,1,2,2,2,1,2,2,2,3,2,4,4,4,4,4,4,3,4,4,4,5,4,4,4,4,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,7,6,6,7,7,7,7,7,6,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,5,5,6,6,6,7,7,7,7,7,7,7,7,8,8,7,8,7,6,6,7,6,6,7,7,6,7,7,6,6,7,7,7,8,8,8,8,8,9,7,8,8,8,8,8,8,8,8,8,9,9,8,8,8,8,8,8,9,8,7,8,8,8,8,8,8,8,8,8,7,8,8,9,9,11,11,13,14,15,13,15,16,17,19,19,20,21,20,22,22,21,21,22,24,22,24,24,23,25,25,24,23,24,23,24,25,24,26,24,24,24,24,25,24,23,23,24,25,24,25,25,24,23,23,24],[29,29,28,28,28,29,29,28,28,28,27,27,28,27,27,27,27,28,27,28,27,27,27,28,27,27,28,27,28,27,26,28,28,28,28,28,27,28,28,27,27,26,26,26,26,25,23,23,24,21,22,21,22,20,19,21,18,19,18,18,15,13,11,8,7,6,5,4,4,4,4,4,4,3,3,2,3,2,2,2,2,2,1,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,4,3,3,3,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,3,3,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,4,5,5,4,4,5,5,5,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,2,3,3,3,3,4,4,5,5,4,4,5,4,3,4,4,4,3,4,4,3,4,4,3,3,4,4,4,5,5,5,5,4,4,3,3,4,3,3,4,3,3,3,4,4,3,4,4,4,4,4,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,6,6,7,6,6,6,5,5,5,6,5,5,6,6,6,7,7,8,11,10,10,13,13,14,14,14,16,16,16,18,18,18,19,21,21,22,22,24,23,24,23,26,23,23,26,23,23,25,25,25,25,26,25,26,26,28,26,27,28,27,27,28,27,27,27,27,27,27,27,27,27,28,27,28,28,28,27,27,26,27,27,27,27,27,26,27,24,24,25,24,22,22,20,20,20,18,18,17,14,14,12,10,8,7,7,7,6,6,6,7,7,7,8,7,8,8,9,8,9,10,9,9,10,11,11,11,12,12,11,12,11,11,11,10,10,10,11,11,12,12,12,12,11,11,10,10,10,8,9,9,9,8,8,8,8,7,7,7,6,6,6,6,6,6,6,6,7,6,6,7,8,7,7,8,8,8,9,9,9,8,8,7,6,6,6,5,5,4,4,4,4,4,4,5,4,4,5,5,4,4,4,4,4,4,4,4,3,4,3,3,3,4,3,3,3,4,4,4,5,6,6,6,6,5,4,3,3,3,3,3,2,3,3,3,4,3,4,4,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,4,5,4,4,4,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,2,2,2,2,1,1,1,0,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,4,4,3,3,4,5,4,4,3,3,3,2,2,2,2,3,3,3,3,4,3,4,4,4,4,4,4,4,5,5,5,6,5,6,5,5,6,6,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,6,5,6,6,6,6,6,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,6,7,6,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,5,6,6,6,5,6,7,8,9,10,11,12,13,12,13,14,16,17,19,18,21,21,20,20,21,20,21,24,22,23,24,22,25,24,25,24,24,23,26,25,25,26,24,25,25,25,24,25,25,25,25,25,24,26,25,24,23,24,25],[28,28,29,29,29,29,29,29,29,28,28,28,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,27,28,29,29,28,28,28,28,28,28,28,27,27,26,27,25,23,24,24,22,23,22,22,20,20,21,19,20,19,18,16,14,11,8,7,6,5,5,4,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,3,4,4,4,4,4,4,4,3,3,3,3,3,4,3,4,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,5,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,4,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,3,3,4,4,4,4,5,5,5,4,4,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,6,7,8,12,10,11,14,14,16,16,15,17,18,16,17,19,19,19,21,21,23,22,23,24,25,24,26,25,23,25,23,23,25,24,25,24,24,24,26,25,27,26,27,26,27,26,26,27,26,26,26,26,26,27,27,27,27,27,27,27,27,27,26,26,27,27,26,27,27,26,27,25,24,26,25,23,23,20,20,20,17,17,16,14,13,12,10,8,8,7,7,6,6,6,7,7,7,7,7,8,8,8,8,9,9,9,9,9,10,10,10,11,12,11,11,10,10,10,9,9,9,10,10,10,11,12,10,11,10,10,9,9,8,9,9,9,8,8,8,7,7,7,7,6,7,6,7,6,6,6,6,7,6,6,7,7,6,6,7,8,7,8,8,8,8,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,3,3,3,3,4,5,5,6,6,6,6,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,1,1,1,1,0,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,6,5,5,4,4,3,2,2,2,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,5,6,6,6,5,5,5,5,6,6,5,5,5,5,5,6,5,5,4,5,5,5,4,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,6,5,6,6,5,6,6,5,6,6,7,8,9,9,11,12,13,12,12,14,16,18,20,20,22,22,22,20,22,22,21,23,22,24,24,23,25,26,25,24,25,24,26,25,25,26,24,25,25,23,24,25,26,25,26,25,24,25,25,23,22,25,24],[28,29,28,28,28,29,28,28,28,27,27,27,27,27,27,27,27,27,27,27,26,27,27,27,26,27,27,27,27,26,26,27,27,28,27,28,26,27,27,27,27,26,25,26,26,25,23,23,23,22,22,22,21,20,19,20,18,19,18,18,15,13,11,8,8,6,5,4,4,4,4,4,4,3,3,3,2,2,2,2,2,3,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,5,4,4,3,3,3,3,3,4,3,4,4,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,5,5,5,4,5,5,5,4,5,5,5,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,3,4,4,4,3,3,3,4,3,3,4,4,4,4,4,3,4,4,4,5,5,5,5,4,4,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,3,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,5,5,5,6,5,6,6,6,7,8,7,8,12,11,11,14,14,16,16,16,17,19,17,18,20,19,19,21,22,23,23,23,24,25,24,25,23,23,24,24,23,24,24,24,25,25,24,26,26,27,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,26,25,26,26,26,26,26,26,26,24,24,25,24,23,22,21,20,20,18,18,16,14,13,12,10,8,7,6,7,6,7,6,6,7,7,8,8,8,8,8,8,9,10,9,9,10,10,10,10,11,12,11,11,11,11,10,10,10,10,10,10,11,11,12,11,11,11,10,10,10,9,9,9,8,8,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,7,7,6,7,7,8,8,8,8,9,8,8,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,4,4,4,5,6,6,6,6,5,4,4,3,3,3,3,2,3,3,3,4,3,4,4,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,1,1,1,0,1,1,1,1,1,2,3,2,3,3,3,4,4,4,4,3,4,5,4,4,4,4,3,3,3,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,6,5,6,6,6,6,6,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,7,7,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,8,8,10,10,11,13,12,11,13,15,16,18,19,19,23,23,21,20,22,22,20,24,21,23,25,22,25,26,25,25,26,24,25,26,25,26,25,25,26,24,25,27,26,25,26,25,24,25,25,25,23,25,24],[29,29,28,29,29,29,29,28,28,28,28,27,27,27,27,27,27,27,27,28,27,27,28,27,27,28,28,27,28,28,26,28,28,28,28,28,28,28,28,27,28,27,27,27,26,25,23,23,24,22,22,22,21,20,20,21,18,19,19,18,15,14,11,8,8,7,5,5,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,4,4,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,5,5,4,4,4,3,4,3,3,3,3,3,2,3,3,3,2,2,3,2,2,3,3,3,2,3,3,3,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,7,7,7,6,6,6,6,5,5,6,6,5,6,6,6,7,8,7,9,13,12,12,15,15,17,16,16,18,18,17,19,20,20,20,21,24,23,23,25,25,25,25,26,24,23,24,23,24,25,24,24,25,24,24,26,26,28,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,28,28,27,27,26,26,26,27,26,26,26,25,26,24,24,25,24,23,22,21,20,20,18,17,17,15,13,12,10,9,8,7,7,7,7,7,7,7,8,8,8,8,8,8,9,9,10,9,9,10,11,10,10,12,12,11,12,11,11,10,10,10,9,10,10,11,12,12,12,11,11,10,10,10,9,9,9,9,9,8,8,7,8,7,7,7,6,6,7,7,7,7,6,7,7,7,7,7,7,8,8,8,8,9,9,8,8,8,7,7,6,6,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,7,7,6,5,4,4,3,3,4,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,2,2,2,2,1,1,1,0,1,1,2,2,1,2,3,3,3,4,4,4,5,5,4,4,5,6,5,6,5,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,7,6,7,6,6,6,6,6,7,7,7,7,7,8,7,7,8,7,7,8,8,7,7,8,8,7,7,8,7,7,7,7,7,7,6,7,7,7,6,7,7,6,6,7,6,6,7,8,9,10,10,12,13,13,12,13,15,16,18,19,19,22,22,22,21,21,21,21,24,23,23,24,22,25,25,25,24,25,24,26,26,26,27,24,25,26,24,25,26,25,25,25,26,25,25,26,24,24,25,25],[28,28,27,28,28,28,28,28,28,27,27,26,27,26,26,27,27,27,27,27,27,27,27,27,26,27,27,27,28,27,26,28,28,28,26,28,27,27,28,27,28,26,26,26,26,25,23,23,24,20,22,21,21,20,20,20,18,19,19,18,15,14,11,8,7,6,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,4,3,3,4,4,3,4,4,5,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,3,3,4,3,3,3,3,2,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,3,3,4,4,5,4,5,5,5,4,4,3,3,4,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,3,3,2,3,3,3,2,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,6,7,7,8,11,11,11,12,14,16,15,14,16,17,16,18,18,18,19,20,22,21,21,23,23,23,23,24,23,22,23,22,22,22,23,24,23,23,23,24,23,27,24,25,26,26,26,26,25,25,26,25,25,25,25,25,24,25,25,26,26,26,25,25,25,26,26,25,26,24,24,26,23,23,24,24,20,21,20,18,19,17,16,16,14,12,12,10,9,8,7,6,6,6,7,7,7,7,8,8,8,8,8,8,9,9,9,9,9,11,10,10,11,11,11,11,11,11,10,9,9,9,9,10,10,11,11,11,11,10,10,9,8,9,9,8,8,8,8,8,7,6,6,6,6,6,6,6,6,6,6,6,7,6,7,7,7,7,7,8,8,8,9,9,9,8,8,7,6,6,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,5,5,6,6,6,6,5,4,4,3,3,3,3,3,3,3,4,4,4,3,4,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,4,5,5,4,4,4,4,4,4,4,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,0,1,1,1,1,2,2,3,3,3,3,3,4,3,3,4,4,5,4,4,4,4,3,3,2,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,5,6,6,5,5,6,6,5,5,6,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,7,7,7,7,8,7,7,7,7,7,7,8,7,7,7,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,8,10,9,12,13,13,12,13,15,17,17,17,17,20,20,21,20,21,20,21,23,21,23,23,23,24,24,25,24,24,22,24,24,24,26,25,24,25,24,24,24,24,22,24,24,23,25,24,24,22,23,24],[28,28,28,28,28,28,28,28,28,27,26,25,27,26,26,26,27,27,27,27,26,26,27,26,26,27,26,26,27,26,26,28,27,28,26,27,26,27,27,26,27,25,25,25,26,25,22,22,23,21,21,21,22,20,20,21,18,19,18,18,15,13,10,8,7,6,5,4,4,4,4,3,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,4,3,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,5,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,6,7,6,6,6,5,5,6,5,5,6,6,6,7,7,8,11,11,11,14,14,15,15,15,16,16,15,18,18,18,19,20,22,22,21,22,23,24,23,24,23,22,24,22,20,23,24,23,23,23,23,25,25,27,25,26,26,27,26,26,26,27,26,26,26,26,26,26,26,27,26,26,26,27,26,25,25,26,25,26,26,26,25,27,23,24,24,24,22,21,20,18,19,17,17,15,14,13,11,10,9,8,7,7,6,7,7,7,8,8,9,9,9,8,9,9,10,11,10,10,11,12,11,12,12,13,12,12,12,12,12,10,11,11,11,11,12,13,12,12,12,10,12,11,10,10,10,10,10,9,9,9,8,7,7,7,7,7,6,7,7,7,7,7,8,7,7,8,8,7,8,9,9,9,10,10,10,9,9,8,7,7,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,6,7,7,7,7,6,5,4,4,4,4,3,3,3,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,4,4,4,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,0,1,1,1,2,2,3,3,3,4,4,4,4,4,4,4,5,4,5,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,6,6,7,6,6,6,5,6,7,6,6,7,7,5,6,6,6,6,5,5,5,5,5,5,5,4,5,4,4,4,4,5,5,4,5,5,5,5,6,6,6,6,7,7,6,6,7,8,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,8,7,7,8,7,8,8,7,8,8,8,8,8,8,9,8,7,7,8,8,7,7,7,6,7,7,7,7,7,7,7,6,7,7,6,6,7,8,9,10,10,11,13,13,12,13,15,17,18,18,19,20,21,21,20,21,22,21,22,20,22,23,22,25,25,24,23,24,23,25,25,25,26,25,25,24,24,25,25,24,24,25,25,23,24,24,23,21,23,24],[28,28,28,28,28,29,28,28,28,27,27,26,27,26,26,27,27,27,27,27,26,26,26,26,26,26,26,26,27,26,25,27,27,28,26,27,25,26,26,26,27,25,25,25,25,24,23,22,23,21,22,21,21,20,20,20,19,19,18,18,15,14,11,9,8,8,6,5,5,4,5,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,4,4,4,5,5,4,4,4,4,4,4,3,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,6,6,5,5,6,6,6,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,4,4,5,5,4,4,4,4,4,4,5,4,5,5,5,4,5,5,5,6,6,6,6,5,5,4,4,5,4,4,4,5,4,4,5,5,4,4,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,4,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,6,6,5,6,6,6,6,7,7,7,8,8,10,11,12,12,13,15,15,15,16,17,17,17,18,19,19,20,21,22,24,22,23,24,25,24,26,24,23,24,22,23,24,23,25,24,24,24,26,26,28,26,26,27,27,27,27,27,27,27,27,27,26,27,27,27,27,26,27,27,27,27,26,26,26,26,26,26,26,26,27,25,24,24,24,23,22,20,19,19,18,17,16,14,13,12,11,9,9,8,8,7,8,7,8,8,9,9,9,9,10,11,10,10,12,11,11,12,13,12,12,13,14,13,13,12,13,12,11,12,11,12,12,13,14,14,14,13,12,13,12,12,10,11,11,11,10,10,9,9,8,8,8,7,7,7,7,8,7,7,7,8,7,7,8,9,8,8,9,9,9,10,10,10,9,9,8,8,7,7,6,6,6,5,5,5,5,5,6,6,5,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,6,7,7,7,7,6,5,4,4,4,4,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,6,6,6,6,6,5,6,6,6,5,6,6,5,6,5,5,5,5,5,5,5,4,4,5,5,5,4,4,4,4,4,4,3,3,3,2,2,2,2,1,1,1,1,1,1,0,1,1,2,2,3,3,3,4,4,4,4,4,4,5,5,5,5,4,4,4,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,7,6,7,7,6,7,7,6,6,7,7,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,4,5,6,5,5,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,8,8,9,8,8,9,8,9,9,8,8,9,9,8,8,8,9,9,8,8,8,8,7,7,8,7,7,8,7,7,7,7,7,7,7,7,7,7,7,8,9,10,10,12,13,13,13,13,15,17,17,18,19,20,20,21,21,21,21,21,22,22,22,23,23,23,24,24,24,24,23,25,25,24,26,25,24,25,23,25,25,24,24,25,25,23,25,25,24,23,24,24],[28,28,28,28,28,28,28,28,28,27,27,26,27,27,26,27,27,27,27,27,27,27,27,27,27,26,27,27,27,27,26,28,28,29,26,28,26,28,27,26,28,26,26,26,26,25,23,23,24,22,22,22,22,21,21,22,19,20,19,19,17,15,12,10,9,8,7,6,6,5,6,5,6,5,5,4,3,3,3,3,3,2,3,3,2,2,3,2,3,2,2,2,3,2,2,3,3,3,3,4,3,4,4,4,4,4,5,5,4,5,5,4,4,3,3,4,5,4,4,5,4,4,4,5,4,4,5,4,4,5,5,5,5,5,6,6,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,3,3,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,5,5,4,5,6,5,5,5,5,5,5,6,6,6,7,6,6,7,7,6,7,7,7,7,6,6,5,4,5,5,4,4,4,4,3,3,4,4,3,3,4,3,3,4,4,4,3,4,4,5,5,6,5,5,5,5,5,5,4,5,5,5,5,5,6,5,5,6,6,5,6,6,6,6,6,7,7,6,6,5,5,6,6,5,5,6,5,5,6,6,5,5,6,6,6,5,5,5,5,4,4,4,3,4,4,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,8,8,8,8,9,9,9,9,9,9,9,9,9,8,8,8,7,8,8,7,7,8,9,9,10,10,11,12,13,13,15,17,17,16,18,20,19,19,21,21,20,22,23,25,24,24,26,25,27,26,27,25,25,26,23,23,24,25,25,25,25,25,27,27,27,26,27,28,28,27,27,27,27,28,28,28,27,28,28,28,27,27,28,28,28,28,27,27,27,27,27,28,27,27,27,25,25,25,25,24,23,22,20,20,18,18,17,15,14,13,12,10,10,10,9,9,10,9,9,11,10,11,11,12,12,13,12,12,14,13,13,14,15,14,14,15,14,15,14,14,14,14,13,13,13,13,14,14,14,16,15,15,14,13,14,13,12,13,13,12,12,11,11,11,11,10,9,10,9,8,8,10,10,9,10,11,10,10,11,11,10,10,11,11,11,11,12,11,11,10,9,9,8,8,8,7,6,6,7,7,6,7,7,7,6,7,7,7,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,5,6,6,7,7,8,9,7,7,6,5,5,5,5,4,4,4,4,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,6,5,6,6,6,7,7,7,7,7,8,8,7,8,7,8,7,7,8,7,7,6,7,7,7,7,6,7,7,6,6,7,7,6,6,6,6,6,6,6,6,5,5,5,4,4,4,3,3,3,2,2,2,1,1,1,1,1,0,1,2,3,3,4,4,5,5,5,5,5,5,6,6,7,6,5,5,4,4,5,4,4,5,5,5,6,6,5,6,6,6,7,7,7,7,7,8,8,9,8,9,9,8,9,9,8,8,9,8,8,8,8,9,8,7,8,8,7,7,7,7,7,7,7,7,6,6,7,7,7,8,8,8,8,8,8,9,9,9,9,9,9,9,11,10,10,10,10,9,9,9,9,9,10,9,9,9,9,9,8,9,9,9,9,10,10,10,10,10,10,10,10,10,11,11,11,11,10,9,10,11,10,10,11,10,9,10,11,9,9,10,10,9,9,9,9,8,9,9,8,8,9,10,10,11,12,14,15,16,14,15,17,19,20,21,20,21,22,23,21,21,22,24,24,23,23,25,23,24,25,26,24,25,22,26,26,25,27,25,26,26,26,25,26,25,25,26,26,25,26,26,25,23,24,25],[28,28,28,28,27,28,28,27,28,27,27,27,27,27,27,28,27,27,28,27,27,27,27,28,27,27,28,27,27,28,26,27,28,29,27,28,27,27,27,26,28,26,25,25,26,25,23,23,24,20,22,22,22,20,20,21,18,19,19,18,17,15,12,10,10,8,7,7,7,7,6,6,6,5,5,5,5,3,3,4,4,3,3,4,3,3,3,4,3,3,3,3,4,3,3,4,3,4,4,5,4,4,5,5,5,5,6,6,5,6,6,5,4,4,4,5,5,5,5,5,5,4,5,6,5,5,6,6,5,6,6,6,6,6,7,7,6,7,6,6,6,6,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,2,3,4,3,3,4,4,4,4,4,4,4,5,5,5,6,5,5,6,6,5,6,6,6,6,6,7,7,7,7,8,8,7,8,8,8,8,8,8,8,8,8,8,7,7,6,6,7,6,6,6,5,5,5,5,5,4,4,5,4,3,4,5,4,3,4,5,5,5,5,6,6,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,8,7,7,7,6,6,7,7,6,7,7,7,7,7,7,7,7,7,7,7,8,7,7,6,5,6,5,4,5,5,5,5,5,6,5,6,6,6,5,6,6,7,7,7,7,7,7,7,8,8,8,8,8,9,10,9,9,10,11,11,11,10,10,10,9,9,8,9,9,8,9,8,9,9,9,10,10,10,13,13,13,15,16,16,16,17,19,18,18,20,21,19,20,23,23,23,23,26,25,26,25,26,26,24,25,24,23,25,25,26,25,24,25,27,26,28,27,28,27,28,28,28,27,27,28,27,27,28,28,27,28,27,27,27,28,27,27,27,27,27,26,27,28,26,26,27,26,25,26,25,23,22,22,20,20,19,18,18,16,15,14,12,12,11,10,10,10,11,11,10,12,13,13,13,13,13,14,14,14,15,15,14,15,15,15,16,16,16,16,16,17,16,15,15,15,15,15,15,15,15,16,16,16,14,14,15,14,13,13,14,13,13,13,13,12,12,11,11,13,11,10,10,11,12,11,12,12,11,12,12,12,12,13,13,14,14,14,14,14,13,13,11,10,10,9,8,8,7,8,8,8,7,8,8,8,8,8,8,7,8,8,7,7,7,8,7,7,7,6,7,6,6,7,6,6,6,7,7,8,8,9,10,9,8,8,7,7,6,7,5,5,6,5,6,6,6,5,6,5,5,4,4,5,5,5,4,5,5,4,6,5,5,5,6,5,5,6,7,5,5,6,7,6,6,7,7,7,7,7,7,8,8,8,8,8,9,10,10,9,9,9,9,8,9,9,8,8,8,9,9,8,8,9,8,7,8,8,8,8,7,7,8,7,7,6,7,7,6,5,5,5,5,4,3,3,2,3,2,2,2,1,2,1,1,0,1,2,3,3,4,5,5,6,5,5,6,6,6,6,7,7,6,5,4,5,5,5,6,6,6,7,7,7,7,7,7,8,8,8,8,8,9,9,10,9,11,10,9,10,10,9,9,10,10,9,9,10,9,8,8,9,9,8,9,8,8,7,7,8,7,8,8,8,8,8,9,9,9,10,9,10,10,10,10,11,10,9,11,12,11,11,11,10,9,9,10,9,10,10,9,9,11,10,9,8,9,10,10,11,11,12,11,12,12,10,12,11,12,12,12,13,12,12,11,14,12,12,12,12,12,11,11,12,11,11,11,11,11,11,11,11,10,10,11,10,10,10,12,12,14,14,17,17,18,17,18,19,20,21,22,20,22,22,24,23,23,22,23,25,24,24,25,24,25,24,26,25,25,24,26,27,25,28,26,26,25,26,26,26,25,25,25,26,25,26,26,25,23,24,25],[29,29,28,28,29,29,29,29,28,27,27,27,28,28,27,28,28,28,27,28,28,27,27,28,27,26,28,27,27,28,26,27,28,28,27,28,27,27,28,27,27,26,25,25,26,24,23,23,23,21,21,22,21,20,20,21,19,20,19,19,17,16,14,13,12,12,10,11,10,10,11,10,11,10,9,8,8,6,5,6,7,6,6,7,8,6,6,5,5,6,5,6,6,6,5,7,6,6,7,7,7,7,9,8,8,8,9,9,9,8,8,8,7,7,6,7,7,9,8,10,8,7,10,10,8,9,10,10,9,11,11,10,10,11,11,11,12,11,10,10,10,10,9,9,10,8,8,8,8,6,7,8,6,5,5,4,4,5,4,3,4,4,4,4,5,5,6,6,6,7,7,8,8,9,8,9,10,10,10,11,9,10,11,11,10,11,12,11,11,11,12,11,12,13,12,12,12,12,11,12,11,10,12,12,11,11,10,10,9,9,9,10,9,9,10,10,9,9,10,10,9,8,11,9,9,9,11,9,7,10,9,9,9,9,9,9,9,9,10,11,8,11,11,11,11,11,12,12,13,13,13,12,12,13,13,12,13,13,13,13,12,13,13,13,13,12,12,12,13,12,12,12,13,11,12,12,12,11,10,11,10,8,11,8,8,10,11,9,9,11,11,10,12,12,11,12,12,12,13,13,12,13,13,13,13,13,15,16,14,15,16,18,16,17,16,16,18,16,15,16,14,15,13,13,12,12,13,13,13,12,13,12,14,12,14,15,15,15,17,17,16,17,19,20,18,20,23,22,20,25,24,24,25,25,26,26,28,26,28,27,26,27,25,24,27,26,27,27,27,27,29,28,29,28,29,28,29,28,28,29,29,29,29,29,29,28,29,28,28,28,29,28,28,27,28,27,27,28,27,27,27,26,26,27,23,25,26,23,23,22,21,22,20,19,20,17,18,18,16,17,15,15,14,17,16,16,18,18,19,20,18,20,20,21,19,20,21,20,20,20,23,21,20,22,22,22,21,22,21,20,21,22,21,22,22,22,22,22,22,20,21,20,21,19,20,19,21,20,19,20,19,19,18,17,20,18,19,18,18,18,17,20,19,18,18,19,19,18,18,17,18,19,18,18,18,18,18,19,17,17,18,16,18,16,13,15,15,15,13,14,15,15,13,14,13,13,13,12,13,13,14,13,12,12,12,11,11,10,11,10,10,9,9,10,10,10,10,11,12,12,11,11,10,10,9,10,9,9,8,7,9,9,8,6,8,7,6,5,5,6,6,5,6,7,7,6,8,7,8,8,10,8,10,11,12,11,11,12,12,12,11,13,13,13,14,14,13,14,14,14,15,15,14,17,15,16,16,15,14,16,15,13,13,13,13,13,13,11,13,14,12,12,13,12,11,11,12,10,11,10,10,10,9,9,10,9,8,7,6,6,4,5,3,3,4,4,3,3,4,3,2,1,0,1,2,3,4,4,4,5,5,5,6,7,8,8,9,9,9,9,8,10,8,9,11,11,9,12,13,11,12,13,13,15,14,13,15,14,14,15,16,14,15,14,16,16,16,15,15,15,14,15,13,14,14,12,13,14,12,11,12,12,11,11,11,12,11,13,12,13,13,14,14,14,15,16,14,15,15,15,15,15,16,14,15,16,16,15,16,15,14,14,15,13,15,16,14,14,16,16,15,15,16,16,15,18,17,16,18,18,18,16,16,17,15,18,16,17,17,17,15,17,17,16,16,16,18,17,15,18,18,18,16,17,19,16,17,18,17,16,16,16,18,16,18,16,18,19,20,20,22,21,22,22,24,24,25,24,25,25,27,25,26,25,25,27,26,27,27,26,27,27,28,27,28,26,28,28,28,28,28,28,27,28,28,28,28,27,28,28,27,28,28,27,26,26,28],[30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,29,29,29,28,29,29,28,29,29,28,29,29,28,29,28,27,29,29,29,28,28,27,28,28,27,28,27,27,26,27,26,24,24,25,23,23,22,23,21,22,22,21,21,20,21,19,17,16,13,13,13,10,10,11,9,12,10,12,10,11,8,8,8,7,7,9,8,8,7,8,9,8,7,7,7,6,6,7,7,5,7,6,6,7,8,8,7,8,9,9,8,9,9,9,9,9,8,7,7,7,8,9,10,10,10,9,10,10,9,10,11,11,10,12,11,10,11,11,10,11,11,12,11,10,10,11,9,9,9,9,8,8,10,9,7,8,9,8,7,6,5,4,5,5,5,6,6,8,6,6,7,7,8,8,9,9,9,10,11,10,12,11,11,11,11,11,12,11,11,13,11,12,12,12,10,11,12,11,12,13,13,12,13,12,12,12,12,12,12,12,11,10,10,9,9,8,9,9,9,9,10,8,9,10,10,10,10,11,10,8,11,11,9,9,11,11,10,10,12,11,11,10,11,12,11,11,11,12,12,12,12,13,13,12,14,12,13,11,14,13,12,14,13,14,13,13,13,11,12,12,14,12,12,13,13,12,12,13,13,12,13,13,12,12,11,11,10,11,9,9,11,11,11,11,11,13,12,11,11,12,12,11,11,12,14,11,13,12,12,13,14,14,15,14,15,15,17,15,16,16,17,17,17,16,15,15,15,14,13,12,14,14,13,14,13,14,14,15,13,14,16,18,15,17,17,18,18,19,20,20,20,22,23,22,23,25,24,25,24,27,26,27,27,27,26,26,27,25,25,28,27,27,27,27,28,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,27,28,28,28,27,28,28,27,27,26,25,27,27,24,25,23,23,23,22,21,20,20,19,18,18,16,15,15,15,15,15,16,14,17,18,19,18,20,20,21,20,21,22,21,21,21,23,20,22,24,24,22,23,22,22,22,21,21,22,22,22,23,22,23,24,23,21,22,22,20,19,19,20,20,20,20,20,18,17,17,18,18,16,16,15,17,17,17,16,19,19,18,19,19,18,17,19,19,20,19,20,19,19,18,18,17,16,16,16,15,14,14,14,15,12,14,14,13,13,13,15,14,13,13,14,13,12,13,13,13,11,12,13,12,11,12,11,11,10,11,10,11,11,11,12,13,12,12,10,11,10,9,8,8,8,9,8,8,7,8,7,7,7,6,7,7,7,6,7,9,7,8,8,7,7,8,9,8,9,10,11,12,12,12,11,12,13,12,12,13,12,13,12,12,14,14,14,13,16,15,15,15,13,14,14,14,14,13,15,13,14,14,15,13,14,13,14,13,13,12,13,13,12,11,11,11,9,10,9,10,9,9,8,8,8,8,6,6,3,4,5,7,6,3,3,3,4,4,1,0,1,3,3,5,7,6,5,6,7,7,7,8,9,8,9,8,7,8,7,8,10,10,10,11,12,12,13,12,11,14,13,12,13,14,14,14,13,14,16,15,15,15,14,13,13,14,14,15,14,13,13,13,13,13,12,13,13,11,11,11,11,11,12,12,12,12,12,13,13,13,14,14,13,14,14,15,15,16,15,14,14,16,14,14,14,14,12,13,13,13,14,14,13,13,14,16,13,13,14,15,15,16,17,16,16,16,15,14,16,16,15,17,16,18,16,17,15,16,17,16,16,17,17,16,16,18,16,17,17,16,15,17,18,18,16,16,18,16,16,17,18,18,19,20,21,23,23,22,23,24,24,26,26,26,28,26,27,28,28,27,28,28,28,28,29,28,29,29,29,28,28,28,30,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,29,28],[29,29,28,29,29,29,29,28,29,28,28,27,28,28,28,28,28,28,27,28,28,27,27,28,27,27,28,27,27,28,25,27,28,29,27,28,26,27,27,26,27,26,25,25,26,24,21,23,24,20,22,22,22,20,20,23,19,20,21,20,18,16,15,13,13,12,11,10,11,11,12,12,12,11,10,9,9,7,7,8,8,7,7,7,8,7,9,6,7,7,7,7,7,6,7,8,7,6,9,9,9,10,10,9,10,10,10,10,10,10,10,9,8,8,9,9,10,11,11,12,11,10,12,12,11,12,12,11,12,12,12,12,12,11,12,12,12,12,11,11,10,11,11,10,10,10,9,9,9,7,8,8,7,6,7,5,6,7,5,6,6,6,8,7,5,6,8,7,8,9,9,9,10,10,11,11,12,12,12,12,12,12,12,11,12,12,11,12,13,12,11,13,13,13,12,13,13,13,13,14,13,13,14,12,12,12,11,11,11,10,11,11,11,10,10,11,10,9,10,10,9,9,10,10,8,10,10,9,8,10,11,10,10,11,11,12,11,12,11,12,11,12,13,13,13,13,13,13,13,14,12,13,14,14,14,14,15,15,14,15,14,14,13,14,13,13,13,13,14,13,13,12,13,13,13,14,13,13,12,11,11,11,11,10,9,11,12,10,11,11,13,12,12,13,13,13,12,13,14,13,13,14,14,14,15,14,16,16,16,17,18,19,18,19,19,18,20,19,18,18,16,17,15,14,14,15,15,15,15,14,14,15,15,14,16,16,15,16,17,17,19,18,18,21,20,20,22,22,21,23,25,24,24,24,26,26,27,25,26,26,25,26,24,24,26,26,26,26,26,26,28,27,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,27,27,27,27,27,27,27,27,26,27,25,24,25,25,22,22,23,21,21,21,20,19,18,18,19,16,16,16,16,16,16,17,18,16,20,20,21,19,20,20,21,19,20,21,20,20,21,22,21,21,21,22,22,22,21,22,21,21,21,22,21,21,21,21,22,22,23,22,21,22,21,19,20,22,20,20,20,21,19,19,19,20,20,21,20,19,20,21,20,21,21,20,20,20,19,20,19,19,20,20,20,20,21,20,19,19,17,19,19,18,18,16,16,17,18,15,17,16,18,16,17,16,16,17,15,15,16,15,15,14,13,13,12,14,12,12,13,12,11,11,12,11,12,12,12,13,14,12,12,11,12,12,12,11,9,10,9,10,10,10,7,8,7,7,6,6,7,7,6,7,8,7,8,9,8,8,8,10,9,10,12,12,11,11,13,12,13,13,14,14,14,14,15,14,16,16,16,17,17,19,19,18,18,18,17,16,17,17,17,17,15,16,15,16,14,14,16,15,13,13,14,13,13,13,11,13,12,11,11,10,9,9,10,7,9,6,7,7,8,3,5,5,5,5,5,4,4,4,3,2,1,0,1,2,4,7,7,5,6,8,8,9,9,9,9,9,8,8,9,8,9,10,10,10,12,13,13,12,13,13,16,15,14,16,16,16,16,16,16,18,17,17,19,17,16,16,16,16,16,15,15,15,15,14,14,14,14,13,13,13,12,13,13,13,14,13,14,14,14,15,15,14,16,16,16,17,17,17,17,18,17,16,17,17,16,17,15,15,15,15,16,16,17,15,16,17,17,16,15,16,16,16,18,18,18,17,17,18,16,18,16,17,18,18,19,18,18,17,17,18,18,18,18,18,18,18,19,19,19,18,19,20,18,19,20,20,18,18,18,19,18,19,18,20,21,23,21,22,22,22,22,24,24,25,24,26,25,26,25,26,25,24,26,26,26,27,26,27,27,27,26,27,26,28,28,26,28,27,27,27,27,27,27,27,26,27,28,27,27,27,26,26,25,27],[29,29,29,29,29,29,29,28,29,27,28,27,28,27,27,27,27,28,26,28,28,26,27,28,26,26,27,26,27,27,24,27,28,28,25,27,26,26,27,26,27,25,25,24,25,23,21,23,23,20,21,21,21,20,20,21,19,19,19,19,18,16,14,13,13,13,11,12,10,12,12,12,13,12,12,10,10,9,9,9,9,9,9,8,8,8,7,6,7,8,7,8,8,7,7,9,9,7,9,10,10,11,11,13,12,10,11,12,12,11,11,11,9,11,9,10,11,12,12,13,13,12,13,13,12,14,14,13,13,13,14,13,13,13,13,13,13,14,13,12,13,13,11,12,12,12,10,12,11,10,11,11,11,10,9,7,6,8,8,6,7,7,8,8,8,9,9,9,11,11,11,11,12,12,12,13,13,14,14,14,13,13,13,13,13,13,14,13,14,13,14,13,14,14,13,13,14,13,12,13,13,12,13,14,11,12,11,11,10,10,10,11,12,11,12,12,11,11,12,13,11,11,12,12,11,12,12,12,11,13,12,13,11,13,12,14,13,13,13,14,14,14,14,14,16,15,15,14,16,15,16,15,16,14,15,15,15,14,14,15,16,14,15,15,14,14,13,14,14,14,13,13,13,13,13,14,13,13,12,11,11,10,12,9,10,11,13,12,12,12,14,13,13,14,14,15,15,15,15,16,15,15,16,16,17,16,19,18,17,19,20,20,18,20,19,19,21,19,18,18,17,17,16,16,15,14,15,16,15,13,15,14,16,14,15,15,15,15,17,16,17,17,19,19,18,20,22,21,21,23,25,24,25,25,26,26,27,26,28,26,26,27,26,25,26,26,26,26,26,27,28,28,29,28,29,29,29,29,29,29,28,29,29,28,28,28,28,28,28,28,28,27,28,27,27,26,27,27,26,27,27,26,26,25,24,25,25,22,23,22,21,22,21,20,20,19,19,20,17,17,17,17,17,19,17,18,20,20,22,22,21,22,22,23,21,21,23,23,21,22,25,23,22,23,24,25,23,23,22,22,22,24,23,23,24,24,24,25,24,24,22,22,24,22,21,22,23,22,21,23,21,20,20,20,22,22,22,21,21,20,21,22,22,21,21,22,22,21,22,20,21,21,21,21,21,21,21,21,21,18,21,18,19,18,16,18,18,18,16,17,18,18,16,16,15,14,15,13,13,15,15,14,13,14,13,11,12,12,11,11,10,10,9,12,11,11,11,12,12,13,12,12,10,12,10,11,10,8,9,8,11,9,8,8,7,6,5,4,6,6,5,5,6,6,5,6,8,7,8,8,9,9,10,11,13,12,12,12,13,16,13,14,15,15,15,15,15,16,16,16,17,17,17,19,19,18,19,17,16,17,17,15,14,15,15,14,15,13,15,15,13,12,13,13,12,12,12,11,11,11,10,10,9,10,10,9,9,7,6,5,4,5,5,4,5,6,7,5,4,5,6,3,3,2,1,0,1,2,3,4,4,3,5,7,7,8,8,9,9,9,9,11,10,9,12,12,11,13,13,12,14,14,14,16,15,14,16,16,15,16,17,15,17,16,17,18,18,16,17,16,16,14,14,15,15,13,13,14,13,13,13,12,12,12,12,14,12,14,14,14,14,16,15,15,15,17,16,16,16,16,17,17,17,16,16,18,16,17,17,16,16,14,15,15,15,18,16,15,18,18,15,17,17,18,17,20,19,20,20,19,20,18,18,19,18,20,18,19,18,18,17,19,19,17,18,19,20,18,18,20,20,20,19,19,21,18,20,20,19,18,19,19,20,18,19,18,19,21,23,23,23,23,23,23,24,26,25,25,27,26,27,26,27,26,26,27,27,27,28,27,27,27,28,27,28,27,28,29,28,29,28,28,28,29,28,28,29,28,29,28,28,28,29,27,26,27,28],[29,30,29,30,30,30,30,30,30,29,29,29,29,28,29,29,29,29,29,29,28,27,28,28,27,28,28,28,28,28,27,28,28,28,27,28,27,27,27,27,27,26,26,25,26,24,23,24,24,22,23,23,22,21,21,22,20,21,20,20,18,16,14,13,12,11,10,10,11,10,12,11,12,11,10,10,8,8,9,9,9,9,7,8,8,7,6,6,6,6,5,6,8,6,7,8,8,8,8,10,10,9,10,11,11,10,11,12,11,11,10,10,9,11,10,10,11,12,12,13,11,11,13,12,12,13,13,13,12,12,14,12,13,13,12,14,12,13,12,12,11,12,11,12,12,9,10,12,9,9,11,11,8,9,9,8,7,8,8,8,8,8,8,8,8,8,9,9,11,11,11,11,13,11,12,13,12,14,13,13,14,13,13,13,14,13,14,14,14,13,14,13,13,14,13,14,13,13,13,13,13,12,13,12,11,11,9,10,9,8,10,10,9,10,12,11,9,10,12,11,10,12,12,11,10,12,12,12,12,11,11,12,11,12,12,13,12,12,14,14,12,14,15,13,13,14,15,14,13,15,15,13,14,14,14,13,14,15,14,15,13,13,13,13,12,14,13,12,13,13,12,13,13,13,13,12,13,12,11,10,11,9,10,7,8,12,11,10,12,12,13,12,13,13,13,14,12,12,12,14,13,14,14,13,14,16,15,14,15,16,15,16,17,17,17,17,16,16,17,16,15,16,15,14,15,14,15,15,14,14,14,14,16,14,13,15,16,16,18,17,19,18,19,20,20,19,21,21,21,22,24,24,24,25,26,26,26,25,27,26,27,28,25,24,27,27,27,27,27,28,29,28,28,28,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,28,29,29,29,28,28,28,27,28,28,28,29,28,28,27,25,27,26,24,25,24,23,23,23,23,22,20,19,20,17,16,16,15,16,15,16,15,15,17,17,19,18,18,19,20,19,19,21,20,20,21,23,20,21,23,23,23,22,22,22,22,21,22,21,21,22,22,22,23,22,21,21,19,22,20,19,18,19,19,20,18,19,19,16,17,17,19,16,15,16,17,18,16,18,20,19,18,19,20,19,18,19,20,19,20,19,21,19,20,19,18,18,17,17,16,15,15,15,17,14,14,15,16,15,14,16,15,14,14,14,14,13,14,14,13,12,11,11,12,11,10,10,9,9,9,9,9,10,10,11,12,11,12,10,10,9,9,8,8,8,8,10,9,8,7,8,7,6,4,5,7,6,4,7,6,6,6,6,7,6,8,7,9,9,10,10,9,11,13,11,13,13,13,13,14,13,13,13,13,14,14,14,14,15,15,15,15,14,15,15,15,15,14,14,15,14,15,15,13,15,14,13,13,14,12,12,10,11,10,9,9,10,9,9,9,8,8,8,7,7,7,4,7,4,4,7,7,8,6,5,6,7,6,4,4,3,1,0,1,3,4,4,4,6,7,7,8,9,8,8,8,8,8,7,8,9,9,10,10,12,13,13,13,12,15,13,13,13,14,15,13,13,13,15,14,14,15,14,14,14,13,14,14,13,14,13,12,13,13,12,11,13,11,10,10,11,10,12,12,12,12,12,14,14,13,14,14,14,14,15,14,14,15,14,14,14,15,14,15,14,13,13,13,12,13,14,14,14,14,15,14,14,14,14,14,13,15,16,16,15,16,16,14,15,15,15,16,17,17,16,16,15,16,16,15,16,17,16,17,16,17,16,17,17,17,18,18,18,17,16,17,18,17,16,18,19,18,19,20,21,22,24,22,23,23,24,26,26,25,28,27,27,27,27,27,28,29,28,28,28,27,29,29,29,29,29,28,29,29,29,29,29,29,29,29,28,29,29,29,29,29,28,29,29,28,28,28,28],[29,29,28,29,29,30,29,29,29,28,28,28,28,28,28,27,28,28,27,27,27,26,26,27,26,27,27,26,27,27,25,27,28,28,26,27,26,26,26,25,27,25,25,25,25,24,23,24,23,22,22,22,21,21,21,21,19,20,20,18,17,15,13,11,12,11,10,9,10,11,10,12,11,10,11,9,9,9,8,7,8,8,7,7,7,8,7,6,5,6,6,6,7,6,6,9,8,7,8,8,10,9,9,10,11,9,10,11,11,10,10,9,9,10,10,10,10,11,11,12,11,12,12,12,11,13,13,11,11,11,13,11,12,12,11,13,11,11,11,10,10,11,10,10,11,10,9,10,10,9,9,10,9,9,8,7,7,7,7,7,8,7,8,8,8,10,9,9,11,11,10,12,13,11,11,12,12,12,11,12,11,13,11,11,13,12,11,11,12,11,12,12,12,12,11,12,11,12,12,12,12,10,11,11,10,10,9,9,9,9,9,10,9,8,10,10,9,9,10,11,10,10,10,13,10,10,11,11,11,10,11,12,10,12,11,12,12,11,12,12,12,12,13,13,14,13,13,13,14,14,12,13,14,12,12,13,14,13,13,13,13,13,14,13,12,13,13,12,14,12,11,11,13,12,12,13,12,11,11,10,10,10,10,9,9,10,12,11,11,11,12,12,12,12,12,13,13,13,13,14,13,13,13,15,15,14,17,16,16,16,18,18,17,18,18,17,19,18,18,19,17,16,15,14,14,13,14,14,14,13,12,14,13,13,14,14,14,14,17,15,16,17,18,18,17,18,20,19,19,22,23,21,24,24,25,25,27,26,26,27,26,27,26,25,27,26,27,28,27,27,28,28,29,28,29,28,29,28,28,28,28,28,28,28,28,28,29,28,29,28,29,28,28,28,28,27,27,28,28,28,28,27,27,26,25,26,26,23,24,23,22,22,21,20,19,18,19,18,18,16,17,15,17,18,17,18,18,19,21,19,20,20,20,20,20,21,22,20,20,20,21,21,20,23,23,21,22,22,22,20,21,21,22,21,22,22,21,21,22,22,21,20,20,19,20,20,21,21,20,21,20,18,19,18,21,19,21,18,19,18,17,20,18,18,20,19,19,19,19,18,18,20,19,20,19,19,19,18,19,17,19,17,17,17,15,15,15,16,14,16,15,16,15,16,14,14,14,13,13,13,13,11,12,12,11,10,12,10,11,10,9,9,8,9,9,9,11,10,11,12,11,10,10,10,11,9,9,7,8,8,8,8,7,7,6,6,6,3,6,6,5,5,6,5,5,6,8,6,6,8,8,7,9,10,10,10,11,12,12,12,11,12,12,13,14,13,13,15,15,15,16,15,16,17,16,17,18,15,15,16,15,14,15,13,14,14,13,12,14,12,11,11,11,10,10,11,11,9,10,9,9,9,9,9,9,8,6,5,5,5,4,5,4,4,5,6,6,5,5,6,6,5,4,5,3,2,1,0,1,3,2,3,3,4,6,7,7,7,7,7,7,9,9,8,9,10,11,11,10,10,11,11,12,14,13,13,13,14,14,14,14,15,16,13,16,16,15,14,14,13,13,13,12,13,12,11,11,12,11,11,11,10,10,10,11,12,11,12,11,13,12,14,13,13,13,14,13,14,15,16,14,15,16,13,15,15,15,14,16,14,12,13,14,13,14,15,13,13,16,15,14,14,17,16,16,18,17,18,17,16,17,14,16,16,16,17,15,17,16,16,14,15,16,17,16,16,17,16,15,17,18,18,16,18,19,16,17,19,19,16,17,17,19,17,17,17,18,20,22,21,21,21,21,22,21,23,24,23,26,24,26,24,26,25,26,27,25,26,27,26,27,27,27,26,27,26,27,27,26,28,27,27,27,27,27,28,27,27,28,27,27,27,27,27,26,26,27],[29,30,29,30,29,30,30,30,29,29,28,28,29,28,28,28,29,28,28,29,28,27,29,29,27,28,29,27,28,28,26,28,28,28,27,28,26,27,27,26,27,25,25,25,25,24,24,24,23,21,22,22,21,20,21,22,22,21,20,21,18,15,13,12,10,10,10,9,10,8,11,10,11,10,10,8,9,9,8,8,9,8,7,7,8,8,6,6,6,7,7,7,7,7,8,8,9,9,8,9,10,10,11,12,12,11,12,14,12,11,10,11,10,11,10,10,12,12,13,12,13,12,13,13,12,14,12,13,12,12,12,13,13,11,12,13,12,12,11,11,12,11,11,12,11,10,10,11,10,9,10,10,10,10,8,8,8,8,9,8,9,8,9,9,10,9,9,10,12,12,11,12,14,13,12,13,12,12,13,13,13,14,11,12,13,12,12,12,12,11,13,12,13,13,13,13,13,12,12,12,12,11,12,12,11,10,10,9,9,7,9,10,10,9,10,11,10,10,11,11,10,11,11,11,10,11,11,11,11,11,11,12,11,12,11,12,13,12,12,12,13,13,12,14,14,13,12,14,13,13,13,13,12,12,12,13,13,13,13,13,13,14,13,12,13,13,12,12,14,13,11,13,14,12,12,14,12,12,11,11,11,10,13,9,9,12,12,10,11,11,13,13,12,12,13,13,12,12,13,15,13,12,13,14,14,13,15,14,14,15,17,18,15,16,17,17,18,16,16,15,15,14,14,13,13,13,13,12,12,12,13,12,12,12,13,15,14,15,16,18,15,18,18,18,17,18,19,19,19,22,23,21,24,24,25,26,27,25,27,26,25,26,26,24,26,26,26,27,26,26,28,28,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,27,27,27,27,27,27,27,26,27,25,24,26,24,22,23,22,22,22,20,21,19,17,18,17,17,16,14,15,15,15,15,15,15,16,18,18,17,18,18,19,18,19,20,19,18,18,20,19,20,22,22,22,21,21,20,20,20,21,20,20,21,21,22,22,22,22,20,20,21,19,19,18,19,18,18,18,17,17,16,18,17,18,17,16,16,17,17,18,17,18,18,17,17,18,19,17,18,19,19,19,19,20,20,19,19,17,17,16,16,15,15,15,14,14,14,14,15,15,13,13,13,13,14,13,13,13,13,12,13,13,11,11,11,10,11,10,10,9,9,9,9,9,11,10,11,12,11,12,10,10,8,10,8,8,7,7,8,8,7,7,5,5,4,4,5,6,3,4,6,5,4,6,6,6,7,7,7,7,7,9,10,10,11,12,11,14,12,12,13,13,13,13,13,13,13,14,14,14,15,15,15,15,14,14,14,14,14,13,13,12,13,14,14,13,13,12,12,13,12,11,12,11,11,10,11,8,8,8,9,8,7,7,7,5,5,4,4,5,4,5,5,7,7,7,6,7,7,6,5,4,4,3,2,1,0,1,1,1,2,3,4,5,6,7,6,6,6,8,7,7,9,9,9,10,11,12,11,11,12,14,13,12,12,12,13,12,12,12,14,13,14,14,13,14,12,13,14,14,13,13,12,12,11,12,12,10,10,10,9,9,9,10,10,11,10,11,12,13,13,12,12,12,13,13,13,13,13,14,14,14,14,14,13,15,13,12,12,13,13,12,13,14,13,13,14,13,13,13,15,14,13,15,15,15,15,14,15,14,14,14,15,16,16,16,15,16,15,14,14,15,15,16,16,14,13,15,15,17,16,16,17,15,16,17,16,16,17,16,17,17,18,17,18,19,22,21,22,21,23,23,23,24,25,24,26,25,28,26,26,25,27,27,27,27,28,28,28,28,28,27,27,27,28,28,28,29,28,28,28,29,28,28,28,28,28,28,27,28,27,28,28,27,27],[29,29,28,29,29,29,29,28,29,28,27,28,28,27,28,28,28,28,28,28,27,26,27,28,25,27,28,26,28,27,25,27,28,28,27,28,26,27,27,26,27,25,25,25,26,24,22,23,23,22,22,22,21,20,21,22,19,19,21,21,18,16,13,12,11,10,10,10,9,10,11,12,14,12,12,9,9,11,9,8,10,9,8,8,10,9,7,6,7,9,8,8,10,10,9,10,12,12,11,12,12,12,12,13,12,12,13,16,13,13,13,13,12,12,12,13,13,14,15,16,16,14,15,16,13,14,15,15,13,15,14,14,15,14,15,15,14,14,13,12,14,13,13,14,14,13,12,13,13,13,12,13,13,12,11,11,10,10,10,10,10,10,11,10,12,11,11,12,13,13,12,14,16,13,13,14,14,15,15,15,14,15,13,14,14,15,14,14,14,14,13,14,15,13,13,14,14,13,13,13,11,12,13,12,11,11,10,11,9,10,11,12,13,11,12,13,12,12,13,14,11,13,13,13,12,12,14,13,12,13,12,12,12,13,14,14,14,13,15,15,13,14,15,16,15,15,15,15,15,16,15,15,16,15,15,15,15,15,15,16,16,15,15,15,15,15,14,15,15,15,13,14,15,14,13,13,13,13,12,13,12,11,12,9,11,13,14,12,13,14,13,13,14,14,15,14,15,15,14,14,14,14,14,16,15,14,18,17,17,18,19,19,19,20,20,19,20,19,18,18,16,16,15,14,14,13,14,13,13,14,14,13,12,13,13,14,14,15,16,17,17,18,19,19,19,19,21,20,19,22,24,21,23,25,25,25,27,25,27,27,26,27,26,24,26,26,26,26,27,26,28,28,29,27,28,28,28,28,28,28,28,28,28,28,27,28,28,28,27,27,28,28,28,28,27,27,27,28,27,27,27,27,28,26,25,26,25,22,22,21,21,22,20,21,20,18,18,17,17,18,18,15,15,17,17,18,18,19,20,20,19,19,19,21,19,20,21,21,19,20,22,22,21,22,23,22,22,22,22,20,21,22,21,22,23,22,23,23,21,23,22,21,21,18,19,18,21,21,18,19,20,19,17,19,20,20,20,20,19,21,20,21,21,21,21,21,21,21,21,19,21,21,21,20,20,21,20,21,21,19,22,19,19,18,17,17,18,18,17,18,19,18,16,17,16,16,16,14,15,14,15,15,14,14,14,12,13,13,14,11,11,11,9,9,11,10,12,11,12,12,11,12,10,11,10,11,11,9,9,8,9,9,9,7,6,5,6,5,4,5,6,5,6,6,6,6,8,9,7,8,9,8,9,11,11,11,13,14,14,13,14,15,14,14,15,15,15,15,16,17,17,17,18,19,18,18,18,18,17,16,16,16,15,14,15,15,15,14,15,14,14,13,12,13,12,12,12,11,11,10,10,9,9,9,8,7,7,5,6,5,4,6,6,5,6,8,9,7,7,9,9,8,8,7,6,4,3,2,1,0,1,1,2,3,4,5,6,7,7,7,8,9,8,8,9,11,10,10,12,12,14,13,13,15,15,14,14,15,15,15,16,16,15,15,16,16,17,15,14,15,14,14,14,14,14,14,12,14,14,11,12,13,10,9,10,10,13,13,12,14,13,15,14,14,14,16,15,16,15,16,15,16,16,15,15,16,17,15,15,16,14,14,16,16,14,15,15,15,16,16,15,15,16,15,15,17,17,17,17,17,17,15,16,16,16,17,16,18,16,17,15,16,17,17,17,18,18,18,17,19,20,19,18,20,20,18,19,21,18,18,20,19,20,18,19,18,18,21,21,22,22,23,23,24,24,25,25,26,27,26,27,26,27,26,26,27,26,27,28,26,28,27,28,27,28,27,28,28,27,29,28,28,28,28,28,28,28,27,28,28,27,28,28,26,27,28,27],[30,30,29,30,29,30,30,29,29,29,29,28,29,28,28,28,29,29,28,29,28,28,28,29,27,28,28,27,28,28,26,28,28,28,27,28,27,27,27,27,27,26,26,26,26,25,24,24,24,21,23,23,22,20,21,23,20,20,21,21,20,17,14,13,12,11,10,10,9,10,10,11,12,11,9,9,7,9,7,7,10,7,6,7,8,6,6,6,7,7,7,8,8,7,8,10,9,9,9,11,13,10,13,14,14,13,14,15,14,13,13,13,11,14,12,13,14,14,14,14,15,13,14,15,14,14,14,15,14,13,15,14,13,13,14,14,14,14,13,13,12,13,13,13,12,11,12,12,11,10,13,12,11,11,10,9,10,10,9,8,8,8,10,10,9,10,11,12,12,12,13,13,14,14,14,13,13,15,14,14,13,12,13,14,13,13,13,14,13,13,13,12,13,14,13,13,14,13,13,13,13,12,13,13,12,12,11,11,10,10,10,11,11,10,11,12,12,10,11,13,12,12,12,13,11,12,13,11,11,13,13,12,12,12,13,14,14,14,14,15,14,13,15,15,13,14,14,14,13,15,14,12,14,15,15,14,15,14,14,14,13,12,12,14,14,12,13,13,13,12,12,13,13,12,12,14,13,11,13,12,11,10,13,10,10,11,14,11,11,12,14,11,12,13,13,14,12,13,14,14,13,14,14,13,15,15,16,15,16,17,19,19,17,18,18,18,18,19,17,17,16,16,15,14,13,14,15,14,13,14,14,12,13,14,14,16,16,16,17,18,17,18,18,19,18,18,21,21,20,21,24,24,24,24,27,26,27,25,27,26,25,27,25,25,27,27,27,26,26,27,28,28,29,28,29,29,28,28,29,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,27,27,28,27,28,28,27,28,26,25,27,26,23,24,22,23,23,21,21,21,18,19,18,17,16,16,14,16,16,16,17,17,18,19,19,18,19,19,20,19,20,21,20,19,21,22,20,22,23,23,22,22,22,22,21,20,21,20,21,21,23,22,23,22,23,22,21,21,20,19,19,21,20,19,19,19,18,17,18,20,19,19,18,17,18,19,20,20,20,20,19,18,19,20,19,20,20,20,21,20,21,20,19,19,18,19,18,18,16,16,15,16,16,14,16,16,16,13,16,15,14,15,15,14,13,13,13,12,11,12,12,11,12,12,12,9,10,9,10,11,11,12,11,13,13,11,11,10,10,11,11,10,8,8,9,8,9,8,8,7,6,6,5,5,6,5,6,6,7,5,5,8,7,6,7,7,8,8,9,10,11,10,13,13,11,11,13,13,12,13,14,13,14,14,15,15,15,17,17,17,16,16,16,16,15,14,15,14,12,15,14,13,13,11,12,13,11,11,12,13,12,12,11,11,10,9,9,9,8,7,7,7,5,6,6,4,5,4,5,5,6,8,6,6,7,7,6,6,6,5,4,3,2,2,1,0,1,2,3,4,5,6,6,7,7,7,7,7,7,9,10,9,10,11,11,11,12,12,12,13,12,13,14,15,14,14,15,16,15,16,16,16,15,13,15,15,14,13,12,13,13,11,12,12,12,11,11,10,9,10,9,11,12,13,12,12,12,12,13,13,13,14,15,15,15,15,16,16,15,15,15,15,15,16,14,14,13,14,14,14,16,14,13,15,15,14,14,15,15,15,17,17,16,16,15,17,15,15,16,15,17,17,16,16,17,16,17,16,17,18,17,17,16,17,18,19,19,17,18,18,17,18,20,17,18,19,18,18,18,18,18,20,20,23,21,22,22,23,24,25,26,26,25,28,27,27,27,28,27,28,28,28,28,29,27,28,28,29,28,29,27,29,29,28,30,29,29,29,29,29,29,29,29,29,29,28,28,28,27,28,28,28],[30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,29,28,29,28,27,29,29,27,29,29,27,29,28,27,28,29,29,28,28,27,28,28,27,28,27,26,26,26,26,25,25,25,24,23,24,24,23,22,24,23,22,21,22,19,17,15,13,11,11,11,9,9,9,11,11,12,12,11,8,8,9,8,8,9,8,6,7,9,7,6,5,6,6,6,7,8,8,8,9,11,9,10,12,13,11,13,14,14,13,14,15,14,14,12,13,11,14,12,12,13,13,14,14,14,13,14,14,14,15,14,15,15,13,14,14,15,13,14,14,14,15,13,13,14,14,13,13,14,12,12,13,12,11,12,13,12,12,10,10,9,10,11,9,11,8,11,10,11,11,11,10,13,13,13,12,15,14,14,15,14,15,14,15,14,14,14,14,16,14,15,16,15,14,16,14,15,15,15,15,14,15,13,14,14,13,13,13,11,11,9,11,9,9,9,11,10,10,13,13,10,12,13,13,12,13,13,14,13,13,14,13,12,13,13,12,12,13,13,14,14,13,14,15,14,14,15,15,14,15,15,16,14,15,16,15,14,14,15,14,15,15,14,15,14,15,14,14,15,14,14,14,15,13,13,14,14,13,12,14,13,12,11,12,11,10,12,9,10,13,12,11,12,14,15,13,13,14,14,15,13,13,14,16,14,14,15,14,15,16,16,15,16,17,17,18,16,17,16,16,17,16,16,17,15,16,15,14,13,14,14,14,13,13,14,13,13,12,14,16,15,16,17,18,18,19,18,21,19,20,21,21,21,23,23,24,25,25,26,26,27,26,28,26,26,27,25,24,27,27,26,27,27,27,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,28,27,28,26,25,26,25,23,24,23,23,22,21,22,22,18,19,18,17,15,15,15,17,16,16,15,16,17,18,17,18,18,18,19,19,19,20,19,18,19,22,20,20,21,23,23,22,21,21,21,19,21,19,20,22,21,22,23,22,21,20,19,20,19,17,18,19,18,17,18,17,16,16,16,18,17,18,17,16,17,18,19,17,17,18,19,18,18,17,18,18,19,18,20,19,19,19,19,19,17,18,17,17,17,17,15,17,17,16,15,16,17,15,15,16,15,15,14,14,14,13,14,15,13,13,13,12,12,12,10,8,8,9,9,8,9,11,10,11,11,12,12,10,9,9,10,8,8,7,7,8,8,8,7,7,7,6,3,7,7,4,6,9,7,6,6,6,7,5,7,9,7,9,10,9,9,10,13,11,12,13,14,14,14,13,13,14,15,14,15,15,15,17,17,16,16,15,16,16,15,14,16,15,15,13,15,15,13,14,13,12,12,13,12,11,10,10,10,9,9,9,8,8,7,8,6,6,4,6,4,3,4,4,4,5,7,9,8,6,7,8,7,6,5,6,5,5,3,4,2,1,0,1,2,4,5,6,6,7,6,5,7,7,7,8,9,9,10,11,12,12,12,12,14,14,13,13,15,14,14,14,15,16,16,15,16,17,15,14,14,15,14,12,12,12,12,11,12,11,11,11,11,10,9,9,10,12,12,12,12,12,13,13,12,12,14,15,13,15,13,15,16,15,14,16,15,15,14,14,13,13,13,12,13,13,15,13,14,14,14,13,14,14,15,15,17,16,15,15,15,16,15,15,15,15,16,17,17,15,17,16,17,16,15,16,15,16,16,16,16,17,17,16,17,17,18,18,18,17,17,18,17,17,18,18,18,18,19,21,21,23,21,23,24,25,26,27,25,28,27,27,28,28,28,28,29,28,28,29,28,29,29,29,29,29,29,30,29,29,30,29,29,29,28,29,29,29,29,29,29,29,29,29,28,28,28,28],[30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,30,29,29,30,29,28,29,29,27,29,29,28,29,29,27,29,29,29,28,29,27,28,28,28,28,27,26,27,27,25,23,24,24,23,21,22,22,21,21,22,22,21,21,22,20,17,15,14,12,11,11,10,10,12,13,14,16,16,13,12,11,13,11,10,13,12,10,9,12,10,9,8,8,10,9,9,10,12,10,11,14,13,11,15,16,13,15,17,16,14,18,19,17,17,15,16,14,16,16,15,17,17,19,18,19,16,19,18,16,18,18,19,17,18,18,18,17,17,17,18,17,17,15,16,17,15,15,16,16,15,15,16,16,14,15,17,15,16,13,14,12,12,15,11,13,14,13,14,15,16,16,14,17,17,15,16,19,17,16,17,17,18,17,19,17,17,17,17,17,18,17,16,17,17,17,16,17,18,16,17,17,16,16,17,15,15,16,15,13,14,13,13,11,12,12,13,13,11,14,16,15,16,15,16,14,15,15,17,17,16,16,17,16,16,16,17,16,17,16,17,17,15,17,17,17,18,19,19,18,19,18,19,18,20,19,18,19,18,19,18,18,17,17,19,19,18,18,18,17,17,17,17,17,17,17,16,17,16,16,17,17,15,15,14,15,13,14,14,13,16,15,16,16,17,19,17,17,18,19,19,18,18,19,20,18,18,18,19,19,18,20,19,20,20,21,22,20,21,21,20,22,21,20,20,19,19,19,17,16,17,17,16,16,15,16,13,14,15,14,16,17,17,16,19,18,19,20,21,19,21,23,22,21,23,25,23,24,26,26,27,28,26,28,27,27,28,26,25,27,28,27,27,28,28,29,28,29,28,29,29,29,28,29,29,29,29,29,29,28,29,29,29,29,28,29,29,29,29,28,28,28,29,28,28,28,27,28,26,25,26,25,24,23,23,22,23,21,21,22,19,20,20,18,18,18,16,18,19,19,20,19,20,22,21,21,22,21,21,21,21,21,22,21,20,22,22,21,23,23,23,23,22,22,22,23,22,22,22,24,22,23,25,22,24,23,22,22,21,20,20,21,21,20,21,20,20,20,19,23,22,22,22,21,23,22,23,22,22,23,23,23,22,22,21,22,22,21,21,21,21,22,22,22,20,23,21,22,22,21,20,22,21,18,20,21,21,17,20,20,18,19,19,18,18,17,18,17,17,18,16,15,13,13,13,13,13,12,13,13,13,15,12,13,16,14,15,13,13,11,12,12,10,10,9,10,9,10,9,8,7,7,5,7,8,5,6,8,9,7,8,10,9,9,11,10,10,11,13,12,13,14,15,15,17,17,18,18,19,17,18,18,19,18,19,21,20,20,22,21,20,20,21,20,19,19,19,18,18,18,18,19,18,18,18,17,15,15,16,13,14,12,12,13,11,11,10,8,9,9,7,8,5,7,7,6,7,6,6,7,9,12,9,8,12,12,10,8,6,7,5,4,3,3,4,2,1,0,2,3,5,6,7,8,8,8,11,11,9,10,14,13,14,13,14,13,15,16,18,18,18,16,18,19,18,20,19,20,19,19,20,20,18,17,19,19,17,18,18,18,16,14,17,15,12,13,14,10,12,11,14,15,15,15,14,16,17,15,17,16,18,19,17,18,20,19,18,20,18,19,19,19,20,17,16,17,16,17,16,17,18,17,17,18,18,17,17,18,18,19,20,18,19,19,18,20,17,18,19,19,20,20,21,19,20,18,21,19,19,20,21,22,21,20,20,22,21,20,20,22,21,21,22,21,20,21,21,22,21,20,20,20,21,23,23,23,23,24,25,26,26,27,26,28,28,28,27,27,28,28,29,29,28,29,29,29,29,29,28,30,28,29,30,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28],[30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,29,29,29,29,28,29,29,28,28,29,28,29,28,27,29,29,29,28,29,27,28,28,27,28,26,26,26,27,26,25,24,25,24,23,24,23,23,22,23,22,22,21,22,21,18,16,16,13,14,13,11,10,10,14,15,17,18,16,11,11,15,12,12,15,13,12,11,15,12,12,11,11,14,11,14,16,15,16,17,18,17,18,19,20,20,22,22,22,21,22,22,22,21,20,22,19,20,19,21,21,21,22,23,23,21,23,23,22,22,24,23,20,23,22,23,21,21,22,21,23,22,21,22,22,20,21,22,21,20,20,20,19,18,21,21,18,19,18,17,17,18,19,16,15,12,16,18,16,17,19,20,20,20,21,20,21,21,21,20,21,22,22,23,21,21,22,22,20,22,22,22,20,20,21,20,22,21,21,21,21,20,20,21,20,19,20,19,19,18,16,17,15,16,17,18,20,17,20,19,20,19,19,20,18,20,20,19,19,20,21,18,18,21,20,19,20,19,20,21,20,20,22,22,20,22,22,23,21,23,23,22,22,23,23,21,23,22,22,21,22,22,22,23,22,21,21,22,21,20,21,21,20,20,19,21,19,20,18,21,19,20,20,18,19,18,19,16,18,19,20,16,19,19,20,19,20,21,19,21,20,20,21,20,21,20,21,22,21,22,23,23,23,23,25,26,24,25,25,24,25,24,23,23,22,22,21,19,19,19,20,19,18,19,20,15,16,18,16,16,18,19,17,21,20,20,20,22,21,22,22,23,22,24,26,25,25,26,28,27,28,26,28,27,26,28,26,26,28,28,28,28,28,28,30,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,28,28,28,27,25,27,26,24,25,24,23,24,22,23,23,20,22,20,20,20,21,19,21,21,23,23,23,24,26,24,24,25,24,24,25,25,25,25,23,24,26,26,24,25,26,26,27,26,26,25,26,26,25,25,26,25,26,26,25,25,26,24,24,25,24,24,25,24,24,24,25,24,23,23,25,25,25,24,24,25,26,26,25,25,26,26,25,25,25,24,24,26,24,25,25,26,25,25,25,24,26,25,24,24,24,23,25,24,21,23,24,24,22,24,22,21,23,21,21,21,21,20,20,21,20,18,19,18,18,18,17,18,13,17,17,15,16,16,17,18,17,17,16,18,15,17,16,12,15,13,14,14,15,10,12,11,10,8,10,10,8,9,10,10,9,10,13,11,10,13,15,14,12,17,18,16,18,19,18,19,20,20,20,20,20,21,20,22,22,22,23,22,23,24,24,24,23,23,23,22,22,22,22,19,21,21,21,19,20,20,19,18,19,19,18,16,17,17,18,15,16,14,13,14,12,10,10,7,8,8,7,9,9,10,10,12,14,12,13,13,14,14,13,11,10,9,8,6,7,5,4,4,1,0,2,4,6,7,10,9,10,10,11,11,12,13,15,16,16,17,17,17,18,19,19,19,20,20,21,21,21,23,23,22,23,21,23,21,19,20,20,20,19,19,19,19,16,18,19,17,17,16,14,13,13,13,17,16,17,16,18,19,18,20,18,20,21,19,20,21,20,21,22,20,21,22,20,21,21,19,21,19,20,18,20,21,19,20,20,20,20,20,20,20,21,24,22,21,22,21,22,21,20,21,20,22,22,22,22,22,21,23,21,23,24,23,24,24,22,23,24,26,23,24,25,23,24,25,24,23,24,25,25,24,23,23,24,25,26,25,25,26,26,27,28,28,28,27,29,28,29,28,28,28,29,30,29,29,30,29,30,30,30,29,30,29,30,30,29,30,29,30,29,30,29,30,30,29,30,30,29,30,29,30,29,29,29],[30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,30,29,28,29,29,28,29,29,29,28,29,28,28,28,28,28,27,26,26,26,26,25,25,25,24,24,25,24,23,23,24,24,23,23,24,22,20,19,17,15,14,12,13,11,14,14,16,16,20,17,15,14,18,15,13,17,17,12,14,17,16,15,12,18,18,16,18,19,17,19,19,20,20,19,22,23,22,24,25,24,22,24,24,23,22,22,22,21,23,22,22,22,22,23,24,23,22,24,25,23,23,25,25,23,24,25,24,23,24,23,23,24,23,22,23,24,23,22,24,23,23,23,23,22,21,22,21,21,23,20,20,20,20,20,18,18,17,18,20,18,19,20,21,21,22,21,22,22,22,22,22,22,23,24,25,23,23,24,24,24,24,25,24,23,24,25,22,23,25,23,23,24,23,23,24,23,22,23,23,23,23,21,22,19,18,20,22,21,21,23,23,23,22,23,22,22,22,22,22,22,21,21,21,21,21,21,20,20,20,19,22,22,21,22,23,21,21,24,23,22,22,24,23,21,24,24,22,23,24,24,23,24,23,24,24,23,23,22,24,23,23,23,24,23,23,22,23,24,22,22,24,24,23,23,22,23,20,20,17,20,22,20,18,21,22,23,22,22,23,22,22,21,22,22,22,22,21,22,22,22,21,23,22,22,24,25,25,24,25,25,24,25,25,23,23,22,22,22,20,21,20,21,20,18,19,20,16,15,19,18,18,19,21,21,22,23,21,23,24,23,23,24,24,22,25,27,26,27,27,28,27,29,28,29,28,27,29,28,27,29,29,29,29,28,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,29,29,29,28,29,28,28,28,27,28,26,25,26,26,24,24,24,23,23,22,23,22,21,22,22,21,21,21,21,22,22,23,24,22,25,24,25,24,24,25,25,25,26,25,25,25,24,27,26,25,26,27,26,28,27,26,25,25,26,25,26,26,26,27,27,26,26,26,24,26,25,23,24,26,24,24,24,25,24,24,24,24,25,24,24,24,26,26,26,25,25,26,26,25,26,25,25,25,26,25,25,25,25,25,25,26,25,26,25,25,24,23,23,25,25,22,24,25,25,22,24,24,23,24,24,23,23,23,24,22,22,22,22,22,19,21,19,17,17,16,19,18,20,18,20,22,22,21,22,21,19,18,21,19,16,17,17,19,18,18,15,16,15,13,11,15,16,11,12,15,13,10,13,17,13,11,17,18,13,15,19,19,18,18,20,18,20,22,22,22,21,22,23,22,23,23,23,23,23,25,24,25,24,23,24,24,23,23,24,24,22,23,24,23,22,23,23,23,22,23,23,21,17,17,19,21,18,17,15,13,14,12,10,11,8,9,9,9,9,11,12,12,17,18,14,14,16,17,16,17,13,12,13,10,9,9,8,6,6,4,2,0,2,4,5,7,10,10,12,11,12,13,17,18,18,16,19,19,19,20,22,23,21,22,23,23,23,22,24,25,23,23,24,25,23,22,24,24,23,23,22,23,23,21,21,21,19,18,19,15,15,12,14,15,18,15,18,21,20,21,22,21,21,24,22,23,24,24,24,24,22,25,25,23,23,22,22,21,21,22,19,23,23,21,20,22,22,20,21,22,22,23,23,22,23,23,24,23,22,23,23,23,24,23,25,23,24,21,24,24,23,24,24,25,23,24,25,24,25,25,25,24,25,25,25,24,25,26,24,25,25,25,24,25,25,27,27,27,27,28,28,28,28,29,28,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29],[30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,29,30,29,28,29,29,28,29,29,28,29,29,27,29,29,29,28,29,28,28,28,28,28,27,26,26,27,25,24,24,24,23,23,22,23,23,21,22,22,22,21,21,19,17,15,14,12,11,10,10,10,12,14,15,16,17,15,14,13,16,13,13,16,15,13,13,16,14,13,11,13,16,14,15,16,15,17,18,19,19,19,21,22,21,22,23,22,22,23,24,23,22,22,22,21,22,21,22,23,24,24,24,24,22,23,24,22,23,24,24,22,23,24,22,22,23,23,23,23,22,21,22,22,21,22,24,21,21,22,22,20,19,21,19,17,18,19,16,18,19,17,17,17,15,18,18,16,18,19,20,18,19,22,20,20,22,23,22,22,24,24,24,22,22,23,23,23,23,24,23,22,23,23,20,21,23,21,22,23,20,20,22,20,19,22,21,22,20,19,19,17,17,19,20,19,19,21,20,20,21,20,19,18,20,20,20,19,21,19,18,19,21,19,17,20,18,19,20,22,22,23,23,22,21,24,22,22,23,24,22,22,24,24,22,23,23,22,22,22,22,23,23,22,21,22,23,21,22,21,22,21,22,21,21,21,21,21,21,22,21,20,20,20,17,17,15,17,18,17,17,18,19,20,19,20,21,20,21,21,21,22,19,19,20,22,21,23,23,23,23,24,24,24,24,24,25,25,25,24,25,24,23,22,22,22,18,18,18,20,17,16,17,18,15,13,17,16,16,17,19,19,19,20,20,20,23,22,21,23,23,23,24,26,25,26,26,28,27,28,27,29,28,27,28,26,25,28,28,28,28,28,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,28,29,28,27,29,27,28,28,27,28,25,25,27,24,23,24,22,22,24,22,23,22,20,22,20,21,22,21,20,18,21,23,21,23,25,24,25,25,24,24,25,25,25,25,24,24,23,26,25,24,26,26,26,26,24,26,25,26,25,25,25,25,25,26,27,25,25,26,23,24,24,22,22,24,25,23,24,25,25,23,24,25,25,24,24,23,25,26,25,25,25,25,25,25,24,25,24,24,25,23,24,24,24,24,24,25,24,26,25,25,24,24,23,25,25,22,23,25,24,21,24,23,22,23,22,22,21,20,22,20,20,21,20,18,17,19,17,15,16,13,16,16,18,18,18,19,19,19,19,17,16,16,18,17,13,16,16,19,18,17,13,15,15,13,11,13,12,10,11,12,11,10,12,13,11,11,13,14,14,14,16,15,15,17,18,16,16,19,20,19,20,20,22,22,22,21,22,23,22,23,23,24,24,22,23,24,21,21,23,22,20,22,23,21,20,20,21,19,19,18,20,18,16,16,17,16,14,13,11,11,12,10,8,10,6,10,9,8,8,10,10,11,13,14,12,11,15,14,13,14,10,11,13,9,10,9,8,7,7,7,4,2,0,1,3,6,9,10,12,12,11,11,13,14,12,14,16,17,16,17,18,19,20,20,20,20,22,22,21,22,22,21,22,23,21,20,22,22,20,19,19,19,18,18,18,19,17,14,16,14,12,12,12,13,14,13,15,18,16,18,20,19,20,20,20,22,21,21,22,22,20,21,22,20,19,20,20,19,19,20,17,19,21,19,17,21,20,20,18,20,21,20,22,22,22,22,22,20,20,21,22,21,23,22,23,22,23,21,23,22,23,24,23,24,23,24,24,24,24,23,24,24,24,25,25,24,24,24,24,24,24,24,22,23,23,26,25,26,26,27,27,28,27,29,27,29,28,29,28,29,28,29,29,29,29,30,29,29,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,29,30,29],[30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,29,30,29,29,29,28,29,29,28,28,29,27,29,29,27,29,29,29,28,29,28,28,28,28,28,27,27,26,27,26,25,25,25,24,24,25,24,22,21,24,22,21,22,21,20,17,15,12,11,9,10,8,8,10,11,13,12,17,12,13,13,14,13,12,15,12,12,13,14,14,13,12,14,15,14,14,15,15,14,17,17,16,18,19,20,20,21,21,22,22,23,23,22,22,21,22,19,20,18,21,21,22,21,24,23,21,23,23,21,20,24,25,20,21,23,23,20,21,23,22,23,22,21,24,22,21,21,22,20,20,19,19,17,17,18,17,17,17,16,15,15,16,17,15,15,13,15,16,15,14,18,19,18,19,20,19,19,19,19,20,20,21,22,22,20,19,21,21,20,21,22,21,19,21,22,20,21,21,20,21,22,20,21,21,21,19,20,22,20,19,18,20,16,16,18,19,19,18,19,19,18,17,18,19,17,19,20,18,18,19,19,17,17,20,18,16,17,18,17,19,19,20,20,20,19,21,21,21,21,21,20,21,20,21,20,20,22,22,21,20,23,20,21,22,20,20,19,22,20,19,19,20,20,21,20,20,20,20,20,20,20,20,20,20,19,17,20,16,18,18,17,16,18,17,18,19,19,19,17,19,18,19,19,17,16,16,19,19,19,21,21,20,22,22,22,22,22,24,23,23,23,22,22,21,19,19,18,16,14,16,17,14,13,14,15,12,11,15,14,14,17,18,18,20,20,20,21,22,20,21,22,23,21,23,25,24,25,26,27,26,27,27,29,27,26,27,26,26,28,27,29,28,28,29,29,29,30,29,29,29,29,29,30,30,29,29,29,29,29,29,30,29,29,29,29,29,29,28,29,27,28,28,27,29,27,26,28,25,23,25,23,22,24,22,21,22,21,22,21,19,19,18,18,19,18,16,14,20,20,20,21,23,23,24,22,22,23,24,23,23,24,24,23,23,25,24,23,25,26,25,26,23,25,24,25,24,24,25,24,24,25,25,23,24,25,24,23,24,23,22,24,25,22,23,23,23,21,22,23,24,23,23,21,23,24,25,23,24,25,25,24,24,25,24,24,24,24,24,23,24,23,24,25,23,25,22,24,22,21,21,23,23,20,22,24,23,21,22,21,20,21,20,21,21,20,21,19,18,19,18,19,16,17,16,15,14,12,15,15,16,15,18,18,19,17,19,17,17,16,17,17,15,16,14,17,17,17,14,17,14,14,10,14,13,12,11,13,12,11,12,12,12,12,13,13,12,12,15,14,14,15,17,16,16,18,19,16,18,18,19,18,20,20,20,21,21,22,22,23,22,21,20,22,21,20,21,20,18,20,20,19,19,19,19,18,18,16,17,17,14,14,16,16,13,11,11,12,12,8,7,8,6,9,9,8,9,8,11,11,13,12,10,12,14,12,11,13,12,11,12,9,11,10,9,8,9,8,5,5,1,0,2,3,5,8,8,10,9,9,12,12,13,11,17,15,14,16,18,17,17,19,19,18,19,20,20,21,20,21,20,22,20,18,18,19,19,19,17,17,18,15,15,18,16,13,14,11,9,10,9,9,12,10,13,14,14,14,15,17,18,18,18,19,20,19,19,20,18,19,20,19,19,18,19,19,18,20,14,15,19,16,13,17,18,15,13,17,18,18,20,20,20,19,20,20,19,21,19,20,19,19,22,20,22,20,21,20,22,22,22,23,22,23,23,24,24,22,23,24,23,24,25,23,22,24,24,25,22,23,22,24,24,25,25,25,26,26,26,28,27,28,28,28,28,29,28,29,27,29,29,29,29,30,29,29,29,30,29,30,29,30,29,29,30,29,29,30,30,29,29,29,29,29,29,29,30,29,30,29,29,29],[30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,30,29,29,30,29,28,29,29,28,29,29,28,29,29,27,29,29,29,28,29,28,29,28,28,28,27,27,27,27,26,25,24,25,24,23,23,23,22,21,22,21,21,20,20,18,15,13,10,9,8,8,7,7,7,9,9,11,12,10,9,9,12,10,10,10,11,11,10,11,11,10,11,11,11,11,12,13,12,12,15,16,14,15,15,18,16,17,17,17,17,17,18,17,15,15,16,15,18,16,16,16,16,18,17,18,17,18,17,16,17,18,19,17,17,19,17,16,17,17,16,17,18,16,17,18,17,17,18,16,18,16,17,15,16,16,14,14,13,13,13,13,13,12,11,11,12,13,12,10,13,12,15,13,13,16,16,14,15,16,16,17,18,17,18,17,17,17,17,17,16,18,17,17,17,17,16,16,18,17,16,18,16,16,17,16,14,16,17,17,16,16,16,16,14,16,15,16,17,16,15,15,15,15,15,13,16,16,14,13,15,13,10,12,14,11,11,12,13,12,13,14,16,15,16,15,17,17,17,16,17,17,17,16,17,17,16,17,17,15,15,16,16,17,16,16,16,15,16,15,15,15,16,16,14,14,16,15,15,15,16,16,15,16,15,16,13,14,11,12,13,12,12,13,13,11,12,14,14,13,13,14,14,14,13,11,14,14,14,13,17,18,16,18,18,18,18,20,19,18,19,18,17,17,15,14,13,13,11,10,13,12,10,11,11,11,10,10,12,11,10,15,16,16,18,17,17,17,20,19,18,19,21,20,20,23,23,23,24,25,25,26,25,27,26,24,25,25,23,25,26,26,26,26,27,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,28,27,27,26,27,27,26,26,26,25,27,24,23,24,22,21,22,20,20,21,20,20,20,18,18,16,16,15,14,13,12,13,17,14,17,17,16,19,18,17,18,19,17,17,19,18,17,17,20,18,19,20,20,20,20,18,19,18,19,19,18,18,19,18,19,21,18,20,19,17,17,18,17,17,19,18,17,16,17,18,16,16,19,19,17,19,16,19,20,19,18,19,20,19,19,19,19,18,18,18,18,18,18,17,18,18,18,18,18,18,19,19,18,16,18,19,16,17,18,18,15,16,18,15,16,15,16,16,15,15,14,13,15,14,13,12,13,13,10,8,9,10,11,12,12,14,15,16,14,15,15,13,14,14,12,11,13,13,14,13,15,11,12,12,10,10,11,10,9,9,10,9,10,10,10,9,10,10,9,8,12,11,10,12,12,10,11,11,11,13,12,13,13,14,14,15,14,15,17,18,16,17,16,18,16,15,16,16,15,16,14,13,14,15,14,14,14,15,13,14,13,13,12,8,7,11,11,11,7,6,7,7,6,4,7,5,8,7,8,6,7,8,8,11,10,8,9,9,11,9,9,9,9,10,8,10,8,9,7,7,7,6,5,6,1,0,1,3,5,8,9,7,8,8,9,7,9,10,11,9,10,12,13,13,15,14,13,15,15,15,15,15,14,15,15,14,12,12,13,14,12,13,13,12,12,11,12,10,9,8,8,8,7,8,9,8,7,10,11,10,9,12,12,12,12,13,14,14,15,14,14,12,14,15,13,14,13,12,12,11,14,11,11,13,12,10,12,12,12,11,11,14,14,16,15,16,17,15,15,14,15,15,14,15,14,17,16,17,14,17,17,15,17,16,19,15,18,18,17,17,17,18,17,18,18,19,16,17,19,18,18,18,18,17,17,18,20,21,21,20,21,23,23,25,26,25,26,26,27,26,27,26,27,28,27,28,28,28,28,29,29,28,29,29,29,29,29,29,28,29,29,28,29,28,29,28,29,28,28,28,29,28,28,28,28],[29,29,28,28,28,29,29,29,28,28,28,28,28,28,27,28,28,28,28,29,28,28,29,28,27,28,28,27,28,28,26,28,29,29,28,29,28,28,28,27,28,27,26,26,26,26,25,24,24,23,22,23,23,21,20,21,20,20,19,18,15,13,11,9,7,6,8,5,6,6,7,7,9,9,8,7,7,8,7,8,8,8,8,6,9,9,8,8,9,10,9,9,11,9,9,10,11,11,10,12,12,11,13,13,12,12,14,14,13,13,12,12,11,12,11,11,12,13,13,13,14,12,14,14,13,12,14,15,12,14,13,13,12,12,12,12,12,13,12,12,14,12,12,13,13,11,11,12,12,12,11,11,10,10,10,9,10,9,9,9,9,7,10,8,9,9,9,10,11,10,11,11,12,11,11,12,12,12,12,13,11,11,12,12,12,12,13,12,11,12,13,11,12,12,13,12,12,12,12,13,12,11,12,13,12,12,12,11,11,10,11,12,12,12,11,12,10,11,11,11,10,11,11,11,10,11,11,9,9,11,9,9,10,10,10,11,11,11,12,11,11,12,12,12,12,13,12,12,11,12,11,11,12,12,11,12,13,12,11,12,12,11,11,12,12,11,10,11,12,10,11,11,12,10,11,11,12,12,11,10,11,10,9,9,9,9,9,9,10,10,10,9,11,10,11,11,11,11,11,10,8,11,10,11,10,11,12,12,14,13,13,13,14,14,14,14,14,15,14,13,12,9,10,8,9,9,8,7,9,8,9,9,8,10,11,12,12,13,15,15,16,15,17,20,16,17,20,20,18,20,21,21,22,22,23,25,25,25,26,25,25,26,23,24,25,25,26,25,25,27,28,27,28,27,28,28,28,28,28,28,28,29,29,29,28,29,28,29,28,28,28,28,28,27,27,25,26,27,25,26,25,25,26,24,22,25,23,20,22,21,21,20,20,19,19,16,15,14,12,11,10,9,9,10,12,11,13,13,13,15,14,14,14,15,15,14,15,14,14,15,16,15,15,16,16,16,16,15,16,14,14,15,15,15,16,16,17,16,17,17,16,15,15,14,15,14,15,15,14,14,14,15,13,13,14,14,13,13,12,14,15,15,14,16,16,15,15,15,15,14,14,14,14,15,15,15,14,14,15,14,15,14,14,14,13,11,13,13,12,12,13,13,11,12,12,11,11,10,10,11,9,10,10,8,9,9,8,7,8,8,7,6,6,7,8,9,10,11,11,11,10,11,10,9,9,10,9,9,10,10,11,10,11,9,10,10,8,9,9,9,8,8,9,7,7,6,7,6,6,6,6,5,8,7,7,7,8,8,8,9,8,8,9,9,10,10,10,11,11,11,12,12,12,13,13,13,11,12,12,11,10,11,10,8,10,10,10,9,9,9,8,7,8,8,7,5,6,7,7,6,5,5,5,5,2,3,4,3,6,6,6,7,7,8,7,8,7,7,9,8,8,8,9,9,7,9,7,8,8,7,7,7,6,5,6,4,2,1,0,1,3,4,5,4,4,6,5,6,5,7,7,7,8,8,8,8,10,10,10,10,11,11,11,11,10,10,12,11,8,9,10,8,9,8,8,7,7,6,7,7,6,7,7,5,7,6,7,6,6,7,8,8,7,8,8,8,9,9,11,10,10,12,11,9,12,13,12,10,10,11,9,8,10,8,8,10,8,7,9,11,8,8,9,11,11,12,13,13,12,13,11,11,13,12,12,13,13,14,12,12,10,13,13,11,12,14,14,11,13,14,12,13,14,14,12,13,14,14,13,13,14,14,14,12,14,14,15,15,18,17,18,18,18,19,22,22,22,22,24,23,25,24,24,23,24,26,25,25,27,25,27,26,27,26,27,26,27,27,28,28,27,27,27,27,27,26,26,25,26,27,26,27,27,26,26,26,26],[29,29,28,28,29,29,29,28,29,27,27,27,28,27,28,27,27,27,27,27,27,26,27,27,26,27,28,27,28,27,26,27,28,28,28,28,27,28,27,27,28,26,26,26,26,25,24,23,24,23,21,21,21,20,18,19,19,18,17,17,14,12,10,7,7,5,4,3,2,2,3,3,3,3,3,2,3,4,3,3,3,4,3,3,3,4,3,4,4,4,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,8,7,8,9,8,8,8,7,7,8,8,8,8,8,8,8,7,7,7,7,7,7,8,7,7,7,7,7,7,8,8,7,7,6,7,6,6,6,7,6,5,6,6,5,6,6,5,5,6,6,6,5,6,6,6,6,5,6,6,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,6,6,6,6,6,5,5,6,6,5,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,6,6,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,5,4,4,5,5,4,5,6,6,7,7,6,7,7,7,7,7,7,6,6,6,6,6,6,6,6,5,6,6,6,7,7,7,7,6,6,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,6,6,5,5,5,4,4,3,3,4,3,3,4,4,4,4,4,4,5,4,5,5,5,5,4,5,5,5,5,6,5,6,6,7,6,6,7,8,7,7,7,7,7,7,6,6,6,5,5,5,5,4,4,5,4,5,5,6,7,10,10,10,14,15,14,13,15,17,15,15,18,19,17,19,20,20,20,21,22,22,24,23,24,23,22,25,22,23,24,24,26,23,24,25,26,26,27,26,26,27,27,27,27,27,27,27,27,28,27,27,27,27,27,27,28,27,28,27,27,25,26,26,25,25,24,24,25,22,21,22,22,20,20,19,18,19,18,17,17,15,14,13,10,9,7,6,7,6,6,6,7,7,8,9,8,9,9,9,9,10,10,9,9,11,11,10,10,11,11,11,11,11,11,10,10,10,11,10,11,12,11,12,12,11,10,11,11,9,9,10,9,9,8,9,8,8,7,8,8,7,6,7,7,8,7,6,7,8,8,7,8,9,8,8,8,9,9,10,10,10,10,9,8,8,7,7,7,7,6,5,6,6,5,6,6,5,5,6,6,5,6,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,5,5,6,7,7,8,8,6,5,5,5,5,5,4,4,5,5,5,6,6,6,6,6,6,6,5,5,5,4,4,4,4,3,4,3,3,3,3,2,3,3,3,3,3,3,4,4,3,4,4,4,4,5,4,5,5,5,5,5,6,6,6,5,5,5,6,5,5,5,5,4,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,3,4,3,3,3,2,2,2,2,2,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,5,6,5,5,5,5,5,5,6,4,3,2,1,0,1,1,2,2,2,2,2,3,3,3,4,4,4,6,5,5,4,5,5,5,6,6,6,6,5,6,7,5,5,6,6,5,5,5,5,5,5,5,5,4,5,4,3,3,3,3,4,4,3,5,5,5,5,5,5,5,5,5,5,5,6,6,7,6,7,7,7,7,6,6,6,6,6,5,5,6,5,5,5,6,5,5,5,5,6,7,8,8,7,7,7,7,7,8,7,8,8,8,8,8,8,9,8,7,7,7,8,7,7,7,7,6,7,7,7,7,7,7,6,7,7,7,7,7,9,10,11,12,13,14,14,14,15,16,17,19,20,19,22,20,23,20,22,21,21,23,22,23,25,23,26,25,26,24,25,25,26,25,25,26,25,25,25,23,25,25,25,23,26,25,23,25,26,24,23,24,25],[28,29,29,29,29,29,29,29,29,28,28,28,28,27,28,27,28,28,28,28,29,27,29,29,27,28,29,27,29,28,27,29,29,29,29,29,28,29,29,28,29,28,27,27,27,26,25,24,24,23,23,22,23,20,19,20,18,18,18,18,15,13,10,7,6,5,3,3,3,2,2,2,2,2,2,2,2,3,2,2,2,3,3,2,3,3,3,3,3,4,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,7,7,6,5,5,5,6,6,6,6,6,6,5,5,6,6,5,5,6,5,5,6,6,5,6,6,7,6,6,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,4,4,5,4,4,5,5,4,5,5,5,4,5,5,6,6,6,5,6,6,6,6,6,6,6,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,4,4,4,5,5,5,6,6,5,5,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,5,5,6,7,9,9,11,13,13,13,14,14,16,16,15,17,18,17,18,20,20,21,22,23,23,25,24,26,23,23,25,22,22,25,24,25,23,23,25,27,25,27,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,26,27,26,25,27,25,25,26,22,23,24,23,21,21,19,19,19,18,17,16,15,14,11,10,7,6,5,5,5,5,5,5,6,5,6,6,6,7,7,7,8,9,8,8,9,9,9,9,10,11,10,10,9,10,9,8,9,8,9,10,10,11,11,10,10,9,9,9,8,8,8,8,7,7,6,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,6,6,7,8,8,9,9,8,8,8,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,4,3,3,4,3,3,3,4,4,5,7,7,7,6,6,5,4,4,4,4,4,4,4,4,5,5,5,4,5,5,5,4,4,4,3,3,4,3,3,3,3,3,2,3,2,2,2,3,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,3,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,5,4,4,4,5,5,5,3,2,1,1,0,1,1,1,1,1,2,2,2,2,2,3,2,3,3,3,3,4,4,4,4,4,4,5,3,4,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,2,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,5,6,6,6,5,5,5,5,6,5,6,6,6,5,6,5,7,6,5,6,6,5,5,5,5,5,5,6,5,5,5,6,5,5,6,6,5,5,6,7,8,9,10,11,13,13,12,14,15,16,18,18,20,21,20,21,19,21,21,20,24,21,23,24,23,25,27,24,24,25,25,26,25,26,26,25,26,25,24,25,25,25,24,26,24,24,26,26,24,22,24,24],[28,28,28,28,28,29,28,28,28,27,27,28,27,27,27,27,27,27,27,27,27,27,27,28,26,27,28,27,28,27,26,28,27,28,28,27,27,28,28,27,28,27,26,26,26,25,23,22,23,23,21,21,21,20,18,20,17,17,17,17,14,12,10,6,6,4,3,3,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,3,3,4,4,4,4,4,4,4,3,3,4,3,3,4,4,3,3,4,4,3,4,4,5,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,5,4,6,8,8,12,11,14,13,13,15,15,14,14,16,16,16,17,19,19,20,19,21,21,22,22,23,21,21,21,22,20,22,22,23,21,23,22,26,25,26,25,25,26,27,26,26,26,26,26,26,27,26,27,27,27,26,27,26,27,26,26,26,25,26,26,24,25,24,24,25,22,23,23,23,21,21,18,18,19,17,16,16,13,11,9,7,6,5,4,4,3,4,4,4,4,4,4,4,4,5,5,6,5,6,6,6,7,7,7,7,7,8,7,8,7,8,7,7,7,7,6,7,7,7,7,7,7,7,7,6,6,6,6,6,5,5,5,5,4,4,4,4,4,3,3,3,3,4,3,4,4,4,4,4,4,4,5,5,5,6,7,7,6,6,6,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,6,6,6,5,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,3,3,4,4,4,4,3,2,2,1,1,0,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,4,3,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,4,4,4,4,4,4,5,4,4,4,5,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,3,3,4,4,4,4,4,6,7,8,9,10,11,10,10,12,13,14,15,17,17,19,19,19,18,19,19,19,21,19,21,23,21,23,24,23,22,23,23,24,22,24,25,23,23,23,22,23,24,23,23,23,22,22,24,22,21,21,22,22],[28,28,28,28,28,29,28,28,28,27,28,27,28,27,27,26,27,28,27,27,27,26,27,28,26,27,28,26,28,28,26,27,28,28,28,28,28,28,28,28,28,27,27,27,27,26,25,24,25,22,23,23,22,19,19,20,18,19,18,17,14,13,10,8,7,5,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,5,4,4,4,5,5,5,5,5,5,4,4,5,5,4,5,5,4,4,5,5,4,5,5,6,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,5,5,5,5,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,5,6,6,7,9,9,10,12,14,15,14,13,16,16,15,17,18,17,18,19,19,21,22,23,24,24,24,25,23,23,24,22,22,24,23,24,24,24,24,27,25,27,26,26,27,27,27,27,27,27,28,28,27,27,27,27,27,27,27,28,27,27,27,27,26,26,27,26,26,26,26,26,24,24,24,23,22,22,19,19,20,18,16,15,13,12,10,7,6,5,5,4,4,4,4,4,5,4,5,5,5,6,6,6,6,7,6,7,7,7,7,8,8,8,8,8,8,8,7,7,7,7,7,8,8,8,8,8,7,7,7,7,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,7,6,7,7,6,5,5,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,3,4,6,7,7,6,5,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,3,3,3,3,3,3,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,4,4,5,4,4,4,5,6,5,4,3,2,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,3,2,2,3,2,3,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,3,3,4,4,4,3,4,4,4,3,4,4,3,3,4,3,3,4,3,3,3,4,4,4,5,5,4,4,4,4,5,5,5,4,5,5,4,4,4,5,5,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,5,5,4,4,5,6,7,8,8,9,12,11,11,12,13,15,15,17,17,20,20,20,18,20,20,19,23,20,22,22,21,26,24,24,23,24,23,25,24,24,24,23,24,25,23,23,25,25,23,25,24,24,25,25,24,21,25,25],[29,28,29,29,29,29,29,28,29,28,28,28,27,28,27,27,28,28,27,27,27,26,27,27,25,28,28,27,28,28,25,28,28,29,28,28,28,29,28,28,28,27,27,27,27,26,24,24,24,23,23,23,22,20,19,20,18,17,18,17,14,12,9,6,5,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,2,3,3,3,3,3,5,5,6,8,8,11,12,12,11,12,15,14,13,16,16,15,16,18,19,20,20,20,22,24,23,24,23,23,23,23,22,22,23,24,23,23,23,26,25,27,25,26,26,26,26,26,26,26,26,26,26,27,27,26,26,27,27,27,27,27,26,26,26,26,27,26,25,25,24,26,24,23,23,23,22,22,19,19,19,18,17,15,14,11,10,7,5,4,4,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,7,7,7,7,7,7,7,6,6,6,6,6,7,6,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,6,6,7,5,4,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,1,2,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,3,3,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,3,3,3,4,4,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,5,6,7,8,9,10,10,10,11,12,13,14,16,17,19,19,19,17,19,18,19,22,19,22,21,22,24,24,23,23,24,23,24,24,24,24,23,24,24,21,22,24,25,23,24,23,24,23,25,24,21,24,26],[28,28,28,28,28,29,28,28,28,27,27,28,27,27,26,27,26,27,27,26,27,27,26,27,27,27,27,26,28,27,26,27,28,28,28,28,28,28,28,27,28,27,27,27,26,26,24,23,24,23,22,21,22,21,19,19,19,18,18,17,13,11,8,6,6,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,2,3,2,3,3,3,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,2,2,3,2,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,5,8,9,8,11,12,12,11,13,14,14,14,17,17,17,18,19,19,21,20,22,22,23,23,24,23,22,23,21,23,23,23,25,23,24,23,26,24,26,26,26,26,26,26,27,27,27,26,27,27,27,27,27,27,27,27,28,27,27,27,26,26,26,26,25,26,24,25,26,22,23,24,23,22,23,19,20,20,17,16,15,13,10,9,7,6,5,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,6,6,6,6,7,7,7,7,7,6,6,6,6,5,6,6,7,7,7,7,6,6,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,6,6,5,4,4,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,5,5,5,4,3,3,3,2,2,3,3,2,3,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,3,4,3,3,4,4,4,3,3,3,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,2,3,3,3,4,3,4,3,3,4,4,4,3,4,4,3,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,5,6,7,8,9,10,10,10,11,12,13,14,16,17,18,17,18,17,18,18,20,21,19,22,21,22,25,24,22,22,24,23,23,24,24,23,22,23,23,22,22,23,23,23,23,23,23,22,24,23,20,23,24],[28,28,28,28,28,28,28,27,28,27,27,27,27,26,26,26,26,27,26,26,27,26,26,27,26,26,27,26,27,26,25,27,27,27,26,27,27,27,27,27,27,26,26,26,25,25,24,23,23,22,22,21,20,20,18,19,17,17,17,16,13,11,9,6,5,3,2,2,2,2,2,1,2,1,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,3,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,4,5,8,7,10,10,13,13,12,13,14,14,13,15,16,16,16,18,19,19,20,21,20,22,22,22,21,21,21,20,20,21,21,23,21,22,22,25,23,26,25,24,25,25,26,25,26,26,25,25,26,25,26,26,26,25,26,26,26,26,25,25,25,25,25,25,25,23,23,25,22,23,22,23,23,22,19,19,19,18,14,14,13,10,9,6,5,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,5,5,5,5,5,5,5,6,5,5,5,5,5,5,4,5,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,5,5,5,5,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,3,5,5,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,5,6,7,8,9,9,8,10,11,12,13,15,16,18,18,17,16,17,18,17,20,18,21,20,20,24,24,23,22,23,23,23,22,23,23,22,21,24,20,21,23,23,21,23,21,21,22,24,21,20,23,22],[28,28,29,29,29,29,28,28,29,27,27,27,27,26,26,25,26,28,26,27,27,25,27,28,26,27,28,26,28,27,26,28,28,28,28,28,27,28,28,27,28,27,27,27,26,26,24,24,24,22,22,21,21,19,18,20,17,17,17,17,15,12,10,7,6,4,3,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,4,4,3,3,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,6,7,7,10,11,13,13,12,13,14,14,13,15,16,16,16,18,19,20,20,21,22,23,22,24,22,22,23,21,21,22,23,25,22,23,24,25,25,26,25,26,26,26,27,27,27,26,26,26,26,26,27,27,27,26,27,27,26,27,26,27,26,25,26,25,26,25,24,25,23,23,23,23,23,22,19,19,19,16,15,14,12,10,9,7,5,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,2,2,3,3,3,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,1,2,2,2,3,3,6,6,7,5,3,3,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,3,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,5,6,6,7,8,10,10,9,10,11,13,14,15,16,18,18,17,16,17,18,18,20,18,20,20,21,23,23,22,21,23,22,22,22,22,22,21,22,23,20,22,23,23,22,23,22,21,23,25,22,20,24,24],[28,28,28,28,28,28,27,27,28,27,27,27,27,27,26,26,26,27,26,26,27,26,27,27,25,28,28,25,28,28,26,28,28,28,28,28,28,28,28,27,28,27,27,27,26,25,24,24,24,23,23,22,22,21,19,20,18,17,17,16,13,12,9,6,5,4,3,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,3,3,4,4,3,3,4,4,4,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,3,3,3,5,6,8,7,11,13,12,10,11,13,13,12,15,15,16,17,17,18,20,19,20,21,22,22,23,22,22,22,20,21,22,22,24,23,22,23,25,25,26,25,25,26,26,25,26,26,26,26,26,26,26,27,26,26,26,26,27,26,27,26,26,25,25,26,24,24,24,23,25,22,22,23,22,22,21,19,19,18,17,15,14,12,10,9,6,5,4,3,3,2,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,6,6,6,6,6,6,6,6,5,5,5,4,5,6,5,6,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,2,2,2,3,3,5,5,6,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,1,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,3,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,6,6,7,8,10,10,9,10,13,13,14,16,16,18,17,17,16,18,16,18,20,19,21,20,21,24,23,21,22,24,22,23,23,23,22,22,23,22,21,23,23,22,21,23,21,23,23,24,23,20,24,24],[28,28,28,28,28,29,27,27,28,26,26,26,26,26,25,26,26,26,26,25,26,25,25,26,26,26,27,26,27,26,26,27,27,28,27,27,28,28,28,28,28,27,26,27,26,25,24,23,23,22,22,21,21,19,18,19,17,17,17,16,13,11,8,5,5,3,2,2,2,2,2,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,3,3,4,4,4,3,4,4,3,3,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,3,2,2,3,2,2,3,3,3,3,3,4,4,6,8,8,11,11,12,10,12,14,13,13,16,16,16,16,17,18,20,19,19,21,22,22,23,21,22,22,20,21,21,21,24,22,22,22,25,24,26,26,25,26,26,26,26,27,27,26,27,27,26,26,26,26,27,27,27,27,27,27,26,26,25,26,26,25,24,25,25,23,23,23,23,22,22,19,19,18,16,14,13,13,9,10,6,5,4,3,3,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,6,6,6,5,5,5,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,3,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,4,4,4,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,1,2,2,3,3,3,4,4,5,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,1,2,2,2,1,2,2,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,3,4,5,6,6,7,9,9,8,10,11,11,13,14,15,17,18,17,15,17,16,19,19,18,21,20,20,23,23,22,22,22,22,23,22,22,22,20,21,22,19,20,22,22,21,22,21,21,22,23,22,19,23,24],[29,28,28,28,28,29,28,27,28,27,27,27,26,26,27,26,26,27,26,26,27,26,25,27,27,27,27,27,28,27,26,27,27,27,27,27,27,27,27,27,27,26,26,26,25,25,25,23,23,23,23,22,21,20,18,19,18,17,18,17,14,12,9,6,4,4,3,2,2,1,2,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,2,2,2,2,2,2,2,3,3,3,3,4,5,6,8,9,11,13,13,11,11,13,13,14,15,15,16,17,17,18,20,19,20,21,22,22,23,22,22,22,22,19,22,22,23,22,22,22,24,24,27,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,25,25,26,26,25,24,24,25,23,23,22,23,23,21,20,18,19,17,14,14,11,10,8,6,4,4,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,5,5,5,5,4,4,4,4,4,5,5,5,5,4,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,2,1,2,2,3,3,3,5,5,6,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,2,2,1,2,2,1,1,2,2,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,4,5,5,5,6,8,8,8,8,11,12,12,15,16,17,18,16,15,17,17,17,19,18,20,20,21,22,24,22,22,22,23,24,22,22,22,21,22,22,20,21,23,23,22,23,22,21,21,24,21,20,23,23],[28,28,28,28,28,29,28,28,27,27,27,27,27,25,26,24,26,26,24,26,26,25,26,27,25,27,27,25,27,27,25,26,27,27,27,27,27,27,27,27,27,26,26,26,25,25,24,23,24,23,23,22,21,20,18,19,17,17,18,16,14,11,8,6,5,4,3,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,2,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,2,3,3,3,2,2,3,3,2,3,3,3,3,4,3,4,6,7,7,10,11,12,11,11,13,12,12,14,14,14,16,16,17,19,20,20,21,22,21,23,21,21,22,20,22,21,22,23,22,23,22,24,24,27,25,25,25,25,25,25,25,25,25,26,26,25,26,26,26,26,26,27,26,27,25,25,25,24,26,24,25,24,23,24,23,21,21,21,21,20,18,18,17,15,14,12,11,8,8,6,4,4,3,3,2,3,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,5,4,5,5,4,5,5,4,4,4,4,3,3,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,2,1,2,2,3,3,3,5,5,6,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,2,2,1,1,2,2,1,2,2,2,2,1,1,1,1,1,1,2,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,3,3,2,2,2,2,3,2,3,2,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,6,7,9,9,9,10,12,13,14,17,16,18,17,18,16,17,17,19,20,19,22,20,21,24,23,22,23,23,23,23,24,22,22,23,23,22,21,21,24,23,23,23,22,22,22,25,22,21,23,24],[28,28,28,28,28,29,27,27,27,26,27,27,26,25,26,24,25,27,25,25,26,25,25,27,26,27,28,26,28,27,26,27,28,28,27,27,27,28,28,27,28,27,26,27,26,25,25,24,24,23,23,22,21,20,19,19,17,17,18,16,13,11,8,5,5,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,3,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,3,3,3,3,4,4,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,2,3,3,3,2,3,2,2,2,3,3,2,3,3,3,5,5,6,7,12,12,11,9,10,13,12,12,14,14,15,16,17,18,19,18,20,21,21,22,23,22,21,22,21,21,21,22,23,22,22,23,25,25,26,26,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,26,27,26,26,25,25,26,25,25,24,24,25,23,23,22,22,21,20,19,18,18,16,14,13,12,9,8,6,4,4,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,5,4,5,5,4,5,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,1,1,2,2,2,2,3,3,3,5,5,5,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,3,4,3,4,3,3,3,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,1,2,2,1,1,2,2,1,2,2,2,2,1,1,2,1,1,1,2,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,3,2,2,2,2,2,2,3,2,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,4,5,5,6,7,9,8,8,10,12,12,14,16,16,18,16,17,16,16,17,19,20,18,21,20,20,23,23,22,22,23,22,22,23,22,21,21,22,22,20,21,23,22,23,23,22,22,21,24,22,19,23,23],[28,27,28,28,28,28,27,27,28,26,27,27,26,25,26,25,26,27,26,26,26,25,25,26,26,25,26,26,27,26,25,26,27,27,27,27,27,27,28,26,27,26,26,26,25,24,23,22,23,22,21,21,20,19,18,19,17,16,17,16,14,11,8,6,4,3,3,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,4,3,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,3,4,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,3,3,3,2,2,2,2,2,3,3,2,3,3,3,4,7,8,8,11,12,12,10,10,13,12,12,14,14,14,15,16,17,17,18,18,19,21,21,22,20,20,21,20,19,20,20,22,21,20,22,24,22,25,24,24,25,26,26,27,26,26,26,26,26,26,26,26,26,26,26,27,26,26,25,24,24,24,26,24,25,24,24,24,24,22,23,22,23,22,20,20,18,17,14,13,13,10,9,6,5,4,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,3,3,3,4,4,5,4,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,1,2,2,2,2,2,2,2,3,2,2,2,2,2,3,3,3,3,3,3,4,4,3,4,3,4,3,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,1,1,2,2,1,2,2,2,2,1,1,2,1,1,1,2,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,3,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,5,6,8,7,8,9,10,11,13,15,15,16,18,16,14,16,17,17,19,17,21,20,20,23,22,22,21,23,22,22,22,22,21,19,23,22,19,19,23,22,21,21,20,20,21,23,21,19,22,22],[29,29,29,29,29,28,28,28,27,27,27,26,27,24,26,24,26,26,25,26,27,26,25,27,26,26,27,26,27,27,26,27,27,27,27,27,27,27,27,27,27,27,26,26,26,25,25,24,24,23,23,22,21,20,19,19,18,17,17,16,13,11,8,5,4,3,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,4,4,3,3,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,4,3,3,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,3,2,2,3,3,2,3,3,3,4,5,6,7,10,12,12,10,11,13,12,12,14,15,15,15,17,18,19,19,19,21,22,21,23,21,21,21,21,21,21,21,23,21,21,21,25,25,27,26,25,25,26,25,26,25,25,25,25,25,26,26,25,25,26,26,26,25,26,25,25,25,25,25,25,25,24,24,25,23,23,22,23,23,21,19,19,18,16,14,12,12,9,8,6,4,4,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,5,4,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,5,5,6,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,3,3,3,3,3,4,4,4,4,3,4,3,4,3,3,3,3,4,3,3,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,1,2,1,1,2,2,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,3,3,2,2,2,2,2,3,3,2,3,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,4,5,5,6,8,8,9,10,13,12,14,16,16,18,19,17,16,17,17,18,22,18,20,20,20,24,22,21,23,23,21,23,23,21,21,22,23,21,20,21,22,22,21,21,21,22,22,23,21,20,23,22],[29,28,28,28,28,28,27,27,27,27,27,26,27,25,26,24,26,26,26,26,26,26,26,27,25,27,28,26,28,27,26,27,28,27,27,27,26,27,28,27,27,26,26,26,26,26,25,24,25,23,23,22,22,20,19,20,19,18,18,17,14,12,8,6,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,4,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,4,4,3,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,2,2,3,3,4,4,3,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,3,2,2,3,2,2,3,3,3,3,3,4,4,6,6,7,10,12,12,11,11,13,12,12,14,14,15,16,16,18,20,19,21,22,23,22,23,22,21,22,21,21,21,22,23,22,22,22,25,25,27,25,26,26,25,25,25,25,26,25,26,26,25,26,25,26,25,25,27,26,26,25,26,25,25,26,24,25,24,23,25,23,22,22,22,22,21,18,19,17,16,15,12,12,9,8,6,4,4,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,5,5,5,5,5,4,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,3,3,4,6,6,6,4,3,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,2,2,1,2,2,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,2,2,3,2,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,4,5,6,6,7,9,9,9,10,13,13,14,17,16,19,18,19,17,18,18,19,21,20,21,21,21,24,23,23,23,24,23,24,24,23,23,23,24,23,21,22,23,23,23,22,23,22,23,24,21,21,24,23],[28,28,28,28,28,28,27,27,27,26,26,27,26,24,26,25,26,26,26,26,25,25,25,26,25,26,27,26,27,27,26,28,27,27,27,27,27,27,28,27,27,27,27,27,26,25,25,24,24,23,23,22,21,21,19,20,19,18,17,17,14,13,9,6,4,4,3,3,3,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,6,6,6,5,4,5,5,5,5,5,5,5,4,4,5,5,4,5,5,4,4,5,4,4,5,5,5,5,4,4,5,4,4,4,4,3,3,4,4,3,4,4,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,3,4,4,4,4,3,3,3,4,3,3,3,3,3,3,4,3,3,3,4,4,5,4,4,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,2,2,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,3,3,3,3,2,2,3,3,2,2,3,3,3,3,4,4,5,6,8,9,12,13,13,12,11,14,13,14,16,17,15,17,17,19,21,20,21,21,23,22,23,22,20,22,20,19,20,22,22,20,20,23,25,24,27,25,26,26,26,26,27,27,26,26,27,27,27,27,27,28,26,26,27,26,27,25,26,26,25,27,25,26,25,24,26,24,24,24,23,24,22,21,20,19,17,14,14,12,11,9,7,5,4,3,3,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,4,5,6,6,6,5,5,5,4,4,4,4,5,4,6,6,4,5,5,4,4,4,4,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,5,5,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,6,5,6,4,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,1,1,2,1,1,1,2,1,1,2,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,5,5,4,5,4,5,4,4,4,4,4,4,4,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,4,5,7,6,8,9,8,9,9,12,13,14,16,17,20,20,18,17,18,18,19,22,20,22,21,20,24,25,22,23,24,23,24,24,24,22,22,22,23,19,21,24,22,23,22,22,21,21,24,21,21,23,23],[28,28,28,28,28,28,27,27,27,26,26,26,26,25,26,24,25,26,25,25,25,25,25,25,25,25,26,26,26,26,26,26,27,27,26,27,26,26,27,26,26,25,25,26,25,25,23,23,23,23,22,22,20,19,17,18,17,15,16,16,12,10,8,5,4,4,3,2,3,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,5,6,6,5,5,4,4,5,5,5,5,5,5,4,4,5,4,4,4,5,4,4,5,4,4,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,3,4,4,3,4,4,4,3,4,4,4,3,3,3,4,3,3,3,4,3,3,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,2,3,2,2,2,2,2,2,3,2,2,3,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,4,5,6,6,7,9,11,11,10,11,13,12,12,14,16,15,13,16,18,19,19,19,20,21,21,22,21,19,20,21,20,20,20,22,20,21,21,24,24,26,25,25,25,26,26,26,26,26,26,26,26,26,27,27,26,26,27,26,26,26,25,25,25,25,25,25,25,24,23,24,23,23,22,22,22,20,19,20,19,17,15,13,13,10,9,7,5,4,3,3,2,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,5,6,5,5,5,4,4,4,4,5,4,6,6,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,5,4,5,4,4,4,4,4,4,4,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,1,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,2,3,3,3,3,3,3,3,3,3,3,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,6,6,7,8,8,8,9,12,12,14,15,16,19,19,17,15,17,18,17,20,17,20,19,20,23,23,24,22,22,22,23,22,21,23,21,23,21,19,20,22,23,20,22,20,22,22,22,20,19,22,20],[29,29,29,29,29,28,28,28,28,28,28,27,28,25,27,25,27,27,27,28,27,27,27,28,26,27,28,27,28,28,26,27,28,27,27,28,27,27,28,28,28,27,27,27,26,26,26,24,25,24,23,22,23,20,19,19,18,17,17,17,13,11,8,6,5,4,3,3,3,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,6,5,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,5,4,5,5,4,5,5,6,5,5,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,3,4,4,4,5,4,5,4,3,4,4,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,3,3,4,3,3,4,4,3,3,3,4,3,4,4,4,5,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,6,7,8,10,12,12,11,12,13,13,12,14,15,16,16,17,18,21,20,21,22,22,22,24,21,21,22,21,22,21,21,24,22,22,22,24,25,28,26,26,25,26,25,26,26,26,26,26,26,26,26,26,26,26,26,27,26,27,27,26,26,26,27,26,26,25,25,25,23,24,23,23,22,21,19,20,18,17,15,13,12,10,9,7,5,4,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,6,6,6,5,5,5,5,4,4,4,5,5,6,6,5,5,5,4,4,5,4,4,4,4,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,6,6,6,4,3,3,3,3,3,3,3,3,3,4,4,5,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,4,4,3,3,3,4,4,4,4,4,5,5,5,6,5,5,5,5,5,4,5,5,5,4,4,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,6,6,7,9,9,10,11,14,14,15,17,16,20,19,18,17,18,18,19,22,20,22,21,22,25,23,23,22,22,22,25,23,23,23,22,23,23,21,22,23,22,22,22,22,21,22,23,20,21,23,23],[28,28,28,28,28,28,28,28,27,27,27,26,27,24,26,24,26,26,26,27,27,27,27,27,27,27,28,27,28,28,27,27,28,28,28,28,27,28,28,28,27,27,27,27,27,26,25,24,24,23,22,22,22,21,19,20,19,18,17,17,15,13,9,7,6,5,4,4,4,3,3,2,3,2,3,3,3,4,4,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,8,8,7,6,6,6,7,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,5,5,6,6,6,6,6,5,6,6,5,5,5,4,5,5,5,4,5,5,4,4,4,5,5,5,6,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,4,5,4,4,5,5,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,5,5,5,5,5,5,5,5,5,6,5,5,5,4,5,4,5,4,4,4,4,3,4,4,4,3,4,4,3,3,3,4,3,3,4,3,3,4,4,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,3,3,4,3,3,4,4,4,5,4,4,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,2,3,3,2,2,2,3,2,2,3,3,2,3,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,4,4,3,3,4,4,4,4,5,6,6,7,9,9,11,13,13,12,12,14,13,13,15,15,14,15,16,18,19,19,21,21,22,22,23,21,21,22,21,20,21,22,24,21,22,23,25,26,28,27,27,26,27,27,27,27,27,26,26,27,27,27,26,27,26,27,27,27,27,26,27,25,25,27,25,26,25,25,26,24,22,24,23,23,21,20,20,19,18,16,14,13,11,11,8,6,5,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,6,6,5,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,3,2,2,3,3,3,3,3,3,4,4,4,5,5,5,6,5,5,4,4,3,4,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,4,4,5,7,7,7,5,4,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,1,1,2,2,1,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,5,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,4,4,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,2,2,3,3,3,3,3,2,3,3,3,3,3,4,4,3,3,3,4,3,3,3,3,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,5,6,7,7,8,9,9,11,10,14,14,15,17,17,19,17,18,17,18,18,18,21,19,20,20,22,23,23,23,22,22,22,24,22,22,22,22,22,23,20,22,22,22,21,22,21,21,22,23,20,20,23,21],[28,27,28,27,28,28,27,27,28,26,26,26,26,24,26,24,26,26,25,26,26,26,26,26,26,26,27,26,27,27,26,27,27,27,27,27,26,27,27,27,27,26,26,26,26,26,25,24,24,24,22,22,22,21,19,21,19,18,17,17,15,13,10,8,7,6,5,5,5,4,4,4,4,3,4,4,5,5,5,5,4,5,5,4,4,5,5,5,5,5,6,7,6,6,7,7,6,7,8,7,7,8,8,8,8,9,9,9,9,10,10,9,8,7,8,8,8,8,8,8,8,7,7,8,8,7,7,8,7,7,8,7,6,7,8,8,8,7,7,8,7,7,7,7,6,6,7,7,6,7,7,6,5,6,7,6,7,7,7,8,7,6,6,7,6,6,6,6,6,6,6,6,5,6,7,6,6,6,6,6,6,5,5,6,5,5,5,6,5,5,6,5,5,5,6,7,7,7,6,7,7,7,7,7,7,7,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,4,5,5,4,4,5,5,5,5,5,5,6,6,6,7,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,3,4,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,3,4,4,4,4,4,4,5,5,6,7,7,8,9,10,12,14,15,12,14,15,15,15,17,17,16,18,19,18,20,20,22,22,24,22,24,22,20,22,20,20,20,22,23,19,20,23,24,25,27,25,26,25,25,27,27,27,27,27,26,26,27,27,27,27,27,27,26,27,27,26,26,25,25,26,25,26,25,25,26,23,24,24,24,23,22,22,21,20,18,17,16,14,14,12,9,7,5,4,4,4,4,3,3,3,3,4,3,3,4,5,4,4,5,5,5,6,6,7,6,7,7,7,7,7,7,6,5,6,5,6,6,6,8,7,6,7,6,6,6,5,5,5,5,5,5,4,4,4,4,3,3,3,2,3,3,3,3,3,3,3,4,3,3,4,4,4,5,6,6,6,7,7,6,6,5,5,5,5,5,4,4,4,4,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,6,6,5,5,4,4,4,4,5,4,5,5,6,6,7,7,7,7,7,7,7,6,6,5,5,5,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,2,3,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,3,3,4,4,4,4,4,5,5,6,6,5,6,6,6,6,7,7,7,7,7,8,7,7,8,7,7,7,6,6,7,6,6,6,5,5,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,1,2,2,1,1,0,1,1,1,2,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,3,3,3,3,4,4,4,5,4,4,4,4,4,4,4,4,4,4,3,3,4,3,2,2,3,3,3,3,3,3,3,4,4,3,4,3,4,4,4,4,4,5,4,3,3,3,2,2,3,3,2,3,4,3,3,4,4,4,4,4,4,4,4,5,6,7,8,8,9,10,10,10,10,14,14,16,17,18,21,20,19,17,19,20,19,22,19,22,21,21,25,24,24,24,25,24,25,25,24,24,23,24,23,21,23,25,23,21,23,22,21,23,24,20,20,22,20],[27,27,27,28,28,27,28,27,27,27,26,26,27,24,27,24,27,26,26,27,26,25,27,27,26,27,27,27,27,28,27,28,28,28,27,28,28,28,28,28,28,27,27,28,27,26,26,25,25,25,23,23,23,22,21,21,19,19,17,18,16,13,11,9,7,7,6,5,5,5,5,4,5,4,5,5,5,6,6,5,5,7,6,5,6,7,7,7,8,8,8,9,9,9,10,10,9,10,11,10,11,11,11,10,12,12,12,12,12,13,13,12,11,11,11,11,11,12,11,11,11,10,10,11,11,10,10,11,10,10,11,10,9,10,10,10,10,10,10,10,10,9,10,10,9,9,9,9,8,9,9,8,8,8,9,9,9,10,9,10,9,8,8,9,8,7,9,9,8,7,8,9,8,8,9,9,8,9,8,8,9,7,8,8,8,8,8,8,8,8,8,7,7,8,9,10,10,10,9,10,10,10,10,10,9,9,9,8,8,8,8,9,8,8,8,8,7,8,8,7,7,8,7,6,7,7,6,5,6,7,5,6,7,7,8,9,8,9,9,8,8,8,8,8,7,7,8,7,6,7,7,6,6,7,8,7,8,8,8,7,7,6,6,6,6,6,6,7,6,6,6,7,6,6,6,7,8,7,7,7,7,6,6,5,6,6,5,5,5,6,5,5,6,5,5,5,6,5,5,4,4,5,5,5,4,5,5,4,5,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,4,5,4,4,5,6,6,6,6,7,7,9,10,10,13,14,14,14,14,16,15,15,16,18,17,17,19,21,20,21,23,22,24,22,24,21,20,22,21,19,21,21,21,20,21,22,25,26,26,24,25,25,25,26,27,26,26,26,26,26,26,27,26,27,26,27,26,27,27,26,26,25,26,26,25,26,25,25,26,24,25,26,24,24,24,22,23,22,19,17,17,16,14,12,10,8,7,6,5,5,5,5,4,4,4,4,4,5,4,5,5,5,7,6,7,7,7,8,7,8,9,9,8,8,8,7,7,8,7,7,9,8,9,9,7,9,8,7,7,8,6,6,5,7,6,5,6,5,5,4,4,4,3,4,4,3,4,4,3,4,5,4,4,6,6,5,6,7,7,9,9,8,8,8,7,7,6,6,7,6,6,5,6,6,6,5,6,6,6,6,6,6,5,5,5,6,5,6,6,5,4,5,6,5,6,6,5,5,5,6,6,7,8,9,9,7,7,6,7,6,7,7,6,7,8,8,9,9,9,9,10,10,9,9,8,9,8,8,8,7,7,7,7,6,5,6,5,5,5,6,5,5,5,5,4,5,5,6,4,4,6,4,4,5,5,4,4,5,4,4,4,5,4,3,4,5,3,3,5,5,4,4,4,4,4,5,5,4,5,5,5,4,4,6,5,5,5,5,5,5,4,5,5,6,6,6,7,7,8,8,7,8,8,8,9,9,9,10,10,10,10,10,10,10,10,10,10,9,9,9,8,8,8,7,6,5,5,5,5,5,4,4,4,4,3,4,5,3,3,3,3,2,2,3,2,1,0,1,2,2,2,2,3,3,4,5,5,4,5,4,4,5,4,4,5,5,5,4,5,4,5,4,4,4,4,4,3,3,3,3,2,3,3,3,3,4,4,4,4,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,3,5,4,5,5,5,4,6,5,6,5,6,5,7,6,5,4,4,5,4,4,4,3,3,3,4,3,3,4,4,4,4,5,5,5,6,6,6,6,6,7,8,9,10,10,10,12,10,12,12,15,15,18,20,19,22,22,21,20,22,23,19,23,20,22,24,22,25,24,24,25,24,25,27,25,24,24,23,23,22,21,22,24,24,22,24,22,22,24,24,21,19,23,22],[29,29,29,29,29,28,28,29,27,27,27,27,28,25,27,25,26,26,26,27,27,26,26,27,26,26,28,27,27,28,27,28,28,28,27,28,28,28,29,28,27,27,27,27,27,26,26,24,25,24,23,23,23,21,19,20,19,17,18,18,14,12,10,8,7,6,6,5,5,5,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,6,6,6,6,7,7,7,7,7,7,8,7,8,8,9,8,9,9,8,9,10,9,10,10,11,11,10,8,9,8,9,8,9,8,8,9,8,8,9,9,8,8,8,8,7,8,8,7,8,8,9,8,8,8,8,8,7,8,8,7,7,8,7,7,8,7,7,6,6,8,7,8,8,8,8,8,7,7,7,7,6,7,7,6,6,7,7,6,7,7,7,6,7,7,7,7,6,6,7,6,6,6,7,6,6,6,6,6,6,7,8,8,7,7,7,8,7,7,8,7,7,7,7,6,7,7,6,7,7,7,6,6,6,6,5,5,6,6,5,5,6,5,5,6,5,5,5,6,6,7,6,6,7,7,7,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,6,6,6,6,5,5,5,5,4,5,5,4,5,5,4,4,5,5,5,5,5,5,6,6,5,6,5,5,5,5,5,5,5,5,4,4,4,5,4,4,5,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,5,5,6,6,6,9,10,9,12,13,13,12,13,15,14,14,15,17,18,17,18,20,22,21,22,23,24,22,24,22,20,21,21,21,20,22,23,20,21,22,24,25,27,26,26,26,26,27,27,26,26,26,26,27,27,27,27,27,27,27,27,26,26,26,26,26,26,27,25,26,25,24,26,23,24,23,23,23,23,21,21,20,19,17,16,14,12,11,9,7,6,5,4,4,4,3,3,3,4,4,4,4,4,4,5,5,6,6,6,7,7,7,7,7,7,7,7,8,7,6,6,6,5,5,6,6,7,7,6,6,7,6,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,7,6,6,6,6,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,4,3,4,4,5,4,4,4,4,4,4,4,4,4,5,5,6,7,8,7,6,6,5,5,5,5,6,5,5,6,7,7,8,7,7,8,8,7,7,7,7,6,7,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,2,3,3,2,3,3,3,2,3,3,2,2,3,3,3,2,3,3,2,3,3,3,3,2,2,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,5,5,5,6,6,6,7,7,6,7,7,7,7,7,8,7,8,8,8,8,8,8,8,8,7,7,7,7,7,7,6,5,5,5,5,5,4,4,4,4,4,4,3,4,3,3,2,2,2,2,2,1,1,1,1,0,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,3,3,3,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,4,4,4,4,3,4,4,4,4,4,4,4,3,3,3,4,3,2,3,3,2,2,3,3,2,3,3,3,3,3,4,3,4,3,4,4,4,4,6,7,8,8,9,11,10,12,12,16,16,16,18,18,23,20,19,20,22,21,19,25,21,23,24,22,26,25,26,25,24,24,27,25,25,24,24,25,25,22,23,26,25,22,25,23,23,24,25,20,21,25,22],[29,28,28,28,28,28,28,27,27,27,26,26,26,24,26,25,26,25,25,27,25,26,26,26,26,26,27,26,27,27,26,27,28,28,27,28,27,28,28,28,28,27,27,27,27,26,26,25,25,24,24,23,23,22,20,21,19,18,17,16,14,12,10,8,7,6,5,5,5,5,5,4,4,4,4,5,5,6,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,9,8,9,9,9,10,10,10,11,10,10,9,9,8,9,9,9,9,9,9,8,7,8,9,8,7,9,8,7,8,8,7,7,8,8,8,7,8,8,7,7,7,7,7,7,7,7,7,8,7,6,6,6,7,8,8,8,7,8,7,7,7,7,7,7,7,7,7,6,7,7,6,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6,6,7,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,5,5,5,5,4,5,6,6,7,7,7,7,7,7,7,6,6,6,6,6,5,6,5,5,5,5,4,5,5,5,6,6,5,5,4,5,4,4,5,4,4,4,5,4,4,4,5,4,4,5,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,7,9,8,9,12,12,13,11,11,14,14,13,14,16,16,17,18,20,21,20,22,22,24,23,24,21,20,22,22,20,20,22,23,19,21,23,24,25,27,26,27,26,26,27,27,27,26,27,27,27,27,28,28,28,27,28,27,27,27,26,27,24,26,26,25,26,26,25,27,24,24,25,23,23,22,22,21,20,20,17,15,14,11,10,8,7,5,4,4,4,4,3,3,3,3,4,3,3,4,4,4,5,5,5,6,5,6,6,7,7,7,7,7,7,6,6,6,5,5,5,6,6,7,8,6,7,7,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,4,4,5,5,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,5,7,7,6,6,5,4,5,4,5,5,5,5,6,6,7,7,7,7,7,7,7,7,6,6,6,6,6,5,6,5,5,5,5,5,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,2,3,2,3,2,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,5,6,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,7,7,7,7,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,7,8,7,9,10,10,11,11,14,15,16,17,17,21,20,20,19,21,20,20,23,21,22,24,22,25,23,25,25,24,23,25,24,24,25,24,24,23,21,23,24,24,21,24,23,22,24,24,21,21,24,23],[29,28,28,28,28,28,28,27,27,26,27,26,26,24,26,25,26,26,25,26,25,25,27,26,25,26,27,26,27,26,25,27,28,28,27,27,27,28,28,28,28,27,26,27,27,26,26,24,25,24,22,22,22,22,20,21,20,20,18,17,15,13,10,8,7,6,5,5,5,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,5,5,5,6,5,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10,9,8,8,8,9,8,9,8,8,8,8,7,8,8,7,7,8,7,7,7,7,6,7,7,8,7,7,7,7,7,6,7,7,7,6,7,7,6,7,7,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,7,7,7,7,7,6,6,6,7,6,6,6,6,6,6,5,5,6,5,5,5,5,5,6,6,7,7,6,6,7,7,6,6,7,6,6,6,6,6,6,6,5,5,6,6,5,5,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,6,6,7,7,7,7,7,7,7,7,6,6,6,5,5,6,5,5,5,5,5,5,5,5,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,5,5,4,4,5,5,5,6,5,6,7,9,8,9,11,12,13,12,12,13,14,14,13,16,18,16,17,20,21,20,21,22,23,22,23,23,20,22,21,20,20,22,22,20,21,24,24,24,26,26,26,26,26,27,27,27,27,27,27,27,28,28,28,28,27,27,26,27,27,26,27,24,26,26,26,27,26,26,26,24,24,24,24,23,23,22,22,20,21,17,17,14,12,10,8,7,5,5,5,4,4,4,3,3,4,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,7,7,7,6,6,6,6,5,5,5,6,6,7,7,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,6,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,6,7,6,5,5,4,4,4,4,5,5,5,5,6,7,7,6,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,6,6,6,6,6,6,6,7,7,7,7,7,8,8,7,8,7,7,7,8,7,7,7,7,7,6,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,4,3,3,3,3,3,4,3,3,3,3,3,3,4,4,3,3,3,3,4,4,3,3,4,4,3,3,3,4,3,3,3,2,2,2,2,3,3,2,3,3,3,3,4,4,4,4,4,4,4,4,6,7,8,8,10,11,11,12,12,15,16,15,18,17,20,20,18,20,20,20,20,25,20,24,23,23,26,24,24,26,25,24,26,26,24,25,25,26,23,24,24,25,26,22,26,24,23,25,25,21,23,26,24],[29,29,29,29,29,29,28,28,28,28,28,26,28,24,27,25,27,27,26,28,27,26,27,27,26,27,28,26,28,28,26,28,28,29,27,28,28,28,28,28,28,28,27,27,27,26,26,24,25,24,23,23,23,22,19,21,20,18,18,19,14,11,9,7,6,5,4,4,4,3,3,3,3,3,4,3,4,4,4,4,4,4,4,3,4,4,4,5,5,5,5,5,5,5,6,5,6,6,6,6,6,6,7,6,7,7,7,7,7,8,8,7,7,6,6,7,7,7,7,7,7,6,6,7,7,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,5,6,6,5,5,6,6,5,6,6,5,5,5,6,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,6,5,5,5,6,5,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,6,6,6,5,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,5,5,6,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,5,5,5,4,4,4,4,3,3,4,3,3,3,4,3,3,3,4,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,4,4,4,4,5,7,8,8,11,14,14,12,11,14,14,13,14,17,18,16,18,20,22,21,22,24,24,23,24,22,20,22,21,21,21,21,22,22,21,23,24,24,27,26,26,26,26,27,27,27,27,28,28,27,28,28,28,28,28,28,28,28,28,27,28,26,26,28,26,28,27,26,27,25,24,24,24,24,25,21,21,21,20,18,16,15,12,9,7,6,5,4,4,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,5,7,6,6,5,4,3,4,3,4,5,4,4,4,5,5,6,5,5,6,6,5,6,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,2,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,4,4,4,5,5,5,4,5,5,5,5,6,6,6,6,6,6,7,6,6,6,7,6,6,5,6,6,5,5,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,1,2,2,1,1,2,2,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,3,4,3,3,3,3,4,3,3,3,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,5,6,7,7,8,10,10,11,12,14,17,16,18,19,20,20,18,19,22,20,20,24,21,24,24,22,26,24,25,26,26,24,26,25,25,24,25,26,25,24,24,26,25,22,25,23,24,25,26,22,23,26,24],[29,29,29,29,29,29,28,28,28,27,28,27,27,25,26,25,26,26,26,27,27,27,26,28,27,26,28,27,28,27,27,28,28,29,28,28,28,28,29,29,29,28,29,28,28,27,27,26,26,24,25,23,23,22,20,20,19,18,18,17,14,12,9,7,6,5,4,4,4,3,4,3,3,3,4,4,4,5,5,4,4,4,4,4,4,5,4,5,5,5,5,5,5,6,6,6,6,6,7,6,6,7,7,7,7,8,8,8,8,9,9,8,7,7,7,8,7,7,7,7,8,6,6,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,6,6,5,5,6,5,5,5,5,5,5,4,5,5,4,4,5,5,4,5,5,6,6,6,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,3,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,5,6,8,7,10,12,13,11,11,14,13,12,14,17,15,15,17,19,20,19,22,22,23,23,24,23,21,22,21,21,22,23,23,22,23,24,26,27,29,28,28,28,28,28,29,28,28,28,28,28,29,29,29,28,28,29,28,28,28,27,28,27,26,27,26,26,27,26,27,25,24,24,24,24,23,23,20,20,19,16,16,15,11,10,8,6,5,4,4,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,6,5,5,6,6,6,6,6,6,5,5,5,5,5,6,6,6,6,5,6,6,5,5,5,4,4,4,5,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,4,5,6,6,6,5,4,4,4,3,4,4,4,4,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,7,6,7,6,6,6,6,6,6,6,6,6,5,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,3,3,2,2,3,3,3,2,3,2,2,2,2,2,2,3,3,2,2,2,3,3,3,3,3,2,3,3,3,3,3,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,5,6,7,7,9,9,9,10,11,14,14,16,18,18,21,20,20,19,21,20,20,23,21,23,24,22,24,25,24,25,25,24,25,24,24,25,24,24,24,22,23,25,25,22,24,24,24,24,25,22,22,25,24],[29,28,28,28,28,28,28,27,27,27,26,27,26,24,26,25,26,26,26,26,26,26,27,27,26,27,27,26,28,26,26,27,27,28,27,28,27,28,27,27,28,27,27,27,27,26,25,24,24,23,23,21,21,21,19,18,19,18,16,16,13,11,9,7,6,5,5,5,4,4,4,4,4,3,4,4,5,5,5,5,4,5,5,4,4,5,5,6,5,5,5,6,6,6,7,6,6,7,7,7,7,7,7,7,8,8,8,8,9,9,9,8,8,7,7,8,8,7,7,8,8,7,7,8,7,7,7,8,7,6,7,7,6,6,7,7,7,6,6,7,7,6,7,7,6,6,7,6,6,7,6,6,6,6,6,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,6,5,5,5,5,5,5,5,6,6,6,5,6,6,6,5,6,6,6,6,5,6,6,6,5,5,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,5,5,5,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,5,5,5,6,7,7,8,11,10,12,11,9,11,12,12,12,13,15,15,15,19,20,19,20,22,22,22,23,21,22,22,21,18,20,22,21,20,20,23,24,23,26,26,27,27,26,27,27,27,27,27,27,27,28,28,27,27,27,28,27,27,27,26,26,25,25,26,25,25,26,25,26,23,24,25,24,24,23,22,22,20,20,17,15,13,11,9,8,6,5,4,4,3,4,4,3,3,3,3,3,3,4,4,4,4,5,5,4,5,6,6,6,6,7,7,7,6,7,6,6,5,5,6,6,6,7,7,6,6,6,6,5,5,5,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,6,6,6,5,5,5,5,5,4,4,4,4,3,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,6,5,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,4,5,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,6,6,6,6,6,7,6,6,7,7,7,6,6,6,7,6,6,6,6,6,6,5,6,5,5,4,4,4,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,5,6,8,7,9,10,9,10,12,14,15,17,19,19,21,20,20,19,21,20,20,23,21,23,24,23,26,24,25,24,24,23,26,26,23,25,25,24,23,23,25,25,25,22,25,25,23,24,26,22,22,25,24],[29,28,28,28,29,28,28,27,27,27,26,25,27,23,25,23,26,25,25,26,25,24,26,27,25,27,27,25,27,27,25,27,27,27,26,27,26,27,27,27,27,27,27,27,27,26,24,23,24,23,23,22,21,21,19,19,20,18,17,16,14,12,9,7,6,5,4,4,4,4,4,3,3,3,4,4,4,4,5,4,4,4,4,4,4,5,4,5,5,5,5,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,8,7,6,7,7,7,7,7,7,8,6,6,7,7,6,6,7,6,6,7,6,6,6,7,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,5,5,6,6,6,6,6,7,6,5,6,6,6,6,6,6,6,6,6,6,5,6,6,5,6,6,6,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,6,6,6,5,6,6,5,5,6,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,5,4,4,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,5,4,4,4,5,5,5,6,6,5,4,5,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,4,4,4,4,3,3,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,7,7,9,11,12,12,12,11,13,12,13,13,14,16,15,15,18,21,19,20,22,22,21,23,21,21,21,19,19,21,21,22,21,20,21,25,23,26,25,26,25,25,26,26,26,26,26,26,26,27,27,27,27,27,27,27,26,27,26,27,24,25,25,25,26,26,25,26,25,24,25,23,24,24,20,21,21,19,17,15,14,12,9,8,6,5,4,4,4,4,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,6,6,6,6,5,5,6,6,6,7,7,6,6,6,5,5,5,5,4,4,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,6,6,6,6,5,5,5,4,5,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,2,3,3,3,3,3,4,5,7,7,6,5,3,3,4,3,4,4,4,4,4,5,5,5,5,5,6,6,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,2,3,3,3,3,3,3,2,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,5,6,7,7,9,10,10,10,11,14,15,17,19,19,21,20,19,20,20,21,20,23,21,24,24,22,26,24,25,24,26,23,26,25,25,25,25,25,24,23,25,26,25,24,25,25,25,24,25,23,23,25,25],[29,29,29,29,29,29,28,28,28,27,27,27,27,25,26,25,26,26,26,27,26,26,27,28,26,28,28,26,28,28,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,27,25,26,25,25,23,23,23,21,21,19,20,20,17,14,12,8,6,5,5,4,4,4,3,4,3,3,3,4,4,4,4,5,4,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,9,9,8,7,7,7,7,7,7,7,7,7,6,6,7,7,6,6,7,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,5,5,6,6,5,6,6,5,5,5,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,6,5,5,5,6,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,4,4,4,5,4,4,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,5,5,4,4,4,3,3,4,3,3,3,4,3,3,4,3,3,3,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,4,3,3,4,4,3,3,3,3,4,4,3,3,4,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,5,5,7,7,8,11,14,12,11,11,12,12,12,14,15,14,15,15,18,19,19,21,22,23,23,24,22,23,23,21,19,22,22,23,21,22,24,24,25,28,26,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,28,28,26,27,28,26,27,27,26,26,25,24,24,24,24,23,21,20,20,19,16,15,13,11,10,7,6,5,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,6,6,7,6,5,6,6,5,5,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,5,5,6,6,5,6,5,4,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,4,4,7,6,5,4,4,3,4,3,4,4,4,4,4,5,5,6,5,5,6,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,6,6,6,6,5,6,6,5,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,3,2,2,2,3,3,3,3,3,2,2,3,3,3,2,3,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,10,11,14,14,16,18,17,21,21,19,18,20,20,21,24,21,24,22,23,26,25,24,24,25,24,25,26,25,25,23,25,25,23,23,25,25,24,25,24,25,24,26,23,22,24,25],[28,28,27,28,27,27,27,26,27,26,25,26,25,24,24,25,25,25,26,26,25,25,26,25,25,26,26,25,26,25,24,26,27,27,26,26,25,26,26,26,27,26,26,26,26,26,26,23,23,23,23,20,20,21,19,19,18,18,16,15,13,11,8,6,6,5,4,4,4,3,4,3,3,3,4,4,4,5,5,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,6,6,7,7,7,7,8,8,8,8,9,9,8,7,7,7,7,7,7,7,7,8,6,6,7,7,6,7,7,7,6,7,7,6,6,7,7,7,6,6,7,6,6,6,6,6,6,6,6,5,6,6,5,6,5,6,6,6,7,6,7,6,6,6,6,6,5,6,6,6,5,6,6,5,6,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,6,6,6,5,6,5,6,5,5,5,5,6,5,5,6,5,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,4,5,5,6,6,6,6,6,6,6,6,5,5,6,5,5,5,5,4,4,5,4,4,4,5,5,6,5,5,4,4,4,3,3,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,5,4,4,3,4,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,4,5,6,6,7,10,9,10,10,10,11,12,10,11,13,13,12,13,16,16,17,19,19,21,19,22,20,20,21,18,18,18,20,20,18,20,23,24,23,26,25,26,26,26,27,27,27,27,27,28,28,28,28,28,28,28,28,27,27,28,27,26,26,26,26,25,25,25,25,26,24,23,23,23,22,21,20,20,19,18,15,13,13,10,9,7,6,5,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,5,6,6,5,6,6,6,6,6,6,6,5,5,5,6,6,6,7,7,6,6,6,5,5,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,6,6,6,6,5,5,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,7,6,6,5,4,3,4,4,4,5,4,4,5,5,6,5,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,6,6,5,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,2,2,2,3,3,2,3,3,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,6,7,7,8,10,9,10,11,14,14,16,17,17,20,20,20,17,19,18,19,22,20,22,22,22,24,23,23,23,25,22,25,25,24,24,23,23,24,21,22,24,24,22,24,23,23,24,25,22,21,24,23],[28,27,27,27,27,27,27,26,25,26,24,24,24,22,24,24,25,23,24,24,22,23,24,23,22,24,24,23,25,24,23,25,25,26,25,25,24,25,25,25,26,24,24,24,25,25,24,22,22,22,22,20,20,21,20,19,18,18,16,16,13,11,9,7,6,6,5,5,5,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,5,5,5,5,5,5,6,5,6,6,6,6,6,6,7,6,6,7,7,7,7,7,8,8,8,8,9,8,7,7,7,8,8,8,7,8,8,7,6,8,7,7,7,7,7,6,7,7,6,6,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,6,6,6,7,7,6,6,6,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,5,4,5,5,5,6,6,6,8,10,10,11,11,10,10,12,11,11,13,13,13,13,16,17,16,18,20,21,19,21,21,18,20,18,16,18,21,20,18,20,23,22,22,25,23,26,26,25,26,26,26,25,25,26,25,26,26,26,26,26,26,25,26,27,25,25,23,23,24,22,25,24,24,25,23,22,22,20,21,21,20,19,18,17,16,14,12,11,9,8,7,5,4,4,4,4,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,6,5,6,6,7,6,6,6,6,6,6,5,5,6,7,6,7,7,6,6,6,5,5,6,5,4,5,5,5,4,4,4,4,4,4,4,3,4,3,3,4,4,3,4,4,4,4,4,4,4,5,5,6,6,7,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,6,4,4,4,4,4,4,5,4,4,5,5,6,6,5,5,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,4,4,5,5,5,6,6,5,6,6,6,6,7,6,6,7,7,7,7,6,6,6,6,6,5,6,6,6,6,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,6,7,8,8,9,10,10,10,11,13,13,16,17,17,20,19,19,16,19,18,19,23,20,22,22,21,25,23,23,23,24,22,24,25,23,23,23,24,23,21,22,23,24,22,24,24,23,24,25,22,21,23,23],[27,28,27,27,27,27,28,27,26,26,25,24,26,23,25,24,25,24,23,25,22,21,25,24,22,25,25,24,26,25,23,26,26,26,25,27,25,26,26,25,27,25,24,25,26,26,25,22,24,24,23,22,22,21,20,20,19,19,19,17,15,12,9,7,6,5,4,4,4,4,4,3,4,4,4,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,8,8,7,6,7,6,7,7,7,7,7,7,6,6,7,7,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,5,5,6,5,5,6,6,6,5,5,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,5,4,5,4,4,3,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,11,11,12,11,11,13,13,12,13,15,14,14,16,17,18,19,20,20,22,21,22,21,20,21,20,18,20,21,21,20,21,22,23,23,27,25,25,25,25,26,26,26,26,26,26,26,26,26,27,26,26,26,25,26,26,26,26,24,25,25,25,26,25,24,25,22,23,23,22,22,22,18,20,20,18,17,15,13,12,9,8,6,5,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,7,6,7,6,7,5,5,6,6,6,7,7,7,7,6,6,6,6,5,6,5,5,5,5,5,4,4,4,4,4,4,4,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,7,7,8,5,4,3,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,6,6,5,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,6,7,8,8,9,10,10,10,11,14,15,16,18,17,20,19,19,18,20,19,20,23,20,22,23,21,25,25,24,24,26,24,24,26,25,24,24,25,24,22,22,26,26,24,25,23,25,24,26,25,22,24,25],[27,27,27,27,27,26,26,26,25,25,24,24,25,23,24,23,24,23,23,24,22,21,24,23,21,24,25,22,25,23,22,25,25,25,25,26,24,26,26,26,26,25,23,25,25,25,25,21,23,23,21,18,21,20,18,19,19,18,17,16,13,11,7,5,4,4,4,4,4,3,4,4,4,4,4,4,4,5,5,4,5,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,6,7,7,7,7,7,8,8,8,8,9,8,8,7,7,7,7,8,8,8,8,8,7,7,8,7,7,7,7,7,7,7,7,6,7,7,7,7,7,6,7,7,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,6,5,6,6,6,6,6,5,6,6,6,5,6,6,5,5,5,5,5,6,5,5,6,6,5,5,6,6,5,5,5,5,5,5,6,5,5,5,5,5,5,5,6,7,6,6,6,7,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,5,4,5,5,5,4,4,4,4,4,4,5,4,4,4,5,4,4,5,5,5,5,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,3,4,4,4,4,4,4,4,5,5,6,7,8,10,11,9,10,11,10,11,11,12,12,12,16,16,16,19,19,20,20,20,19,18,19,19,18,18,20,20,18,20,22,20,22,25,23,24,24,24,24,25,25,25,25,25,25,25,26,26,26,24,26,25,26,24,25,25,22,25,24,23,24,23,22,24,21,22,22,19,20,19,17,18,16,16,14,13,12,10,8,7,6,5,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,6,6,5,5,7,6,6,6,7,6,6,6,7,6,6,6,6,7,7,7,8,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,7,7,7,7,6,6,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,6,5,4,3,4,4,4,4,4,4,5,5,5,5,5,5,6,5,5,5,5,5,4,5,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,3,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,3,3,3,4,3,3,3,3,2,3,3,3,2,3,3,2,2,3,2,2,3,3,3,2,2,2,2,1,1,1,1,1,1,0,1,1,1,2,1,2,2,2,2,2,3,3,3,3,3,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,3,3,3,3,4,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,3,4,4,4,4,5,5,5,5,6,6,7,8,8,10,9,11,11,13,12,15,16,16,20,17,20,16,18,17,18,20,18,20,21,19,22,23,22,22,22,21,24,23,22,23,22,22,21,21,21,23,22,21,21,21,22,22,24,21,19,22,23],[29,29,29,29,29,29,28,28,28,28,27,27,28,26,26,26,26,26,26,27,25,26,27,26,25,27,27,25,27,27,25,27,28,27,27,28,27,28,27,27,28,27,27,27,27,26,26,24,25,24,24,22,23,22,20,21,20,19,19,19,16,13,9,6,5,5,3,3,4,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,6,7,7,7,7,8,8,8,8,8,9,8,7,7,6,7,7,7,8,7,8,6,7,7,7,6,6,7,6,6,6,6,6,6,7,7,6,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,6,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,4,5,4,4,4,4,3,3,4,4,3,3,4,4,3,3,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,5,6,7,8,9,12,13,12,11,13,13,11,12,14,13,14,16,17,17,19,19,20,22,21,22,22,20,22,19,19,20,21,21,20,21,24,24,25,26,25,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,25,26,26,26,26,25,24,26,23,23,24,23,23,22,19,20,19,18,16,15,13,11,9,7,6,5,4,4,3,4,4,3,4,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,7,7,7,6,6,6,6,6,5,6,6,6,7,7,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,7,7,7,7,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,7,5,4,3,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,5,5,4,5,5,5,5,6,6,5,6,6,6,6,6,6,5,6,5,5,5,5,5,5,4,4,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,5,7,8,8,9,9,11,11,11,12,14,15,15,17,17,21,20,19,18,19,19,20,23,21,23,23,22,26,26,23,25,24,22,25,25,24,24,24,25,24,22,23,25,25,24,25,22,25,24,26,25,22,24,25],[29,29,29,29,29,29,28,28,28,27,28,28,28,27,26,27,26,26,26,25,26,26,25,26,26,26,27,26,27,27,26,27,27,28,27,27,27,28,27,27,27,27,27,27,26,26,26,24,23,23,24,23,22,22,22,21,20,21,20,18,15,14,9,5,5,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,8,8,9,9,7,7,6,6,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,5,5,6,6,5,5,6,5,5,5,5,5,5,5,5,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,6,6,6,5,5,6,5,5,6,5,5,5,4,4,5,5,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,4,4,4,5,5,5,6,5,5,4,4,4,4,3,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,4,3,3,3,4,3,4,4,4,4,3,3,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,3,3,4,5,6,7,10,12,13,10,10,13,12,12,12,13,13,13,14,17,17,17,20,21,22,21,23,19,19,21,19,18,19,21,21,19,21,22,23,24,26,24,26,26,26,27,27,28,27,28,28,28,28,28,28,28,28,28,28,27,27,27,27,25,26,26,25,26,25,25,26,23,23,24,22,22,21,20,21,19,18,16,14,13,11,9,7,6,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,3,4,3,4,3,3,4,4,3,4,4,4,4,4,4,5,5,5,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,3,3,3,4,6,6,6,5,4,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,5,5,6,5,5,5,5,5,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,6,7,8,8,9,11,10,11,11,13,14,15,17,17,21,19,19,18,20,18,19,23,20,22,22,21,25,24,23,23,24,22,24,24,23,23,23,23,23,22,22,25,23,23,24,23,23,22,25,23,21,24,24],[28,29,28,28,28,28,28,28,27,26,26,25,27,25,25,26,25,25,26,25,25,25,25,25,25,26,26,24,26,25,24,26,26,26,26,27,26,27,26,26,26,26,25,25,25,25,25,22,23,23,21,21,21,21,19,19,20,19,18,17,14,12,9,6,5,4,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,4,4,3,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,7,6,5,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,6,5,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,6,6,5,5,5,5,5,5,5,5,4,4,4,4,5,4,4,4,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,4,4,4,6,7,8,10,10,12,10,11,12,13,12,12,14,12,13,14,17,16,17,19,21,22,20,23,21,19,20,19,18,18,21,21,19,20,22,22,23,25,24,25,25,25,26,26,27,26,26,26,26,26,27,27,27,26,27,27,27,26,25,26,25,26,25,23,26,23,24,26,22,22,23,21,22,20,18,20,17,17,15,13,13,11,8,7,5,4,4,3,3,3,3,3,3,4,4,4,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,5,5,6,5,6,6,6,6,6,5,5,6,5,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,6,6,6,6,6,6,5,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,2,3,2,2,3,2,2,3,3,3,4,6,5,5,4,4,3,3,3,3,4,4,3,4,4,5,5,4,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,5,4,5,5,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,6,6,7,8,9,10,9,10,10,12,12,14,15,15,19,18,17,16,17,17,17,21,18,19,20,19,22,22,21,22,23,21,23,23,22,21,22,22,22,19,21,23,23,22,22,22,21,22,23,22,20,23,22],[27,29,28,28,29,29,28,28,28,27,27,26,27,25,26,25,26,25,24,26,25,24,25,25,24,26,27,24,27,26,24,27,27,27,26,28,26,27,27,26,27,26,26,26,26,26,24,23,24,23,21,21,22,21,19,20,20,18,19,19,16,13,10,6,5,4,3,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,6,6,5,5,6,6,6,6,6,6,5,5,6,5,5,5,6,5,5,6,5,5,5,6,6,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,4,3,3,4,4,3,3,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,6,7,8,9,12,12,10,12,12,13,12,13,13,14,15,16,17,18,19,19,20,22,22,22,21,21,21,20,19,20,20,22,21,21,22,24,24,26,25,26,25,26,27,27,27,27,27,27,27,27,27,27,27,26,27,26,27,26,26,26,24,26,25,25,26,24,24,26,22,22,23,22,22,21,19,20,19,17,16,15,13,11,9,7,5,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,5,5,7,6,6,6,6,5,5,6,5,6,7,6,7,6,6,6,6,5,5,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,5,5,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,3,2,2,3,2,2,3,3,3,4,6,6,7,5,4,3,3,3,3,4,4,3,4,4,4,4,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,4,5,5,5,4,4,4,4,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,1,1,2,1,1,1,2,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,6,7,8,8,9,10,10,10,11,13,14,15,16,17,21,18,19,18,20,18,20,22,19,22,22,21,24,24,24,24,24,23,25,25,24,24,23,25,23,23,23,26,26,23,25,24,24,25,25,24,22,25,25],[29,29,29,29,29,30,29,29,29,28,28,28,28,27,27,26,26,27,26,26,27,27,26,28,26,27,28,26,28,27,26,27,28,28,27,28,27,27,27,27,27,27,26,26,25,25,24,23,23,23,24,22,21,21,20,20,20,21,21,19,16,13,9,6,5,4,3,3,3,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,6,6,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,5,5,5,4,5,4,4,5,5,4,4,4,4,4,5,5,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,5,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,9,11,14,10,11,15,12,12,14,14,14,14,16,17,17,18,20,21,21,22,23,22,21,22,21,21,20,21,22,21,22,24,25,25,27,26,26,26,27,27,27,27,27,27,27,28,28,28,28,28,27,28,28,28,27,27,27,25,26,27,25,26,25,24,26,23,23,24,22,23,22,20,20,19,18,15,14,13,11,9,7,5,4,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,6,5,5,6,5,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,6,6,6,7,6,6,5,5,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,6,5,5,4,4,3,3,3,3,4,4,3,4,4,5,5,4,4,5,5,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,4,4,4,4,5,5,4,5,5,5,5,5,5,4,5,5,4,4,4,5,4,4,3,3,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,6,7,8,8,9,11,10,11,12,13,15,15,18,17,20,19,19,18,20,19,20,22,20,21,23,22,25,25,24,24,25,24,24,26,24,24,24,25,24,22,23,25,24,24,25,23,25,24,26,23,21,25,24],[28,28,28,29,28,29,28,28,28,27,27,27,27,27,26,27,26,27,26,25,26,26,25,26,25,26,27,25,27,26,25,27,27,27,27,27,27,27,27,26,27,26,25,26,25,24,24,23,23,22,22,21,21,22,20,20,20,20,18,18,14,13,8,5,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,3,4,4,4,4,4,4,5,5,5,6,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,8,8,7,6,6,6,6,6,7,7,7,7,6,6,6,7,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,5,5,5,6,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,4,4,3,3,3,4,3,4,4,4,4,4,3,3,4,4,3,3,4,4,4,4,4,4,4,5,4,4,4,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,6,7,7,10,9,11,9,8,12,10,10,12,14,12,12,14,16,16,16,20,21,22,21,22,21,20,20,19,19,18,19,21,19,20,23,23,23,26,26,26,25,26,26,27,27,27,27,27,27,27,27,27,27,26,27,27,27,27,25,26,24,26,25,23,25,24,22,25,21,22,22,21,21,21,18,20,19,17,16,14,13,11,9,7,6,4,4,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,6,6,6,6,6,7,7,7,7,6,6,6,6,5,6,5,4,5,5,5,4,5,4,4,4,4,4,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,6,6,6,7,7,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,4,5,5,6,5,4,3,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,4,4,4,5,4,4,3,3,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,1,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,6,7,8,8,9,10,10,10,11,13,14,14,16,16,19,18,19,17,18,17,18,20,19,21,22,20,24,23,23,23,24,23,23,24,24,23,23,24,22,21,22,24,23,22,23,22,23,22,24,22,21,22,23],[28,28,28,28,28,28,28,27,28,26,27,27,26,27,26,26,27,26,26,26,25,24,25,26,24,25,27,24,27,26,24,27,27,27,26,27,26,27,26,26,26,26,25,25,25,24,24,23,23,22,22,21,22,20,19,19,19,18,17,17,15,12,9,6,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,3,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,7,6,6,6,7,7,7,7,7,7,6,6,7,6,6,6,7,6,6,7,6,6,6,7,7,7,6,6,6,6,6,6,6,6,5,6,6,5,6,6,5,5,5,6,5,5,6,6,6,5,4,5,5,5,4,5,5,5,5,6,5,5,6,6,6,6,6,6,6,6,6,5,6,5,5,5,6,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,5,4,4,5,5,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,4,3,3,3,3,4,6,6,7,9,10,10,10,11,12,12,12,13,13,13,14,14,16,17,17,18,21,22,21,23,21,21,21,20,19,18,20,21,20,20,22,23,23,25,24,25,25,25,26,26,25,25,26,26,26,26,26,25,25,26,26,25,26,26,24,25,24,24,25,22,24,23,22,24,21,21,21,20,20,20,17,18,18,16,15,13,12,11,9,7,6,5,4,3,3,4,3,4,4,4,5,4,4,5,5,4,5,6,5,5,6,7,6,6,6,7,7,7,6,7,6,6,6,6,7,7,7,7,7,6,6,7,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,6,6,7,7,7,7,6,6,6,6,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,4,6,6,5,5,4,4,4,4,4,5,4,4,4,5,5,5,5,5,6,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,2,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,7,8,8,9,10,10,10,12,12,13,14,15,15,19,17,17,16,18,17,17,20,18,21,21,18,23,20,22,22,23,22,24,24,22,22,22,23,20,19,22,23,23,22,22,21,22,22,22,21,19,22,22],[28,28,28,28,28,29,28,28,28,27,28,28,27,27,26,27,26,27,26,27,27,26,27,27,26,27,27,26,27,26,25,27,28,28,27,28,26,28,27,27,27,26,26,26,25,25,23,24,23,22,24,22,21,21,20,20,19,19,18,17,14,13,9,6,5,4,3,3,3,2,3,2,3,3,3,3,3,4,3,3,3,4,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,8,8,8,8,8,7,6,6,7,7,7,7,7,7,7,6,6,7,7,6,6,7,6,6,6,6,6,6,7,7,7,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,6,5,6,6,6,6,5,4,4,5,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,5,6,5,5,5,6,5,5,6,5,5,6,6,6,7,7,6,6,6,6,6,6,6,5,5,5,5,5,6,5,5,5,5,5,4,5,5,4,4,5,5,4,4,4,4,4,4,5,4,4,5,5,5,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,4,5,5,6,6,6,6,6,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,3,3,4,4,3,3,4,3,3,3,4,4,3,4,4,4,4,3,3,3,4,4,3,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,3,4,5,7,7,9,11,12,10,12,13,12,12,12,14,14,14,16,17,18,19,20,20,22,21,23,21,21,21,21,21,20,21,22,21,21,23,25,24,26,25,26,26,26,26,26,26,26,26,26,26,27,27,26,27,26,26,27,26,27,25,26,25,25,25,24,25,24,23,25,22,21,23,21,21,20,18,19,18,17,15,14,13,11,10,8,6,5,4,3,3,3,4,3,4,4,5,4,5,4,5,5,5,6,6,6,6,7,6,6,7,8,7,8,7,7,7,6,6,6,6,7,7,7,7,6,7,7,6,5,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,7,7,7,7,7,6,6,5,5,5,5,4,4,4,5,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,6,6,6,5,4,4,4,4,4,4,4,4,4,5,5,6,5,5,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,5,5,6,5,5,5,5,5,4,5,4,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,2,1,2,2,1,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,5,7,8,9,9,10,11,11,11,11,14,14,15,17,17,20,19,19,18,18,19,19,22,20,22,22,20,24,24,22,23,24,23,24,24,24,24,24,24,24,21,23,25,25,23,25,22,24,24,26,23,21,25,25],[28,28,28,28,28,29,28,28,29,28,28,28,28,28,27,27,27,28,28,27,28,27,26,28,27,27,28,27,28,27,27,28,28,28,28,28,27,28,28,28,28,27,26,26,25,25,24,23,22,22,23,21,20,21,20,20,20,21,19,17,15,13,10,7,6,3,2,2,3,2,2,2,3,3,3,3,3,4,4,3,3,4,4,3,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,7,6,7,7,7,7,7,7,7,7,6,6,7,7,7,6,7,7,6,7,6,6,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,6,5,5,5,5,5,5,6,6,6,6,6,5,6,5,5,6,5,5,5,6,5,5,5,6,5,5,6,6,7,7,6,6,7,7,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,4,4,5,4,4,4,5,4,4,4,4,4,4,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,6,6,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,3,3,4,4,3,3,4,3,3,3,4,4,4,4,4,4,3,3,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,5,4,6,7,8,10,11,12,10,10,15,12,11,13,14,12,13,15,17,16,17,21,21,23,23,24,22,21,22,21,20,20,22,22,21,22,24,25,26,27,26,26,26,27,27,28,28,28,28,28,28,27,28,28,28,27,27,28,27,28,26,27,25,27,27,25,27,25,25,27,24,23,24,22,22,21,19,20,19,17,15,15,13,12,11,8,6,4,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,6,6,6,6,7,7,7,7,8,7,8,7,7,7,7,6,6,7,7,7,8,8,7,7,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,7,7,7,7,7,7,6,6,5,5,5,5,4,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,4,6,6,6,5,4,4,4,4,4,5,4,4,5,5,6,6,5,6,5,6,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,5,5,5,5,5,5,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,2,3,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,7,8,9,9,10,11,11,11,11,14,14,15,18,17,20,18,19,18,19,18,19,21,19,21,22,21,24,25,23,23,24,23,24,25,24,24,24,24,24,22,23,25,24,22,24,23,24,23,26,23,20,24,24],[28,27,27,27,27,28,27,27,27,27,26,26,26,26,26,27,26,27,26,26,27,26,26,27,26,26,27,25,27,27,25,27,28,27,26,27,26,27,27,26,26,26,25,25,24,24,23,22,22,21,22,21,21,21,19,18,19,18,16,16,14,11,9,7,7,4,3,2,3,3,3,3,3,4,4,4,4,5,4,4,4,5,4,4,5,5,5,5,6,6,6,7,6,7,7,7,7,8,7,7,8,8,8,8,8,8,8,9,9,9,9,8,7,8,8,8,8,8,8,8,8,8,7,8,8,8,8,8,8,8,8,8,8,7,8,9,8,8,7,8,8,7,7,7,7,7,7,7,6,7,7,7,6,6,7,7,7,7,7,7,6,5,6,6,6,5,6,7,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,7,7,8,8,8,7,8,8,7,7,7,8,7,7,6,6,7,7,7,7,7,6,6,6,6,6,5,6,6,6,5,6,6,6,5,6,6,5,5,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,7,6,6,6,7,7,7,7,6,6,6,5,6,6,6,5,5,6,5,5,5,6,5,5,6,6,6,6,6,6,6,5,5,5,5,5,4,5,5,4,5,5,5,5,6,5,5,5,5,4,4,5,5,4,5,5,5,5,6,5,6,6,6,6,6,6,6,6,5,5,4,5,4,4,4,4,3,4,4,4,3,3,4,5,6,7,7,8,11,10,10,11,12,11,12,13,12,12,13,14,16,17,17,19,20,22,20,23,21,21,21,20,20,20,21,22,20,21,22,24,25,26,25,24,25,25,25,26,26,26,26,26,26,26,26,26,26,25,26,26,26,25,24,26,23,24,25,22,24,23,22,25,21,21,23,20,20,20,18,18,17,16,15,14,13,11,11,8,6,5,4,4,4,4,4,4,5,5,6,5,5,6,6,6,6,7,7,7,7,8,7,7,8,9,8,8,8,8,7,8,8,8,8,8,9,9,8,8,8,8,7,7,7,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,7,7,7,7,7,8,8,9,9,8,8,7,7,7,7,6,6,6,5,6,6,6,5,6,6,5,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,5,6,6,7,6,5,5,5,5,5,6,5,5,6,6,7,7,6,7,7,7,6,6,6,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,5,5,5,6,6,5,6,7,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,3,2,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,1,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,4,4,4,4,4,4,3,4,4,4,4,4,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,9,10,11,12,12,12,13,13,14,16,17,17,19,18,18,18,18,17,18,20,19,20,21,20,23,22,22,22,23,22,24,24,22,23,22,23,21,21,21,22,23,21,22,21,22,22,23,21,19,22,23],[28,28,28,27,28,29,28,28,28,27,27,27,27,27,27,27,27,28,27,27,27,26,27,27,26,27,28,26,28,27,26,28,28,28,28,28,28,28,28,27,28,27,26,26,26,25,24,23,23,23,22,21,21,20,19,19,18,18,17,15,13,11,9,7,6,3,3,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,7,6,6,6,7,7,7,7,7,7,6,6,7,7,7,6,7,6,6,6,7,6,7,7,7,7,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,6,6,6,6,6,5,5,4,5,5,4,4,5,5,5,5,5,6,6,5,5,5,6,6,6,6,6,5,5,6,5,6,6,6,5,5,6,6,6,6,6,7,7,7,6,7,7,7,6,7,6,6,6,6,5,6,6,5,6,5,5,5,4,5,5,4,5,5,4,4,4,4,4,4,4,5,4,4,5,5,6,6,6,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,6,7,6,6,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,4,5,6,7,9,12,11,10,11,12,12,12,13,14,13,15,17,17,17,19,20,21,22,20,23,21,21,22,21,20,21,22,23,21,22,23,25,24,26,25,26,26,27,26,26,27,26,27,27,27,27,26,26,27,26,26,26,27,26,26,26,24,25,25,24,25,23,23,25,22,21,23,20,21,20,18,18,19,16,15,15,14,12,11,8,7,5,4,4,3,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,8,8,7,8,8,8,8,8,8,7,7,7,7,7,8,8,8,8,8,7,7,6,6,6,6,5,6,6,5,5,5,5,4,5,4,4,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,7,7,7,8,8,8,7,6,6,6,5,5,5,5,5,5,5,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,4,5,6,6,7,6,5,4,4,4,4,5,5,4,5,5,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,3,4,3,3,4,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,5,5,5,5,5,5,5,5,5,5,4,4,3,2,2,3,3,2,2,2,2,2,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,0,1,1,1,2,2,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,3,3,3,2,3,2,2,3,3,2,2,3,3,2,2,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,4,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,6,5,5,5,6,7,8,9,10,10,11,12,12,12,14,14,16,17,17,20,19,19,18,18,19,19,21,20,21,21,22,24,24,23,23,23,23,25,24,24,24,22,24,24,22,23,24,24,24,25,24,24,24,26,24,20,24,24],[27,27,28,27,28,28,28,28,28,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,26,27,28,26,27,28,26,28,28,28,28,28,28,28,28,27,28,27,27,26,26,25,24,23,23,22,22,21,21,21,19,20,19,18,17,16,12,12,9,6,5,4,6,5,3,4,3,3,4,4,5,4,5,5,5,6,5,6,5,5,6,7,6,6,6,7,8,8,8,9,8,8,9,9,9,9,9,9,9,9,10,10,10,11,10,11,10,10,9,10,9,9,9,9,9,9,10,9,9,10,10,10,9,10,10,9,9,9,9,9,9,10,9,10,9,9,10,9,9,9,9,8,9,9,8,9,8,8,8,8,8,8,7,8,8,8,7,6,6,7,7,6,8,8,8,8,7,8,9,7,8,8,8,8,8,8,8,9,8,8,9,8,8,8,9,8,8,8,9,8,8,9,9,10,9,9,9,10,10,10,9,9,8,8,8,8,8,8,8,8,8,8,7,8,8,7,7,7,8,7,7,7,7,5,6,7,5,5,6,6,7,7,8,8,8,8,8,8,8,8,8,8,8,8,7,8,7,8,7,8,8,8,8,8,8,8,8,8,7,7,8,8,7,7,8,7,7,7,8,7,7,7,7,8,7,8,8,7,6,5,6,6,5,5,7,6,6,5,7,6,6,7,7,7,5,5,4,5,5,5,5,5,6,6,5,6,7,7,7,7,7,7,7,6,6,6,5,5,4,4,4,4,4,3,3,4,4,5,5,6,5,6,8,7,9,10,10,10,10,12,12,12,14,15,14,16,17,18,18,19,21,21,23,21,24,22,21,22,21,21,22,23,23,22,23,24,26,26,26,26,26,27,27,27,28,28,27,28,28,28,28,27,27,28,27,27,27,27,27,25,27,24,26,26,22,26,23,24,26,22,22,24,21,21,22,20,20,20,17,17,16,14,13,12,9,7,6,4,5,4,5,4,6,6,7,7,7,8,8,8,9,9,9,9,10,9,10,9,9,10,10,10,10,11,10,9,9,9,10,9,10,10,10,10,10,9,9,9,9,9,8,8,8,8,7,7,7,7,6,6,6,7,6,7,6,7,7,7,8,7,8,8,8,9,9,9,8,9,9,9,10,11,9,9,9,8,9,8,8,8,8,7,7,8,8,8,8,8,7,8,7,7,8,7,6,7,6,6,6,6,5,5,6,5,5,5,5,4,4,4,5,6,7,7,8,7,7,7,6,6,6,7,7,6,7,8,8,8,8,8,8,8,7,7,7,6,6,6,6,5,5,6,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,7,8,7,7,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,2,2,3,3,3,3,3,4,4,5,5,5,6,6,6,7,7,6,7,7,8,7,7,8,7,7,7,7,6,6,6,5,6,5,6,5,6,5,4,5,3,3,4,3,3,3,3,3,3,4,4,4,3,4,5,5,5,6,6,5,5,6,6,5,5,6,6,6,5,5,6,5,5,4,4,3,3,3,3,2,2,2,1,1,0,1,2,2,2,2,2,3,3,3,4,4,4,4,5,5,5,5,6,5,6,6,5,5,4,4,5,4,4,3,5,5,4,3,4,4,4,3,4,4,4,5,6,6,6,6,6,5,6,6,6,6,6,7,7,7,6,8,7,7,7,7,8,6,7,7,8,7,8,8,8,7,8,8,8,8,8,8,9,8,9,10,11,11,13,14,14,14,15,16,16,18,19,20,21,19,23,20,21,19,21,23,23,23,24,24,24,24,26,23,25,25,27,25,25,27,24,26,24,24,24,25,25,23,25,24,25,26,25,24,22,24,25],[28,28,28,28,29,29,29,29,29,28,28,27,28,27,28,27,28,28,27,28,28,27,27,28,27,28,28,27,28,28,27,28,28,29,28,28,28,28,28,28,28,27,27,27,27,26,25,24,24,23,23,22,22,20,19,19,18,17,16,15,12,11,8,7,6,4,4,3,3,2,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,7,7,7,8,8,8,8,8,8,8,8,7,7,7,7,8,7,7,7,7,7,7,8,7,7,7,7,7,7,7,7,7,7,8,8,8,7,7,7,7,6,6,7,7,6,7,6,6,6,6,6,5,5,6,6,6,6,6,6,6,5,6,5,5,5,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,8,8,7,7,8,8,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,6,7,6,6,6,6,6,6,6,6,5,5,6,6,5,5,5,5,5,6,6,7,7,7,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,3,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,5,4,4,5,8,8,10,12,12,10,10,15,12,12,15,16,14,16,19,19,18,21,21,21,24,21,24,22,20,24,22,22,23,24,25,23,24,25,27,26,28,26,26,27,28,27,28,28,27,27,27,28,28,28,27,28,27,27,28,27,27,26,27,26,26,26,23,26,23,23,25,22,23,23,22,22,22,19,19,19,16,15,14,12,11,9,8,6,4,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,6,6,7,7,8,8,8,8,10,8,9,8,9,7,7,7,6,7,9,7,9,9,7,8,7,7,6,6,6,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,7,7,8,8,8,8,7,6,6,6,6,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,5,6,6,6,6,6,5,5,4,5,6,5,5,5,6,7,6,6,6,7,6,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,4,4,4,4,3,4,4,3,3,3,3,3,3,4,4,3,4,4,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,5,6,6,6,6,6,6,5,6,5,5,5,5,5,5,4,4,3,2,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,3,3,4,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,8,8,10,10,11,12,12,12,13,15,16,17,18,19,22,20,20,18,20,20,21,23,22,23,25,23,25,26,26,25,25,24,25,25,26,26,23,24,25,24,24,25,26,25,25,25,25,25,26,24,21,24,23],[28,28,28,28,28,29,28,28,29,27,27,27,27,27,27,27,27,27,27,27,28,27,27,28,27,27,28,27,28,27,26,28,28,28,27,28,27,28,28,27,28,27,26,26,27,26,25,24,24,23,23,22,22,21,19,20,19,18,19,17,14,11,8,6,6,3,3,2,3,2,3,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,6,6,6,7,7,7,8,7,7,8,8,8,9,9,9,9,9,8,7,8,8,7,7,7,8,8,8,7,7,7,8,7,7,8,7,7,7,7,7,7,8,8,8,8,7,7,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,6,6,7,6,6,5,6,6,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,8,8,8,7,7,8,8,8,7,8,7,7,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,4,5,5,4,4,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,6,6,7,6,6,5,5,5,5,5,5,5,4,5,5,4,5,5,6,5,5,6,6,6,6,5,6,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,5,4,4,4,3,3,4,3,3,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,3,5,5,7,8,8,9,12,13,9,10,16,13,11,16,15,15,16,18,18,18,21,20,21,23,21,24,22,21,22,21,20,22,22,24,22,23,24,26,26,26,26,26,27,27,28,28,28,28,28,28,28,28,28,28,27,26,27,27,27,27,26,26,26,26,26,24,25,24,24,25,23,23,24,22,22,22,20,20,19,17,17,16,15,12,11,8,6,5,4,3,3,3,3,3,4,4,4,4,4,5,5,5,5,6,6,6,7,7,7,7,8,8,8,9,8,8,7,7,7,6,7,7,8,8,9,7,7,7,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,7,7,8,8,8,8,7,6,6,6,6,5,5,5,4,4,5,5,4,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,6,7,7,8,7,6,5,5,5,5,6,5,5,6,6,7,7,7,6,7,6,6,6,6,5,5,5,5,5,4,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,3,4,4,4,5,5,5,6,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,3,4,4,3,3,3,3,3,3,2,2,3,2,2,2,2,3,3,4,4,3,3,3,3,4,4,4,4,5,5,4,5,4,5,5,4,5,5,4,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,6,6,8,9,10,10,11,12,12,11,13,15,15,16,18,18,20,20,20,18,20,19,19,23,21,22,22,21,24,24,24,24,24,23,25,24,24,25,24,24,23,22,24,25,25,22,25,23,24,24,25,23,21,24,23],[29,28,28,28,28,28,28,28,28,28,27,27,28,26,27,26,27,27,26,28,27,27,28,28,27,27,27,27,27,28,26,28,28,28,27,28,27,27,28,27,28,27,27,27,27,26,24,25,25,24,24,23,22,22,20,20,19,18,18,18,15,12,9,6,6,3,3,3,2,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,7,7,6,6,6,6,7,7,7,7,6,6,6,6,7,6,6,7,6,6,6,6,6,6,7,7,7,6,6,6,6,5,6,6,5,5,6,5,5,6,5,5,4,5,5,5,5,6,5,5,5,4,5,5,4,4,5,5,5,4,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,6,6,7,6,6,6,6,6,6,7,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,3,4,4,3,4,4,5,5,6,5,5,6,5,5,5,5,5,4,5,5,5,4,4,4,4,4,5,5,5,6,6,5,5,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,4,4,3,3,3,2,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,5,7,8,8,10,12,13,11,13,14,14,13,15,15,17,16,19,20,19,21,22,21,23,22,24,21,20,22,22,20,22,23,24,23,22,23,25,25,27,25,26,26,26,27,27,26,26,27,27,27,27,27,27,26,26,27,27,27,27,25,26,25,26,25,24,25,23,23,25,23,23,23,22,23,22,20,19,18,17,15,15,15,11,10,8,6,4,3,3,2,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,6,7,7,6,7,8,7,8,7,8,7,6,6,6,6,7,7,7,8,7,6,6,5,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,7,7,7,6,5,5,5,5,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,6,6,6,6,5,4,4,4,4,5,4,4,5,5,5,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,2,3,3,2,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,6,8,8,8,9,11,11,10,12,14,14,15,17,17,20,20,19,17,18,19,18,20,19,21,23,21,24,23,23,23,23,24,24,24,24,24,24,23,25,21,23,25,24,22,25,22,24,24,25,21,21,24,24],[28,28,29,28,28,29,28,28,29,27,28,28,28,27,27,26,26,28,27,26,28,27,27,28,26,28,29,27,29,28,26,28,29,29,28,28,28,28,28,28,28,27,27,27,27,26,25,24,24,23,23,22,22,21,19,19,18,19,19,16,13,12,9,7,6,4,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,7,7,7,7,7,7,7,6,6,5,6,6,6,6,6,6,5,5,6,6,5,6,6,6,6,6,6,5,6,7,7,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,4,4,5,5,5,6,5,5,4,4,4,4,4,4,4,5,4,4,5,5,4,4,5,5,4,5,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,5,5,4,5,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,5,5,6,5,5,5,4,4,4,4,4,4,3,4,4,3,4,4,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,2,2,2,3,2,3,5,5,5,6,7,8,10,13,13,10,12,13,13,12,14,15,14,14,17,18,18,18,20,20,22,21,23,20,20,21,20,21,21,21,23,22,22,22,25,25,27,25,26,26,26,26,27,26,26,26,26,27,27,27,27,27,26,26,27,26,27,25,26,25,25,26,23,25,24,23,25,23,23,23,22,22,21,19,19,18,16,15,14,15,11,10,8,6,5,3,3,2,3,3,3,3,4,4,4,4,4,5,4,5,5,5,5,6,6,6,7,7,7,7,8,7,7,6,6,6,6,6,7,6,7,8,6,6,6,6,5,5,5,4,5,5,4,4,4,4,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,6,6,6,5,5,4,4,3,4,5,4,4,4,5,6,6,5,6,5,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,3,2,2,2,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,4,4,3,3,2,2,2,2,2,2,2,2,2,1,2,1,1,1,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,1,2,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,3,3,3,3,3,4,3,4,4,4,4,4,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,5,5,4,4,5,6,7,8,8,10,11,11,11,12,13,15,16,18,17,20,19,20,17,19,19,19,22,20,23,23,21,25,24,24,24,25,24,25,25,24,24,24,25,25,22,23,25,24,24,25,24,24,24,26,23,22,24,24],[29,28,28,28,28,29,28,28,29,27,28,28,28,27,27,27,27,28,27,27,28,27,27,28,27,28,29,27,28,28,27,28,29,29,28,29,29,29,29,28,29,28,28,28,27,27,26,24,25,24,24,23,23,21,21,21,19,19,19,17,14,13,9,7,6,3,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,7,7,6,7,7,6,6,5,5,6,6,6,6,6,6,5,5,6,6,5,6,6,5,6,6,5,5,5,6,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,4,5,5,4,4,5,5,4,4,5,4,5,5,5,6,6,6,5,6,6,5,5,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,5,5,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,2,2,3,2,4,4,6,6,8,8,9,10,11,10,11,12,11,11,16,15,14,16,18,19,18,19,21,21,24,23,24,21,20,22,20,20,22,22,23,22,22,24,26,26,27,26,27,27,27,28,28,28,28,28,28,28,28,28,28,28,27,28,28,28,28,26,27,26,27,27,24,26,25,24,27,25,24,24,23,24,22,21,20,19,17,16,15,15,12,11,8,5,3,3,2,2,2,2,2,2,3,3,3,3,4,4,3,4,5,4,4,5,6,6,5,5,7,6,7,6,6,6,5,5,5,5,6,5,6,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,6,6,7,6,6,5,5,4,4,4,4,4,3,3,4,3,3,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,3,3,3,4,5,5,6,5,4,4,4,3,3,4,4,3,4,4,5,5,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,4,5,4,5,4,4,4,4,4,4,4,3,3,2,2,2,2,2,1,2,2,1,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,3,3,2,2,2,2,3,2,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,6,7,8,8,10,11,11,10,11,13,13,15,17,17,19,17,20,17,18,17,18,21,20,21,22,20,23,24,24,22,24,23,24,24,24,23,24,24,23,20,23,24,24,21,23,22,24,23,25,22,21,24,23],[28,28,28,28,28,29,28,28,29,27,27,27,27,27,27,27,27,28,27,26,27,27,26,28,27,27,28,27,28,27,26,27,28,28,27,27,28,27,28,27,28,27,27,26,26,26,24,24,24,23,23,22,21,21,19,19,18,19,18,17,14,12,8,6,5,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,4,5,5,5,4,5,5,6,5,5,5,5,5,4,4,5,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,4,4,4,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,3,3,3,3,2,2,2,2,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,5,6,7,9,12,12,9,10,15,12,11,15,14,13,13,17,17,16,18,20,20,22,21,23,21,19,21,20,19,20,21,21,21,21,23,25,25,27,25,26,26,27,27,27,26,26,26,26,27,27,27,27,27,26,27,28,27,27,25,26,24,25,26,25,25,24,23,25,23,22,22,21,21,21,19,18,18,15,14,13,13,10,9,7,5,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,6,5,6,5,5,5,5,4,4,4,5,5,5,5,4,5,5,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,5,5,5,6,6,5,5,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,4,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,2,2,2,3,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,9,10,12,12,14,17,16,18,18,17,15,17,17,18,21,19,21,20,20,24,23,22,22,23,22,23,22,23,22,20,22,22,18,21,23,22,21,23,21,22,21,24,21,19,22,22],[28,28,29,28,29,29,28,28,29,27,28,28,27,27,26,27,26,28,27,26,28,27,26,28,27,27,27,27,27,27,27,27,28,28,27,27,27,27,28,27,28,27,27,27,26,26,25,24,24,24,23,23,22,21,20,20,19,19,20,18,15,13,10,6,6,4,3,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,4,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,5,4,4,4,4,3,4,4,3,3,3,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,3,4,4,5,5,5,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,4,4,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,3,3,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,4,5,7,8,12,12,13,11,11,14,13,13,15,15,14,14,17,17,18,19,20,20,22,21,23,20,20,21,21,19,20,21,23,21,22,22,24,24,27,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,27,26,26,24,25,26,25,25,24,24,25,23,23,22,22,22,21,20,19,18,16,15,13,13,11,9,7,5,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,4,5,5,4,5,5,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,2,2,2,3,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,9,10,11,12,13,16,15,19,19,16,16,18,17,18,21,18,21,21,19,24,24,22,22,23,22,23,24,22,21,22,23,21,19,20,24,23,21,23,22,22,23,25,22,20,24,23],[28,28,29,28,29,29,28,28,29,27,28,28,28,27,26,26,26,27,27,26,27,26,26,27,26,27,28,26,28,28,26,28,28,28,28,28,28,28,28,28,28,27,27,27,26,25,25,24,24,24,23,22,21,21,21,20,19,20,19,19,14,14,9,6,5,3,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,3,2,2,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,5,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,5,4,4,5,4,4,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,3,3,3,4,3,3,4,3,3,3,4,3,3,4,4,5,5,4,4,5,5,4,4,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,6,8,7,9,12,13,10,12,12,10,10,12,12,12,13,15,16,16,17,19,20,21,21,22,21,20,21,19,21,21,21,22,20,21,22,24,24,27,25,25,25,26,26,26,26,26,26,26,26,27,26,26,26,26,27,27,26,26,26,26,25,25,25,24,25,24,23,25,22,22,22,21,21,20,19,19,18,16,15,14,13,10,9,7,4,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,5,5,5,5,5,5,4,4,4,5,5,4,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,4,4,3,3,3,3,3,2,2,3,2,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,3,4,3,4,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,2,2,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,9,10,12,13,14,16,15,18,16,18,16,18,16,19,20,19,22,21,21,24,24,23,23,23,22,24,23,23,23,22,23,23,20,23,24,24,21,24,21,23,23,26,22,20,24,24],[28,28,28,28,28,29,28,28,28,26,27,28,27,26,26,26,25,27,26,25,26,26,25,27,26,26,27,26,27,27,26,27,28,28,27,27,27,27,28,27,28,27,27,27,26,25,25,24,24,23,23,22,22,21,19,20,18,20,19,17,13,12,8,5,4,3,3,2,3,2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,5,5,4,4,5,5,5,5,5,5,4,4,5,5,4,5,5,4,5,5,4,4,5,5,5,5,4,5,5,5,4,4,4,4,4,4,4,3,4,4,3,3,3,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,4,3,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,3,4,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,3,3,4,4,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,4,4,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,5,7,6,8,10,9,8,9,10,10,9,11,12,12,12,15,16,16,17,19,19,22,20,22,20,18,21,20,18,19,20,21,20,21,23,24,25,27,25,26,26,26,26,26,26,27,26,27,27,27,27,27,27,27,27,27,27,27,26,26,25,26,26,24,26,24,23,26,22,22,22,21,21,20,19,19,17,16,14,13,13,9,9,6,4,3,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,4,5,4,4,4,4,4,4,4,5,5,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,2,2,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,9,10,11,13,14,16,16,19,17,17,16,17,16,18,20,20,21,20,20,23,24,22,22,23,23,23,24,23,22,21,23,22,21,21,23,24,23,24,22,23,22,24,21,19,23,22],[28,28,28,28,28,29,27,28,28,27,27,27,27,26,26,26,26,27,26,25,26,26,25,27,26,26,27,26,26,26,25,27,27,27,26,27,27,27,27,26,27,26,26,26,25,25,25,23,24,23,22,22,20,20,18,19,18,18,18,17,14,13,9,5,4,4,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,7,7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,6,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,4,4,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,4,5,6,8,10,11,13,9,10,13,11,10,13,14,13,12,15,17,16,17,18,20,21,19,22,20,18,20,18,19,18,20,21,19,19,22,23,24,27,24,26,25,26,26,26,26,26,26,26,26,26,27,27,27,26,26,26,26,26,24,25,25,25,26,23,25,24,23,25,23,22,22,22,22,21,19,19,18,16,14,13,13,11,9,6,4,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,2,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,2,1,1,2,1,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,5,6,7,7,7,9,8,9,9,11,12,13,14,14,18,18,17,15,17,16,16,21,17,20,19,19,23,23,22,22,23,21,23,22,23,20,20,22,21,18,19,23,22,19,22,20,21,21,23,19,19,22,21],[28,28,29,28,28,29,28,28,28,27,28,27,27,25,26,24,26,26,26,26,26,26,26,27,26,27,28,25,28,27,25,27,28,27,27,28,27,28,28,27,27,27,27,27,26,26,26,24,24,24,24,22,22,21,20,20,18,19,20,18,15,13,9,5,4,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,5,6,7,6,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,4,5,5,4,5,5,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,3,4,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,4,3,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,4,4,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,3,2,4,5,5,9,9,11,12,9,10,12,11,11,12,12,12,13,14,15,16,17,18,19,20,20,21,19,19,20,19,20,19,20,22,20,22,22,24,24,27,25,26,25,25,26,26,25,25,26,26,26,26,26,26,26,25,26,27,26,26,25,26,24,25,26,24,25,23,23,25,22,22,21,22,22,20,18,19,17,16,14,12,12,9,8,6,4,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,5,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,4,4,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,4,5,6,6,7,7,9,9,9,10,12,13,13,16,15,18,17,17,16,16,16,17,21,18,20,20,20,24,23,21,22,22,21,22,23,21,20,20,22,21,19,20,22,22,21,22,21,21,21,23,21,20,23,22],[28,28,28,28,28,29,28,28,28,26,28,27,27,26,26,26,26,26,26,26,26,26,26,26,25,26,28,26,28,27,26,27,28,28,27,28,27,28,28,27,28,27,27,27,26,26,25,24,24,24,24,23,22,22,21,21,20,20,20,17,14,13,9,5,5,4,3,3,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,7,7,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,3,4,4,5,5,5,4,5,5,4,5,5,5,5,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,4,5,5,5,4,4,4,4,3,3,4,3,3,3,4,3,3,4,4,4,5,5,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,2,2,3,3,4,5,5,6,8,10,11,9,9,11,10,10,11,12,12,12,14,16,16,17,19,20,22,21,24,20,21,21,20,20,19,21,22,20,21,23,24,25,27,24,25,25,26,26,26,27,27,27,27,27,27,27,27,27,27,27,28,27,27,26,27,26,26,27,23,26,24,24,25,23,23,23,21,22,21,19,19,18,17,15,14,13,10,10,6,4,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,5,4,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,5,5,4,4,3,3,3,3,3,3,3,3,4,4,5,4,4,5,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,2,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,9,11,12,13,14,17,16,19,17,18,17,18,17,18,20,19,20,21,20,24,24,21,23,24,23,23,24,22,22,22,24,22,21,22,23,23,23,23,22,23,22,25,22,20,23,23],[28,28,28,28,28,28,27,27,27,26,27,26,27,25,25,25,25,26,25,25,26,25,24,26,25,25,26,25,26,25,25,26,27,27,26,27,26,26,27,26,26,26,25,26,25,25,24,23,23,23,22,21,20,20,18,19,18,18,18,16,14,12,9,5,4,4,3,2,3,2,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,5,5,5,5,6,5,5,6,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,5,6,6,6,6,6,6,5,5,6,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,5,4,4,5,5,4,5,5,5,5,5,4,4,5,4,4,5,4,4,4,4,4,4,4,5,5,6,5,5,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,3,3,4,4,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,2,4,6,6,8,10,11,12,8,9,12,11,9,11,13,12,12,14,16,15,16,18,18,20,19,22,19,17,19,18,18,17,19,21,18,19,22,22,25,27,23,25,26,26,26,26,27,27,27,27,27,26,27,27,27,26,27,27,26,26,25,26,25,25,26,24,25,23,23,25,23,22,22,22,21,21,19,19,18,16,14,14,12,10,9,7,5,3,3,2,2,2,2,2,2,2,3,3,2,3,3,3,3,4,4,3,4,4,4,4,4,5,4,5,5,5,4,4,4,4,4,4,4,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,6,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,3,4,5,5,5,4,4,3,3,3,3,4,4,3,4,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,1,1,1,1,1,1,2,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,2,3,2,2,2,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,7,7,8,10,9,10,10,12,12,14,14,15,19,18,18,16,17,17,17,20,18,20,20,20,24,23,22,22,24,22,23,23,23,21,21,22,20,18,19,23,22,19,21,20,21,21,23,19,18,22,20],[28,28,28,28,28,28,27,28,27,27,26,26,26,24,26,25,26,25,26,26,25,25,25,26,25,26,27,25,26,26,25,26,27,27,26,27,26,26,27,27,27,26,26,26,26,25,25,24,23,22,21,21,21,20,19,19,18,18,17,16,14,13,9,7,5,4,4,3,4,3,3,3,3,3,4,4,4,5,4,4,4,5,5,4,4,5,5,5,5,6,6,7,6,6,7,7,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,9,7,7,7,8,8,8,8,8,8,7,7,8,8,7,8,8,7,7,8,7,7,7,8,8,8,7,7,7,7,7,7,7,6,6,7,7,6,7,7,6,6,6,7,6,7,7,6,7,6,6,6,6,6,5,6,6,6,5,6,6,6,6,7,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,7,7,7,7,7,7,7,7,8,7,7,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,5,5,5,4,4,5,5,4,5,5,5,4,5,5,5,5,5,5,6,5,6,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,4,4,5,7,7,9,10,11,12,11,11,13,12,11,12,14,12,13,16,17,16,17,19,19,20,19,21,19,18,19,18,19,18,19,20,18,19,21,23,24,26,24,25,25,26,26,26,26,26,26,26,26,27,27,26,26,25,26,25,25,26,24,24,23,24,25,23,24,23,23,24,22,22,22,21,21,20,20,19,17,16,15,13,13,11,10,7,5,4,3,3,2,3,3,3,3,3,4,4,3,4,5,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,6,5,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,6,6,6,7,7,6,6,5,5,5,5,5,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,3,4,3,4,4,4,3,4,4,4,3,4,4,4,5,6,7,7,5,5,4,5,4,5,6,5,5,6,6,7,7,7,7,7,7,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,6,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,6,6,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,3,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,1,2,2,2,3,3,3,2,2,2,2,3,2,2,2,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,3,4,4,4,4,5,5,4,5,5,6,7,8,8,9,10,10,11,11,13,14,15,16,16,19,19,18,17,18,19,17,21,18,21,21,20,23,23,22,23,23,22,23,24,22,22,23,23,21,19,21,23,22,19,22,21,21,23,23,20,20,22,20],[28,28,28,28,29,28,28,28,28,27,28,27,27,25,27,25,26,26,26,26,26,26,27,27,26,27,28,26,28,28,26,28,29,28,28,29,27,28,28,28,28,28,28,28,27,27,26,25,25,26,25,22,24,22,22,21,21,20,20,18,15,13,9,6,5,5,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,6,6,7,6,6,7,7,7,7,7,8,8,7,8,9,9,9,9,9,8,7,7,7,8,8,8,8,8,8,7,7,8,8,7,7,8,7,7,7,7,7,7,7,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,6,5,6,6,6,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,5,5,6,6,5,6,6,7,7,7,7,7,6,7,7,7,7,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,5,4,5,5,6,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,4,4,4,5,4,5,6,6,8,10,10,12,10,10,12,11,10,11,14,12,14,15,17,18,17,19,20,22,22,22,20,21,21,21,20,21,22,22,20,20,23,23,25,26,25,26,26,26,27,27,27,27,27,27,28,28,28,27,28,27,27,27,27,26,26,26,25,25,26,24,25,24,24,26,24,23,22,23,23,22,20,20,19,18,16,14,14,11,10,7,6,4,4,3,2,3,3,3,3,3,3,4,3,4,4,4,4,5,5,4,5,6,5,5,6,6,6,6,6,6,6,5,5,5,5,6,5,6,6,6,5,6,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,6,6,6,6,6,6,6,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,6,6,5,5,4,5,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,4,3,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,7,7,6,6,6,6,6,5,5,4,4,3,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,1,1,1,2,1,1,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,6,7,8,8,9,10,11,11,11,13,14,15,16,16,20,18,18,17,19,17,18,21,20,21,23,21,24,24,24,22,23,22,23,24,23,23,23,23,23,20,22,24,23,21,23,22,22,22,24,21,20,24,23],[28,28,28,28,28,28,28,27,28,26,27,27,27,25,26,26,26,26,26,26,25,26,25,26,27,26,27,26,27,27,26,27,28,28,27,28,27,28,28,28,28,27,27,28,27,26,26,25,24,24,24,22,21,21,21,20,19,20,19,17,15,14,9,7,6,5,5,5,5,4,4,4,4,4,4,4,5,5,6,5,5,6,5,5,5,6,6,6,6,6,6,7,7,7,8,8,7,8,8,8,9,9,9,9,9,10,10,10,10,11,11,10,9,9,9,9,9,9,9,9,10,8,8,9,9,9,8,9,9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7,7,8,8,7,8,8,7,7,7,8,8,8,8,7,8,7,7,7,7,7,7,7,7,6,6,7,7,7,7,7,7,7,7,7,7,7,6,6,7,7,6,6,7,6,6,6,6,6,6,7,7,8,8,7,7,8,7,7,7,7,7,7,7,6,7,7,7,6,7,6,6,6,7,6,6,6,6,6,5,6,6,5,5,6,6,5,5,6,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,5,6,6,6,5,6,6,7,7,7,6,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,5,5,5,6,5,6,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,4,4,4,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,7,7,8,9,11,12,12,10,10,12,11,11,11,14,14,13,15,17,17,17,19,20,22,20,22,19,19,21,20,19,21,21,21,19,20,23,23,25,27,24,26,26,27,27,27,28,27,27,27,28,28,28,28,28,27,27,27,27,27,27,27,25,27,27,25,26,25,24,26,24,23,23,23,23,21,21,19,19,19,16,15,14,12,11,8,6,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,6,6,6,6,7,7,6,6,6,6,6,6,6,7,7,6,6,6,5,5,6,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,7,7,7,7,7,6,6,5,5,5,5,5,4,4,5,5,4,5,5,4,4,5,4,4,4,4,4,3,4,4,4,3,3,4,3,3,4,4,3,4,4,4,5,6,7,7,5,5,5,5,4,5,6,6,6,6,7,7,7,8,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,4,3,3,4,3,3,3,4,4,3,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,7,8,8,8,8,7,7,7,7,7,6,6,5,5,4,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,3,2,2,2,2,2,2,1,2,1,1,1,0,1,1,1,1,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,3,3,3,3,2,3,3,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,7,8,9,9,10,12,10,12,12,13,14,15,18,17,20,19,19,18,20,19,19,22,20,21,22,20,24,23,23,23,24,23,24,25,23,24,23,23,23,20,22,24,23,22,23,22,22,22,24,22,20,24,23],[28,28,28,28,28,28,27,27,27,26,26,26,26,25,25,25,25,25,25,25,24,24,24,25,25,25,26,26,26,26,25,26,27,27,26,26,25,26,27,26,27,26,26,26,25,25,25,23,23,22,23,22,20,20,19,19,18,18,17,16,14,13,10,8,7,6,6,6,6,5,5,5,5,5,6,6,6,7,7,6,6,7,7,6,7,8,8,8,8,8,8,9,9,9,10,10,9,10,11,10,10,11,11,11,11,12,12,12,12,13,13,12,11,11,11,12,11,12,11,11,11,10,10,11,11,10,10,11,10,10,10,10,9,11,10,11,11,10,10,10,10,10,10,10,9,9,10,10,9,10,10,8,9,9,10,9,10,10,10,10,9,8,8,9,9,8,8,9,8,8,9,9,8,9,9,9,9,9,9,9,9,8,9,9,8,8,9,9,8,8,8,8,8,9,9,10,10,10,9,10,9,9,10,10,9,9,9,9,8,9,9,9,8,9,9,8,8,8,8,8,8,8,8,7,7,7,7,7,7,8,6,7,7,8,8,9,8,9,9,9,9,9,9,8,8,9,8,8,7,8,8,8,7,8,8,8,8,9,9,8,8,7,6,7,8,7,7,7,7,7,7,7,7,6,7,7,7,8,8,8,8,7,7,6,6,7,6,6,7,6,6,6,7,6,6,6,7,6,6,6,5,6,6,6,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,8,8,8,9,11,12,13,12,10,14,13,11,12,14,14,12,14,17,17,17,18,19,20,20,22,19,18,19,20,18,19,20,20,19,21,22,22,24,26,24,25,25,26,26,27,27,27,27,27,28,27,27,27,27,26,27,26,27,26,25,26,24,25,25,24,25,24,24,25,23,23,22,22,23,21,21,20,19,18,15,14,13,11,11,8,7,5,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,6,6,5,6,7,6,6,7,8,8,7,7,8,7,7,7,6,7,8,7,8,8,7,7,7,6,5,6,6,5,5,6,6,5,5,5,5,5,4,5,5,5,5,5,5,6,5,5,6,6,6,7,6,7,7,8,7,9,8,9,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,5,5,6,6,6,5,5,6,5,5,6,6,5,5,6,6,7,8,8,8,7,7,7,7,7,7,8,7,8,9,9,10,9,10,9,9,10,9,9,9,8,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,6,6,7,6,8,7,8,8,8,8,8,8,9,9,9,9,10,10,9,10,10,10,9,9,8,9,9,8,8,7,7,6,6,6,6,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,1,1,0,1,1,2,2,3,2,2,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,2,3,2,3,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,9,10,10,11,11,11,12,12,13,15,16,16,17,19,19,19,18,20,18,18,23,19,21,21,21,24,24,23,23,24,23,24,25,24,22,23,24,22,21,22,24,23,20,22,21,22,22,24,20,20,22,21],[29,29,29,29,29,29,28,28,28,27,27,26,27,25,27,26,27,26,25,26,26,25,26,27,26,27,28,26,27,27,26,28,28,28,27,28,27,28,28,28,28,28,27,28,27,27,26,25,25,25,24,23,23,22,21,20,20,19,19,18,16,13,10,8,7,6,5,5,5,5,4,4,4,4,5,5,5,6,5,6,5,6,6,5,6,6,6,6,7,7,7,7,7,7,8,8,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,10,9,9,9,10,10,10,9,9,10,9,9,9,9,9,8,9,8,8,8,8,8,8,8,9,9,8,8,8,8,8,8,8,7,7,8,8,7,8,8,7,7,7,8,8,8,9,8,8,7,7,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,7,7,7,7,7,7,7,7,7,6,7,6,7,7,7,7,8,8,8,8,8,7,8,8,8,8,7,7,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,8,7,8,7,7,7,7,7,7,6,6,6,6,6,6,6,6,7,7,7,7,7,6,6,6,6,5,6,5,5,5,5,5,5,5,6,5,6,6,6,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,5,4,4,5,6,5,7,8,8,9,11,13,13,12,11,13,13,13,13,14,14,15,15,17,17,18,19,19,22,20,22,20,18,21,20,18,20,20,20,18,20,21,22,23,26,24,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,26,27,27,25,25,25,25,26,25,25,24,24,25,22,23,23,23,22,22,21,21,19,18,16,15,13,11,10,7,6,5,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,6,6,6,6,6,6,5,6,6,6,6,7,6,6,6,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,5,5,5,5,6,6,7,7,8,7,7,7,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,7,7,7,6,6,5,6,5,6,6,6,6,7,7,8,7,7,7,7,7,7,7,6,7,7,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,6,6,6,6,7,7,7,6,7,7,7,8,7,8,8,8,8,8,8,8,8,7,7,7,8,7,7,7,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,3,2,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,4,4,3,3,4,4,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,7,8,9,9,10,11,11,11,12,13,14,14,17,15,20,18,18,18,19,18,19,22,19,22,23,21,25,23,24,24,24,22,25,25,23,23,23,25,22,21,22,24,24,22,24,23,21,24,24,22,20,23,23],[29,29,28,29,29,29,29,28,28,27,28,27,28,26,26,27,27,26,26,27,26,26,27,27,25,27,28,26,28,28,26,28,29,29,28,28,28,28,28,28,29,28,27,28,28,27,27,25,26,25,24,22,24,21,22,21,20,21,20,19,15,14,9,7,7,6,6,6,6,5,6,5,5,5,6,6,6,6,7,7,7,7,7,6,7,7,7,7,8,8,8,9,8,8,9,9,9,9,10,10,10,10,11,10,10,12,12,11,11,12,13,12,10,10,10,11,11,12,11,11,12,10,10,11,11,11,10,11,10,10,10,10,9,9,10,10,11,9,10,10,9,9,9,10,9,9,10,9,8,9,9,9,8,8,9,9,9,9,9,9,8,8,8,8,8,8,9,9,8,8,9,8,8,8,9,9,9,9,9,9,9,8,8,9,8,8,8,8,7,7,8,8,7,8,8,9,9,9,9,9,9,9,8,9,8,9,8,8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,7,7,7,7,7,7,7,7,6,7,7,8,9,9,8,9,9,9,8,8,8,8,8,8,8,7,7,7,7,7,6,7,7,7,8,8,7,7,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,6,6,6,6,5,6,6,6,5,5,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,8,8,9,12,12,14,13,10,14,13,12,14,15,14,16,17,18,18,19,20,21,22,21,22,21,21,21,20,20,21,21,21,19,21,23,23,23,25,24,25,25,27,26,27,27,27,27,27,28,27,28,28,28,27,28,27,27,27,27,27,25,27,26,26,27,26,26,27,24,24,24,24,23,23,21,21,20,20,17,15,14,12,10,8,7,6,5,4,4,4,4,4,4,3,4,4,4,4,5,4,5,6,6,5,6,6,7,7,7,8,8,7,7,7,7,6,7,6,7,7,7,8,8,7,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,5,4,4,4,4,4,5,5,5,5,5,6,5,6,7,7,8,8,9,8,8,7,7,6,6,6,6,6,5,5,6,6,5,6,6,6,6,6,5,5,4,5,5,5,4,5,5,4,4,5,4,4,5,5,4,5,5,5,6,7,7,7,7,7,6,6,6,6,8,7,7,7,8,8,9,8,9,9,8,8,8,7,8,7,7,7,7,6,7,6,5,6,6,5,5,6,6,5,5,6,5,4,5,5,4,4,5,5,4,4,5,4,4,5,5,5,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,4,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,5,5,6,6,7,7,8,8,8,8,8,8,8,9,8,8,8,9,9,9,9,8,9,9,8,8,8,8,8,8,7,7,6,6,5,6,5,5,4,4,5,5,4,4,4,4,3,3,4,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,0,1,1,2,2,2,2,2,2,2,3,2,3,3,3,2,3,3,3,3,3,3,3,4,3,3,3,2,2,3,3,2,2,2,3,3,3,3,4,4,3,4,4,3,3,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,8,9,10,10,11,13,12,12,14,15,15,17,19,19,23,20,20,20,22,20,21,24,21,23,24,22,26,25,25,25,26,25,26,26,25,25,25,26,25,24,24,26,26,24,25,23,25,24,26,23,20,24,24],[29,28,28,28,28,28,28,27,27,27,26,26,26,26,26,26,25,25,25,25,25,25,25,25,25,26,26,26,26,26,25,27,27,27,27,28,27,28,27,28,28,27,26,27,27,27,26,24,24,24,24,22,23,22,20,20,20,19,19,17,15,13,10,9,8,8,9,8,8,8,8,8,8,9,9,9,9,10,10,10,9,10,10,8,10,11,10,10,10,11,12,12,12,12,13,13,13,14,13,14,14,14,14,14,15,16,16,16,16,16,17,15,15,15,15,15,16,16,15,15,16,15,14,15,15,15,15,15,15,14,14,14,14,14,14,14,14,14,13,13,14,13,13,14,14,13,14,15,13,14,14,13,13,12,14,13,14,13,13,14,13,12,12,12,13,12,12,12,13,13,13,14,13,13,14,14,13,13,13,13,14,13,13,13,13,12,12,12,12,12,12,11,11,12,12,13,13,13,11,12,12,12,11,11,11,10,10,11,11,11,12,11,11,12,12,11,11,12,13,10,11,13,12,10,11,12,11,9,11,11,9,11,10,11,11,11,12,12,12,13,13,12,12,13,12,12,12,11,10,12,11,11,9,11,10,11,12,12,11,10,10,10,10,10,10,10,8,10,10,8,8,9,9,8,9,9,10,11,9,10,10,10,8,8,9,10,8,8,10,9,8,8,10,8,8,9,9,9,9,9,8,8,8,9,9,9,9,9,9,9,9,10,9,9,9,10,9,9,9,9,8,8,8,8,8,8,8,7,7,7,7,8,8,6,7,9,7,8,12,13,12,12,11,12,13,11,13,14,15,15,16,18,19,19,19,20,23,20,23,19,19,22,20,19,20,20,20,20,21,23,22,23,25,23,24,25,24,26,26,26,26,26,26,26,27,27,27,27,26,27,26,26,27,25,26,25,26,25,24,26,25,24,26,23,23,23,23,23,23,22,21,20,19,17,16,14,13,11,10,8,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,8,8,7,8,7,9,8,7,8,9,9,8,9,9,8,9,9,9,10,9,9,10,10,8,8,8,7,7,8,7,7,8,8,7,7,8,8,8,8,8,8,7,8,7,7,9,8,7,8,8,8,8,9,9,9,9,10,10,10,11,11,11,11,10,10,10,10,10,10,9,9,9,10,9,8,9,10,8,9,9,8,8,7,7,8,7,7,7,7,5,7,8,6,6,7,7,6,6,6,6,7,8,8,8,8,8,8,9,8,8,10,9,9,10,11,11,11,11,10,11,12,11,11,11,9,10,10,10,9,10,10,9,8,9,9,8,7,8,8,7,7,8,8,6,7,8,6,6,7,7,6,7,8,7,6,8,8,9,7,8,7,7,6,7,7,6,5,6,5,5,5,6,6,5,4,5,5,5,4,5,5,5,5,6,6,5,7,7,7,7,8,8,8,9,9,10,10,11,10,10,11,11,11,12,12,12,13,12,13,11,11,11,12,11,11,11,10,9,10,9,9,9,9,8,8,8,8,7,8,7,7,7,6,6,7,5,4,6,5,4,5,5,4,4,4,4,4,4,4,3,4,3,3,3,2,3,4,3,3,3,4,4,4,4,5,4,4,5,5,6,6,6,6,5,5,5,5,4,4,5,3,3,4,4,2,3,3,2,1,0,1,1,1,2,2,3,3,3,3,4,3,3,4,4,4,4,5,5,6,6,6,6,7,5,4,5,4,4,4,4,3,4,4,4,4,4,5,5,4,5,6,5,5,5,6,6,5,7,8,7,7,8,9,8,9,9,9,9,9,11,11,11,12,13,12,12,13,15,15,15,18,19,20,22,20,23,19,21,21,20,25,20,22,23,20,26,23,23,24,24,24,25,26,23,23,24,24,22,21,22,25,24,22,24,22,21,23,24,20,20,22,22],[29,28,28,28,28,28,28,28,27,27,27,26,27,25,26,27,26,25,25,25,25,24,25,25,25,25,27,26,26,27,25,26,27,27,26,27,26,27,28,27,28,27,27,27,26,26,26,25,25,23,23,24,22,22,22,21,20,20,20,17,15,14,10,8,8,7,6,7,6,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,9,10,9,9,9,10,10,11,10,11,12,11,11,11,13,12,13,13,13,13,13,14,15,15,14,16,15,14,13,13,14,14,13,14,14,14,14,12,13,14,14,13,12,14,13,13,13,13,12,13,12,13,13,12,13,13,12,11,12,12,11,11,12,12,11,12,12,11,10,9,11,11,12,11,11,12,10,10,10,10,10,10,11,11,10,10,11,12,11,11,11,11,11,11,11,11,12,11,11,11,11,11,10,11,10,10,10,9,10,10,10,12,12,11,10,11,11,10,10,11,10,9,9,9,9,10,11,10,9,11,10,10,10,10,11,9,9,10,10,9,10,9,9,8,9,10,9,9,9,9,11,10,10,11,12,12,10,10,12,11,10,11,11,10,9,11,10,10,9,10,10,10,11,10,10,9,8,9,8,8,9,9,8,8,9,8,8,8,9,7,7,8,8,9,8,9,9,8,8,7,8,8,8,8,8,8,7,7,8,8,8,8,9,8,8,7,6,7,8,7,7,8,8,7,7,8,7,8,8,8,7,8,8,7,7,7,7,6,7,7,7,6,6,5,6,6,5,7,6,5,7,8,8,8,11,13,13,11,11,14,13,12,13,14,14,16,16,18,17,18,20,20,21,20,21,21,19,19,18,16,16,17,17,15,18,21,20,21,24,24,25,25,25,26,27,27,27,28,28,28,27,28,28,27,26,27,26,27,25,26,27,24,26,26,25,26,25,25,27,23,24,24,23,23,23,22,22,20,19,18,16,14,13,11,8,7,6,5,5,5,5,5,5,5,6,6,6,5,6,6,6,6,7,7,6,7,8,7,6,7,8,7,8,8,8,7,8,7,8,8,8,7,9,8,7,8,9,7,6,8,6,6,6,7,6,5,6,7,6,6,6,7,5,7,6,6,7,7,6,7,7,7,8,8,8,8,8,10,9,10,11,10,10,10,9,10,9,9,9,9,8,8,8,9,8,8,9,8,8,8,8,7,7,6,7,7,6,6,7,6,5,6,6,6,6,7,7,5,6,6,7,8,8,9,9,8,8,7,7,8,8,9,8,9,10,9,11,10,10,9,10,10,10,9,9,9,9,8,8,8,8,8,8,8,8,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,6,7,7,6,7,7,7,7,7,6,6,5,6,6,5,4,5,5,5,5,6,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,7,8,8,8,9,9,9,9,10,9,9,10,11,10,11,12,12,10,11,10,10,10,10,10,10,9,9,9,8,8,7,7,7,6,6,7,6,5,6,6,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,3,3,3,4,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,4,4,4,5,3,3,3,4,3,2,3,2,2,2,2,1,1,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,5,5,5,4,3,3,3,3,3,2,3,2,3,4,4,4,5,4,4,4,5,4,4,5,5,5,5,6,6,7,7,7,8,8,8,9,9,9,9,11,11,11,12,12,14,12,13,15,16,16,17,18,19,22,22,21,20,22,21,21,25,22,24,25,21,27,24,24,25,25,22,27,27,24,24,25,24,23,21,23,25,24,23,24,24,21,23,25,22,21,25,24],[29,28,27,27,28,27,27,28,26,25,26,25,26,25,25,25,24,25,25,26,25,24,25,26,25,25,26,24,26,25,24,26,27,26,25,27,26,26,26,26,26,25,25,26,26,25,24,24,23,24,23,21,23,21,21,20,20,20,19,17,15,13,9,7,6,6,6,5,6,6,6,6,6,6,7,6,7,8,8,7,8,8,7,7,8,9,8,8,8,9,9,10,10,10,11,11,10,11,11,11,12,12,12,12,12,12,13,13,13,13,13,12,13,13,12,12,12,14,13,13,13,11,12,13,13,13,12,13,13,13,12,12,12,12,11,12,13,11,13,11,11,11,11,12,11,11,12,12,10,11,12,11,9,9,11,10,11,11,10,11,10,10,10,10,9,9,10,11,10,9,10,11,10,11,12,11,11,12,11,11,11,10,10,11,11,10,11,11,9,9,10,10,9,10,10,11,12,11,10,11,11,10,9,10,9,10,9,9,9,9,10,9,9,10,10,9,8,10,10,8,8,10,10,9,8,10,9,8,9,9,8,8,9,9,10,10,10,10,11,12,11,10,11,11,10,11,11,10,9,10,11,9,9,9,9,10,10,10,9,8,8,8,9,8,9,8,8,8,8,8,8,8,8,7,7,7,8,9,8,8,8,8,8,7,7,8,7,7,8,7,7,7,8,8,7,8,8,8,7,6,6,7,7,7,7,7,7,7,7,7,8,8,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,5,6,6,5,6,6,6,6,7,7,7,10,11,11,11,9,12,12,11,12,14,14,13,15,17,17,16,19,20,21,19,21,19,20,19,19,18,20,18,18,18,20,21,22,22,23,24,24,24,24,26,26,26,26,26,26,27,27,27,27,27,27,26,25,26,26,25,26,23,25,25,22,25,24,23,26,23,23,23,22,22,21,20,21,20,18,16,15,14,12,10,9,7,6,5,5,5,6,5,6,5,6,6,6,5,5,6,5,6,6,6,6,6,6,6,6,6,7,7,7,7,8,7,8,7,7,8,8,7,8,7,6,7,7,7,6,6,7,6,6,6,6,5,6,6,6,6,6,6,6,7,6,6,6,7,7,7,7,7,7,7,8,7,7,9,9,9,9,9,9,10,9,9,9,9,9,8,8,8,8,9,8,8,9,8,8,8,8,7,7,6,6,7,6,7,6,7,6,6,6,6,6,6,6,5,5,5,6,6,7,7,8,8,7,7,7,7,7,8,8,8,8,9,10,10,10,9,10,10,9,9,9,8,8,7,7,7,7,8,7,6,6,6,6,5,6,6,6,6,6,7,6,6,6,6,6,6,6,6,5,6,6,6,7,7,7,6,7,7,6,6,6,6,6,5,5,6,5,5,6,5,6,5,4,5,5,5,4,5,4,4,4,5,5,5,5,6,5,5,5,6,6,7,7,8,9,8,8,9,9,8,9,10,10,9,10,10,10,10,9,10,8,9,9,8,8,8,8,8,7,6,6,6,6,5,6,5,5,6,6,5,5,5,5,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,4,3,3,3,4,3,4,4,4,4,5,5,4,3,4,4,4,4,4,4,3,3,3,2,2,2,2,2,1,1,0,1,1,1,2,1,2,2,2,2,2,3,3,3,3,3,3,5,4,5,5,5,4,3,3,3,3,3,3,3,3,3,4,4,4,5,5,4,4,5,5,5,6,6,5,6,7,7,7,7,7,8,7,7,8,9,8,8,10,11,11,11,13,13,12,12,14,16,15,18,18,19,20,20,21,19,21,20,19,23,20,22,23,20,25,22,23,23,24,21,25,25,23,22,24,23,21,20,24,24,22,21,22,22,21,23,23,20,21,23,22],[28,29,28,28,29,28,28,29,28,27,28,26,28,26,27,25,27,27,26,27,26,25,26,26,25,26,28,25,27,27,25,27,28,28,27,28,27,27,27,27,27,27,26,27,26,26,26,25,25,25,24,23,24,22,22,21,21,21,19,18,16,14,10,6,5,5,4,4,4,4,4,4,4,4,5,4,5,6,6,5,5,6,6,5,6,6,7,7,7,7,7,8,7,7,8,8,8,8,9,9,9,9,9,10,10,11,11,11,11,12,11,10,10,9,9,10,10,11,11,11,10,9,10,11,10,9,10,10,10,9,10,9,9,9,9,9,10,9,9,9,8,8,9,9,8,8,9,8,8,8,8,7,7,7,8,8,8,8,8,9,8,8,8,8,7,7,8,8,7,7,8,8,7,7,8,8,8,9,8,8,8,7,8,8,8,7,7,8,8,7,8,7,8,7,8,9,10,9,9,9,9,9,8,8,8,8,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,7,7,8,8,8,8,8,8,7,8,8,7,7,8,7,6,7,7,6,6,7,7,7,8,8,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,6,7,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,5,4,4,4,4,4,4,4,5,3,5,5,5,7,9,9,12,11,8,12,13,12,12,14,14,16,16,18,18,18,19,20,21,21,20,19,19,19,19,19,19,19,18,20,19,19,22,22,24,22,24,23,24,25,26,26,25,26,26,26,26,26,26,26,26,25,25,25,25,25,24,23,25,24,23,25,24,24,26,24,24,24,23,24,23,21,21,21,19,17,16,14,12,9,7,5,4,4,4,3,3,4,3,4,4,5,4,4,4,5,4,5,6,5,6,6,6,6,6,6,7,7,7,7,7,6,6,6,6,7,7,6,7,7,6,7,6,6,6,6,5,5,5,5,4,5,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,6,6,6,6,7,8,8,8,8,8,8,7,7,6,6,6,6,6,5,5,6,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,5,5,4,4,4,5,5,7,7,7,7,7,6,6,5,6,7,6,6,7,7,7,7,8,7,8,8,7,7,7,7,6,6,6,6,5,6,5,4,5,5,4,4,5,5,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,6,6,7,7,6,6,7,7,7,7,7,7,8,8,7,8,8,8,7,7,7,7,7,7,7,6,6,5,4,4,4,4,4,4,3,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,6,5,5,6,6,6,6,7,8,9,10,10,11,12,11,13,13,15,14,16,19,20,23,20,22,22,22,22,19,23,21,22,26,20,24,25,26,25,26,25,27,26,25,25,26,25,23,22,25,27,26,23,25,25,25,25,24,23,22,24,23],[28,28,28,28,28,29,28,28,28,27,28,26,28,27,27,27,27,27,26,26,27,25,26,27,27,26,28,27,27,27,26,27,27,27,27,27,27,27,28,27,27,27,27,27,27,26,26,25,25,24,24,24,23,22,22,21,20,20,21,19,17,15,10,6,6,5,5,5,5,5,5,5,5,5,6,5,6,7,7,6,6,7,7,6,7,7,6,7,7,7,7,8,7,8,9,8,8,8,9,9,9,10,10,9,10,10,11,11,11,12,12,11,10,9,10,11,10,11,10,11,10,9,9,10,10,10,9,9,9,9,10,9,9,10,9,10,9,9,9,10,8,8,9,9,8,8,9,8,8,9,9,8,7,8,8,8,8,9,8,9,8,8,8,8,8,7,8,8,8,7,8,8,8,8,8,8,8,9,8,8,8,7,8,8,8,7,8,8,8,7,7,7,7,8,8,9,9,8,8,8,8,8,8,8,8,7,8,7,7,8,8,7,7,8,8,7,7,8,8,7,7,7,8,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,9,9,8,8,9,8,7,8,8,7,7,7,7,7,7,7,7,7,8,8,8,6,7,7,6,7,7,7,6,6,6,6,6,6,6,5,6,6,6,6,6,7,7,6,6,5,6,6,6,6,6,6,5,6,6,6,6,6,7,6,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,5,5,5,7,7,8,11,12,12,12,11,13,13,12,14,14,15,15,16,18,18,19,19,21,22,21,23,21,21,20,19,18,18,19,18,17,20,23,21,22,26,25,26,24,25,26,28,27,27,28,28,27,28,27,28,27,26,27,26,27,26,25,26,23,26,25,24,27,24,24,27,24,24,24,22,23,23,21,20,20,20,17,16,15,12,11,8,6,5,4,4,4,4,3,4,4,4,5,5,4,5,5,4,4,6,6,5,6,7,6,5,6,6,6,6,6,7,6,6,6,6,6,7,7,7,7,6,6,6,5,5,6,5,5,5,5,5,5,5,5,4,5,5,5,5,6,5,5,6,5,5,6,6,6,6,6,6,6,6,7,7,8,9,8,8,8,7,8,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,6,5,5,6,5,5,5,5,4,4,5,5,4,5,5,4,4,4,5,5,6,6,6,6,6,6,6,6,6,7,6,7,7,7,8,8,8,7,7,7,8,7,7,7,7,7,6,6,6,6,6,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,4,3,3,4,4,4,4,4,4,4,5,5,5,6,6,6,7,7,7,7,7,7,7,8,8,7,8,8,7,8,8,8,8,7,8,8,7,7,7,6,6,5,5,5,5,5,5,5,4,5,5,4,4,4,4,3,4,4,4,3,4,4,3,3,3,3,3,3,4,3,2,3,3,2,3,3,2,3,2,2,3,2,2,3,3,3,3,3,3,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,2,2,1,2,2,2,2,2,3,3,3,3,3,4,4,3,3,2,2,2,3,3,3,3,3,3,4,3,4,4,4,4,4,4,4,4,5,5,4,5,5,5,5,6,6,6,6,6,6,7,7,8,9,10,10,10,12,11,12,13,14,14,15,17,17,20,19,20,18,20,19,19,22,21,22,23,21,25,23,24,25,25,22,26,25,24,24,25,24,23,22,23,25,24,21,23,21,24,23,24,23,22,25,23],[27,27,27,28,27,28,27,27,27,26,25,25,26,25,25,25,25,26,24,26,26,25,25,26,25,25,26,25,26,26,25,26,27,27,25,27,25,26,26,26,27,26,25,26,26,26,25,24,22,23,23,23,21,20,21,20,20,21,21,18,16,14,10,7,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,9,8,9,9,9,10,9,9,10,10,10,10,11,11,11,11,12,12,13,12,13,13,12,11,11,11,11,11,12,11,12,12,10,10,12,11,11,11,12,12,11,11,11,11,11,11,12,11,11,11,11,11,10,10,10,10,10,11,10,9,10,10,9,9,8,10,9,10,10,9,10,9,9,8,9,9,9,9,9,9,8,9,9,9,9,10,10,9,10,10,9,10,9,9,10,9,9,9,10,9,9,9,9,9,9,9,10,11,10,9,10,10,9,9,10,9,8,8,8,8,9,9,8,8,10,9,8,9,9,9,8,8,9,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,10,9,9,9,9,9,9,9,8,8,9,9,8,8,8,8,9,9,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,7,8,7,8,8,8,7,7,7,7,7,7,7,6,7,6,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,6,6,6,6,6,6,6,5,5,6,5,6,5,5,5,5,5,5,5,6,5,5,8,8,7,10,10,12,10,10,12,12,11,12,13,14,12,16,16,18,17,20,20,21,20,21,20,18,17,16,17,16,18,18,16,19,22,21,22,24,24,24,24,25,26,27,27,26,27,27,27,27,27,26,27,25,26,25,26,25,23,25,22,25,25,23,24,23,23,26,23,22,23,21,21,21,20,19,19,17,16,15,14,11,11,8,6,5,4,4,4,4,4,4,4,5,5,5,4,5,5,4,5,5,6,5,5,6,6,6,6,7,7,7,7,7,7,7,7,7,8,8,7,8,7,6,6,7,6,5,6,6,5,5,6,5,5,5,5,5,5,6,5,5,6,6,5,6,6,6,6,6,6,6,7,7,7,7,7,8,9,9,9,8,9,8,8,8,7,8,7,7,7,7,7,7,7,7,7,7,6,6,6,6,5,5,6,6,6,6,6,5,5,6,5,5,5,6,5,5,5,6,6,7,7,7,7,6,6,6,7,7,8,7,8,8,8,9,9,9,8,9,9,9,8,8,8,8,7,7,7,8,7,7,6,7,6,6,6,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,5,6,5,5,5,5,4,5,5,4,4,5,5,4,4,4,4,4,4,4,5,4,4,4,4,4,4,5,6,6,5,6,6,6,7,7,7,8,8,8,8,8,8,8,9,9,8,9,9,8,9,9,9,8,8,8,8,8,8,7,7,7,6,6,5,6,5,6,5,5,5,5,4,5,5,5,4,4,4,4,4,4,4,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,2,2,2,3,2,3,3,3,4,4,4,5,4,4,4,4,4,4,4,5,5,5,6,6,6,6,6,7,7,7,7,7,8,7,9,9,10,11,11,13,12,12,14,15,14,16,17,17,20,20,21,17,20,19,18,22,20,21,22,20,24,22,22,23,24,21,24,24,22,23,23,24,21,20,22,22,21,20,21,21,22,22,23,21,20,23,23],[28,28,27,27,28,28,28,27,27,26,27,26,27,25,26,26,26,26,26,26,26,25,26,26,25,26,26,25,26,26,25,27,27,27,26,27,26,27,27,27,27,26,25,26,26,26,25,24,24,24,24,23,23,23,22,21,21,21,20,19,17,14,10,7,6,5,5,5,5,4,5,5,5,5,6,5,6,7,7,6,7,7,7,6,7,7,7,7,8,8,8,8,8,8,8,9,8,9,9,9,10,10,10,10,10,11,11,11,12,12,11,11,10,10,10,10,10,11,11,11,11,10,10,11,11,10,10,11,10,10,11,10,10,10,10,10,10,10,10,10,9,9,10,10,9,9,10,9,8,9,9,8,8,8,9,8,8,9,8,9,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,10,9,9,9,9,9,9,9,8,8,8,8,8,9,9,9,10,9,8,10,9,9,9,9,9,9,8,8,8,8,8,8,8,9,8,8,8,8,9,8,8,8,8,8,8,8,8,7,7,8,7,7,7,8,8,9,8,9,9,9,8,9,9,9,9,9,9,8,8,9,8,8,8,8,8,8,9,9,9,7,7,8,7,7,8,8,7,7,7,7,7,7,7,6,7,7,7,8,7,7,8,7,7,6,7,7,7,6,7,7,6,6,7,7,7,7,7,7,6,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,6,6,6,6,6,5,5,5,5,5,6,5,5,5,5,5,5,4,5,6,9,8,11,12,12,11,12,14,15,14,15,16,15,17,17,18,18,18,21,21,22,21,22,21,20,20,20,18,19,18,19,20,20,22,22,22,24,23,24,25,25,26,26,26,26,27,27,27,27,27,27,27,26,26,24,26,26,24,25,24,24,24,22,25,24,23,25,22,23,23,22,21,21,20,19,20,19,17,15,13,12,11,9,6,6,5,5,4,5,5,5,5,5,6,5,5,5,6,5,6,6,6,6,6,7,6,6,6,8,7,8,7,8,7,8,7,7,8,9,7,9,8,7,7,7,7,6,7,7,5,6,6,6,5,6,6,5,5,6,5,5,6,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,9,9,9,9,9,8,8,8,8,8,8,7,7,7,8,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,5,5,6,6,5,5,5,4,4,5,6,8,8,8,7,7,6,6,7,6,7,7,7,8,8,8,8,8,8,9,9,8,8,8,7,7,7,7,6,6,6,6,5,6,6,5,5,6,5,5,5,5,6,5,5,5,6,5,5,5,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,6,7,6,7,7,7,8,8,8,8,8,8,8,8,9,8,9,8,8,8,8,8,7,7,7,7,7,6,6,5,4,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,4,5,4,4,4,4,4,5,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,1,1,2,1,1,0,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,5,4,4,6,5,5,5,5,5,5,5,6,5,5,6,6,6,6,7,7,7,7,8,8,7,8,9,10,10,11,12,13,12,12,14,16,16,16,19,17,20,19,20,19,21,18,19,22,20,22,23,20,24,22,23,23,24,22,24,24,23,24,23,23,21,21,22,23,23,23,22,22,23,24,22,22,20,23,22],[28,29,28,28,29,29,29,29,28,27,28,28,28,27,28,28,28,28,27,27,27,25,27,26,26,27,28,27,28,28,25,28,29,29,28,28,28,29,28,28,28,28,27,27,27,26,26,25,25,24,25,24,23,22,22,22,21,20,20,19,17,16,11,7,7,5,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,10,10,10,10,10,9,8,8,8,9,9,9,9,9,10,8,8,9,9,8,8,9,8,8,8,8,8,8,8,9,8,8,8,9,8,7,8,8,7,7,8,7,7,7,7,7,7,7,7,7,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,7,7,7,7,8,8,8,7,8,8,8,8,8,7,7,7,7,7,7,7,6,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,7,7,7,7,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,6,7,7,7,7,6,6,6,6,5,6,6,5,5,6,5,5,6,6,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,3,4,6,7,7,9,10,12,10,8,12,11,13,14,14,13,15,16,17,18,18,19,20,22,22,22,21,21,20,20,19,18,19,22,19,20,21,22,23,27,24,25,25,26,27,27,27,27,27,27,28,27,27,27,27,27,27,27,26,26,25,26,25,25,26,25,26,25,24,27,23,23,23,22,23,22,20,20,20,19,16,16,15,13,12,8,5,4,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,7,6,7,6,7,6,7,6,6,6,6,6,7,6,8,7,5,6,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,7,7,8,8,8,8,7,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,5,5,7,7,7,7,6,5,5,5,5,6,6,6,6,6,7,7,6,7,7,7,6,6,6,6,5,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,5,5,6,6,6,6,6,6,6,6,7,7,6,7,7,7,7,7,7,7,7,7,6,7,6,6,7,6,5,5,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,1,2,2,2,2,2,2,3,3,3,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,5,5,5,6,6,6,6,7,8,9,10,10,12,12,13,13,15,15,17,19,18,23,20,21,21,22,20,21,24,23,23,25,23,26,25,26,26,26,25,26,26,25,25,25,26,25,23,24,26,25,24,25,25,26,26,27,23,21,25,24],[28,28,28,27,28,28,28,27,28,26,28,27,27,26,25,27,26,27,26,26,27,26,26,27,26,26,27,26,26,27,26,27,27,27,26,27,27,27,26,26,27,26,25,25,25,24,23,22,22,20,22,21,21,20,20,20,20,21,20,18,16,15,12,7,6,4,4,4,4,4,4,4,4,4,5,4,5,6,6,6,5,6,6,5,6,7,7,6,6,7,7,7,7,8,8,8,8,8,8,9,9,8,9,9,10,10,11,10,10,11,11,10,9,8,8,9,9,9,9,9,9,8,8,9,9,9,9,10,9,9,10,9,8,8,10,10,10,8,8,9,9,8,8,9,8,8,9,8,7,8,8,7,8,7,8,8,8,8,7,7,7,7,6,7,7,7,6,7,7,7,7,7,7,8,8,8,8,8,9,8,8,8,8,8,8,8,8,8,7,7,8,7,8,7,8,8,9,8,8,8,9,8,8,8,8,7,7,7,7,7,7,7,7,7,7,8,7,7,7,7,7,7,7,6,6,7,7,6,6,7,6,6,6,7,6,7,7,7,7,7,7,6,7,7,6,6,7,7,6,7,7,7,7,7,7,7,7,8,7,7,7,6,6,6,6,6,6,6,7,6,6,6,7,6,7,6,6,7,7,6,7,6,6,6,6,6,5,6,6,5,5,5,6,6,5,6,6,6,5,5,4,4,5,5,4,5,5,4,5,5,5,5,5,6,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,4,4,3,5,8,9,8,12,9,11,11,10,12,12,11,12,14,14,15,16,18,17,19,19,20,20,18,22,21,18,20,20,15,19,20,19,19,20,23,21,23,24,24,24,24,25,26,26,26,26,26,26,26,26,26,26,25,24,26,25,24,24,23,24,22,24,23,22,24,23,21,25,22,22,22,21,21,19,19,19,17,17,15,14,13,11,10,7,5,4,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,5,7,6,6,6,8,7,8,7,7,7,7,7,5,6,7,6,8,8,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,6,5,6,6,6,6,7,8,8,8,8,8,7,7,7,6,7,6,6,6,6,6,6,6,6,6,7,7,6,6,7,6,6,5,6,5,5,5,5,5,4,5,5,4,4,5,5,4,4,5,5,6,7,6,7,6,6,6,6,6,6,6,6,7,7,7,7,7,8,7,7,8,7,7,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,4,5,5,5,4,4,5,4,4,5,5,4,4,5,5,4,5,5,6,5,5,5,5,4,5,5,4,4,5,4,4,5,5,4,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,4,4,4,4,5,5,6,6,6,6,7,7,7,6,7,7,7,7,7,8,8,7,8,7,7,7,7,7,7,6,6,6,6,6,5,4,4,5,4,5,5,4,4,4,4,3,4,4,3,4,3,3,3,4,3,3,3,3,4,3,4,4,4,3,4,3,3,3,3,3,3,3,2,3,2,2,2,3,2,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,2,2,3,3,3,3,4,4,3,4,4,5,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,8,9,9,10,11,12,11,12,14,14,16,16,18,20,20,18,20,19,20,19,20,22,22,22,24,21,23,23,25,23,23,22,24,23,23,24,25,23,24,22,25,24,24,24,23,24,25,24,24,23,22,24,23],[27,27,27,27,28,28,27,28,27,26,27,26,27,26,26,26,26,27,26,27,26,26,26,27,26,26,27,26,26,27,26,27,28,28,26,27,27,27,27,26,27,26,26,26,26,25,24,24,24,23,22,23,22,22,22,22,20,21,19,18,15,14,10,6,5,4,4,4,4,4,3,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,9,10,10,9,8,8,8,8,8,9,9,9,9,8,8,9,8,8,8,9,8,8,9,8,8,8,9,9,9,9,8,9,8,7,8,8,7,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,7,6,6,6,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,7,6,7,7,7,7,7,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,6,7,7,6,6,7,6,6,6,6,6,6,6,6,6,5,5,6,5,5,6,6,6,7,7,7,7,7,7,6,7,7,6,6,7,6,6,6,6,6,6,6,7,7,7,7,7,6,6,6,5,5,6,6,5,5,6,5,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,4,4,5,5,4,5,5,5,4,4,3,4,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,4,4,3,4,3,4,4,3,3,3,3,3,4,3,3,3,3,5,6,8,6,9,9,10,9,8,12,10,11,13,13,13,15,15,16,17,17,19,20,21,20,21,20,19,20,19,19,18,20,20,19,20,21,22,23,24,24,24,23,24,25,25,25,25,26,26,26,26,26,26,26,25,26,24,25,25,24,24,22,24,24,21,24,23,22,25,21,21,23,19,20,21,19,20,19,18,16,16,12,12,11,7,5,4,3,3,3,3,3,3,3,4,4,4,4,4,5,4,5,5,5,5,5,6,6,6,6,7,7,8,6,8,6,7,6,5,6,7,6,7,7,6,6,5,5,5,5,5,4,5,5,4,4,4,4,3,4,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,8,8,8,8,7,7,6,6,6,6,6,5,5,5,5,6,5,5,6,6,5,5,6,5,5,5,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,6,7,7,6,6,6,5,5,5,6,6,6,6,6,7,7,7,7,8,8,7,7,6,6,6,5,6,5,5,5,5,4,5,5,4,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,3,4,3,4,3,3,3,4,3,3,3,3,3,4,3,4,4,4,5,5,5,5,6,6,6,6,6,6,7,7,7,6,7,7,7,8,7,8,7,7,6,6,6,6,6,5,5,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,2,2,3,3,3,3,3,4,4,4,4,5,5,4,4,5,4,4,5,5,4,5,5,5,5,6,6,6,6,6,6,6,6,6,7,8,9,10,10,12,11,11,13,14,15,15,17,18,20,18,19,19,20,18,18,21,21,21,22,21,23,23,23,23,23,22,23,24,23,23,23,22,22,21,22,22,22,22,22,21,23,23,24,22,21,23,23],[28,29,29,28,29,29,28,28,28,27,28,27,28,27,27,27,27,28,27,28,28,27,28,28,26,28,29,26,28,28,26,28,29,29,28,29,28,28,28,28,29,28,27,27,27,27,25,25,25,24,24,23,23,23,22,22,21,21,20,18,16,14,10,7,5,4,4,4,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,9,9,9,8,7,7,7,7,8,7,7,8,8,7,7,7,7,7,7,8,7,7,7,7,6,7,8,8,8,7,7,7,7,6,7,7,6,6,6,6,6,6,6,5,5,6,6,6,6,6,6,6,5,5,5,6,5,5,6,5,6,5,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,6,6,6,5,6,5,6,6,6,7,7,7,6,7,7,7,7,7,7,6,6,6,6,6,6,5,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,5,5,4,5,5,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,7,8,7,9,10,12,9,9,13,11,11,14,13,14,15,15,17,17,18,19,21,21,21,23,20,20,21,21,21,20,20,22,20,20,23,24,24,27,24,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,26,27,26,27,26,25,25,25,26,24,26,24,24,26,23,23,24,22,23,22,20,20,20,18,16,15,14,12,10,7,5,3,2,2,2,2,2,2,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,6,6,7,6,6,6,5,5,4,5,6,5,6,6,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,6,6,7,7,7,7,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,3,4,4,3,3,4,4,5,6,6,7,6,5,5,5,4,4,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,5,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,4,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,3,2,2,2,2,2,2,2,2,3,3,3,3,4,4,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,7,8,9,9,10,11,11,11,12,13,14,16,18,17,22,18,20,20,21,19,20,22,21,22,25,21,25,25,25,24,24,24,25,25,25,25,25,24,24,22,24,25,24,23,24,24,24,25,25,22,22,25,22],[28,29,28,28,29,29,28,28,28,27,28,28,28,28,27,27,28,28,28,28,28,26,27,28,27,28,29,28,28,28,27,28,28,29,28,29,27,28,28,28,28,27,28,27,27,26,25,24,25,24,24,23,22,22,22,21,20,21,19,19,16,15,10,6,5,4,4,3,4,3,3,3,3,4,4,4,4,5,5,4,4,5,5,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,8,7,7,8,8,8,8,9,10,9,9,10,9,9,8,8,7,8,8,8,7,8,9,7,7,8,8,7,8,8,8,7,8,8,7,8,8,9,8,8,8,8,7,7,7,7,6,7,7,7,6,6,7,6,6,6,6,6,6,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,7,6,6,6,6,7,6,6,7,7,6,6,7,6,6,6,6,7,8,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,5,5,6,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,5,5,4,4,5,4,3,4,5,4,4,5,5,4,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,6,7,7,9,9,9,11,9,10,12,13,13,15,16,15,16,18,19,19,20,21,22,21,23,22,21,22,19,17,20,21,21,20,20,24,22,23,25,25,26,26,26,27,28,28,27,28,27,28,28,27,27,27,27,27,26,26,26,26,26,24,25,25,25,25,24,25,26,24,24,23,22,23,23,20,21,20,19,16,15,14,12,10,7,5,3,2,2,2,2,2,2,3,3,3,4,3,3,4,4,3,4,5,4,5,5,5,5,5,6,6,6,6,7,6,6,5,5,5,6,5,6,6,5,5,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,5,5,5,5,6,6,7,7,7,7,7,6,6,6,5,5,5,5,5,4,4,5,5,4,5,5,5,5,5,5,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,3,4,4,4,5,6,6,6,5,5,5,5,4,5,5,5,5,6,6,6,6,7,6,6,6,6,6,5,5,5,5,5,4,4,5,4,4,4,4,3,4,4,4,3,4,4,4,3,3,4,3,3,4,4,3,3,4,4,3,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,6,7,7,6,6,6,6,6,6,6,5,5,5,4,4,3,4,3,4,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,2,2,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,2,2,2,2,3,3,2,2,2,2,3,3,3,3,3,4,3,4,4,4,3,4,4,3,3,4,4,4,4,5,4,4,5,5,4,5,5,5,5,5,5,7,8,9,9,10,11,11,11,11,14,14,15,18,18,20,19,20,19,20,18,19,21,20,21,23,21,24,24,22,24,24,23,24,24,23,25,24,23,23,21,23,24,23,21,23,22,24,25,25,22,21,24,22],[26,27,27,27,27,28,27,27,28,26,26,26,26,27,25,26,26,27,27,27,27,27,26,27,27,26,27,26,27,27,26,27,28,28,26,28,27,27,28,27,27,26,26,26,25,25,24,22,22,22,22,22,22,22,21,22,20,21,20,18,15,14,10,7,6,4,4,3,3,3,3,3,3,3,4,4,4,5,4,4,4,5,5,4,5,5,6,6,6,6,6,7,7,6,7,7,7,7,8,8,8,8,8,8,8,9,10,10,10,10,10,9,8,8,7,8,8,8,7,8,8,7,7,8,8,8,8,9,8,8,9,9,8,8,8,9,9,8,8,8,8,7,8,8,7,7,8,7,7,7,7,6,6,6,7,7,7,7,6,7,5,5,5,6,6,5,6,6,6,6,6,7,6,6,7,7,7,7,8,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,7,7,7,6,6,7,7,7,6,7,7,7,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,4,5,5,6,6,6,6,7,7,6,6,6,6,6,6,6,6,5,6,6,6,5,6,7,7,7,7,7,6,5,6,5,5,6,5,5,6,6,5,5,6,6,5,6,5,6,6,6,6,6,6,5,5,5,5,4,4,5,5,4,4,5,4,4,5,5,4,4,3,3,3,4,4,3,3,4,3,3,4,4,3,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,4,4,7,8,7,9,10,10,9,9,10,10,11,13,13,14,13,16,17,17,17,18,18,22,20,22,18,18,21,18,18,18,19,21,18,19,21,21,22,25,23,24,24,25,25,26,26,26,26,26,26,25,26,25,26,24,25,24,25,25,23,25,22,24,23,21,24,21,21,25,21,23,22,20,20,20,18,20,18,17,16,14,12,10,9,7,4,3,2,2,2,2,2,2,3,3,4,4,3,3,4,4,4,4,5,4,4,6,5,5,5,6,6,7,6,6,6,6,5,5,6,6,5,6,6,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,4,5,5,5,6,6,6,7,7,7,7,7,7,6,6,6,5,5,5,5,4,5,5,5,5,5,5,5,5,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,5,6,6,6,6,5,5,5,5,5,6,6,6,6,7,7,7,6,7,7,7,6,6,6,6,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,3,4,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,4,4,3,3,4,4,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,6,5,6,6,6,6,7,6,6,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,4,3,3,3,3,4,3,3,3,3,3,3,3,3,3,2,3,3,2,3,3,3,2,3,3,3,3,3,2,2,3,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,3,2,2,2,2,2,3,3,3,3,3,3,4,4,5,4,4,4,4,3,3,4,4,4,4,5,4,4,5,5,5,5,6,6,6,6,6,8,9,9,10,11,11,11,11,12,14,14,15,17,17,20,18,18,18,19,17,19,21,20,20,22,19,22,22,23,21,22,22,23,23,22,24,22,21,22,22,20,22,22,22,22,21,22,21,23,21,21,23,23],[28,29,28,28,29,29,28,29,29,28,28,28,29,28,28,28,28,29,27,28,28,28,28,28,28,28,29,28,28,28,27,28,29,29,28,29,29,28,29,29,29,28,28,28,27,27,26,24,25,24,24,23,23,23,22,23,21,21,21,19,16,14,11,7,6,4,3,3,3,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,7,6,6,6,7,7,7,7,8,8,7,8,8,7,6,6,6,7,6,7,7,7,7,6,6,7,6,6,6,7,6,6,7,7,6,7,7,7,7,7,6,7,6,6,6,6,6,5,6,6,5,5,6,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,5,5,5,5,6,5,5,5,5,5,5,6,5,5,6,6,6,7,7,6,6,7,6,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,5,5,5,5,5,4,5,5,4,5,5,4,4,5,5,5,6,6,6,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,4,4,7,6,6,7,9,10,9,11,10,10,11,13,13,13,14,15,17,17,18,20,20,22,20,23,20,20,22,20,20,20,19,21,19,21,22,24,24,26,24,25,25,26,26,27,27,27,27,27,27,27,27,26,27,26,26,27,26,26,25,26,24,25,25,24,26,24,24,25,23,23,23,22,22,22,20,21,20,18,16,15,13,12,10,7,4,3,2,2,2,2,2,2,2,3,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,6,6,7,5,6,5,5,5,4,5,6,5,6,6,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,5,5,6,6,6,6,6,6,5,5,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,6,6,6,5,5,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,2,3,3,2,2,3,3,2,2,3,3,3,3,3,4,4,4,4,4,5,5,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,3,2,2,2,2,2,2,3,3,3,3,3,3,4,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,5,6,7,8,8,10,11,11,11,12,13,14,16,17,17,21,18,19,17,20,19,18,21,20,22,23,21,23,24,24,23,23,24,24,24,24,24,24,24,24,22,24,24,24,23,23,22,24,24,25,23,22,24,23],[28,28,29,29,29,29,28,28,29,27,28,28,28,27,27,27,28,28,28,27,28,27,27,28,28,27,29,28,28,28,27,28,29,29,28,28,28,28,29,28,29,28,28,28,27,27,26,25,25,24,25,24,22,22,22,22,20,21,20,18,15,14,10,6,5,4,3,3,3,3,3,2,3,3,3,3,3,3,4,4,3,4,4,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,7,7,6,8,8,8,8,9,9,8,7,6,6,7,7,7,6,7,7,6,6,7,7,6,6,7,6,6,7,6,6,7,7,7,7,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,4,5,5,5,5,6,5,5,5,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,6,6,7,6,6,6,7,6,6,6,6,6,5,5,5,5,5,5,5,5,5,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,5,5,5,5,5,6,5,5,5,5,5,4,5,5,4,4,4,4,4,4,5,5,5,6,6,5,4,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,3,3,5,6,6,9,10,10,10,10,11,11,10,12,14,14,14,16,17,18,19,19,20,21,21,23,20,20,21,20,20,20,21,21,20,21,23,24,25,27,25,26,26,26,27,27,27,27,27,27,28,27,27,27,27,27,27,27,26,27,26,25,24,25,26,24,25,23,24,25,22,23,23,22,22,21,20,20,19,18,16,15,13,11,9,6,4,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,4,4,4,4,4,4,5,5,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,6,6,6,6,6,5,5,4,4,4,4,3,3,3,4,3,3,4,4,3,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,6,6,5,5,4,4,4,4,4,4,4,4,5,6,6,5,6,6,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,3,4,4,4,4,4,5,6,7,8,9,9,11,10,10,11,13,13,14,16,16,19,19,18,17,18,18,18,21,18,21,22,20,24,24,21,24,23,23,24,24,23,22,22,23,22,19,22,23,24,20,24,21,22,23,24,21,20,24,22],[28,28,28,28,28,29,28,28,28,27,27,27,27,27,26,27,27,27,26,27,26,27,27,27,26,27,27,26,27,27,26,27,28,28,26,28,27,27,27,27,28,26,27,27,27,27,26,24,24,25,24,23,23,22,21,22,21,21,19,19,17,15,10,6,5,4,4,3,3,3,3,3,3,3,4,4,4,5,5,4,4,5,5,4,5,5,5,5,6,6,6,7,6,6,7,7,7,7,8,7,7,8,8,8,8,9,9,9,9,10,9,9,8,8,7,8,8,7,7,8,8,7,7,8,8,7,7,8,7,8,8,8,7,8,8,8,8,8,8,8,7,7,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,7,6,6,6,5,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,6,7,6,6,6,6,7,6,6,6,7,6,6,6,6,6,6,7,7,8,7,7,7,8,7,7,7,7,7,6,6,6,6,7,6,6,6,7,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,6,6,6,7,6,6,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,6,5,6,5,5,4,4,5,5,4,4,4,4,4,4,5,4,4,4,4,4,4,3,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,5,4,7,6,8,8,9,10,9,10,12,13,12,13,13,14,14,16,17,17,18,19,20,22,19,22,20,18,21,18,16,19,20,19,17,21,23,23,24,27,25,26,26,27,27,27,28,28,28,28,28,27,27,27,27,27,27,24,28,27,26,26,22,26,24,25,26,23,24,26,23,23,23,21,22,21,20,19,19,18,16,14,12,9,8,5,4,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,5,5,5,5,5,5,5,5,5,4,4,5,4,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,4,3,4,4,4,4,4,5,5,5,6,6,6,7,7,6,6,5,5,5,5,5,5,5,4,4,5,5,4,5,5,5,4,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,4,4,3,4,4,4,5,6,6,6,6,5,5,5,5,5,6,5,5,6,6,7,7,7,7,7,6,6,6,6,6,5,5,5,4,5,5,4,4,4,4,3,4,4,4,3,3,4,3,3,3,3,3,3,3,4,3,3,3,3,3,3,4,4,3,4,4,3,3,4,4,3,3,3,3,3,3,4,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,7,7,6,7,7,6,6,6,6,6,6,6,6,5,5,4,4,3,4,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,5,4,4,5,5,5,5,5,7,8,9,9,10,11,10,10,11,13,13,14,15,15,17,18,17,16,17,17,17,20,18,20,20,19,23,22,23,22,23,22,24,23,22,22,23,23,21,19,19,23,21,20,21,20,21,21,24,20,19,22,22],[27,27,27,27,27,28,27,27,27,26,27,27,27,27,26,27,27,27,27,27,27,27,27,27,27,26,27,26,27,28,26,27,28,28,26,27,26,27,27,27,27,26,26,26,26,25,24,23,24,23,22,22,22,22,22,22,21,21,20,19,17,15,10,8,6,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,5,5,4,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,9,9,9,9,10,9,8,7,8,7,8,8,7,7,8,8,7,7,8,8,7,7,8,8,7,8,8,7,7,8,8,8,8,8,8,8,7,7,7,7,7,7,7,6,7,7,6,6,6,6,6,7,7,6,6,6,5,5,6,6,5,5,6,6,6,6,6,6,6,6,6,7,7,7,6,6,6,6,7,6,6,6,7,6,6,7,6,7,7,7,8,8,8,7,8,8,8,8,8,8,7,7,7,6,7,7,7,6,7,6,6,6,6,6,6,5,6,6,5,5,6,5,4,5,5,4,4,5,5,5,6,6,6,6,6,6,6,6,6,6,5,6,6,5,6,6,6,5,6,6,6,7,7,7,6,5,5,5,5,5,5,5,5,6,5,6,6,6,5,6,6,6,6,6,6,6,6,5,4,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,4,5,6,7,8,9,10,12,9,9,12,12,10,14,13,12,13,15,16,15,17,18,19,20,19,20,19,18,20,17,19,19,20,20,18,21,21,23,24,26,25,25,25,26,26,26,27,27,27,27,27,26,27,27,27,26,26,25,26,26,25,24,21,25,23,23,25,23,23,25,21,24,23,20,22,21,20,20,18,17,15,14,11,9,9,6,4,3,2,2,2,2,2,2,3,3,4,3,3,4,4,4,4,4,5,4,4,6,5,5,5,7,6,7,6,6,6,6,5,5,5,6,5,7,6,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,3,4,5,4,4,5,5,5,5,5,6,6,6,7,7,7,7,7,7,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,6,7,7,6,6,5,5,5,5,6,5,5,6,6,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,5,5,5,5,5,5,6,6,5,6,6,6,6,7,7,7,7,7,7,6,6,6,6,6,6,5,5,5,4,4,3,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,2,2,3,3,2,2,2,2,3,3,3,3,4,4,4,4,5,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,6,6,6,6,6,7,8,9,9,10,11,11,10,12,13,13,14,15,16,18,17,18,16,17,17,18,20,18,20,21,19,22,22,23,22,23,22,22,22,23,23,22,22,23,19,20,21,22,20,21,20,20,21,23,20,19,22,21],[28,28,28,28,29,28,28,29,28,27,27,27,28,27,27,27,28,28,27,28,28,27,28,28,27,28,29,27,28,28,27,28,29,29,27,28,28,28,29,28,29,28,28,28,28,27,26,24,25,25,24,23,24,22,22,23,21,20,20,19,16,14,9,7,5,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,5,5,5,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,7,8,8,7,7,7,7,7,7,7,6,7,7,6,6,7,7,6,7,7,7,6,7,7,6,7,7,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,5,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,6,5,5,5,6,5,5,6,6,6,6,6,6,6,5,5,6,5,5,6,6,5,5,6,6,5,6,6,7,7,7,6,7,7,7,7,7,7,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,5,5,6,6,5,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,6,6,6,6,5,5,4,4,4,5,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,3,3,2,3,3,2,2,3,3,3,3,5,5,5,6,7,7,8,10,11,8,9,14,11,9,14,14,13,13,16,16,16,18,20,20,21,19,22,20,17,20,19,19,19,19,21,19,21,22,24,25,26,24,25,25,26,26,26,27,27,27,27,27,27,27,27,27,26,27,27,27,27,26,26,24,26,26,24,26,24,25,26,23,23,24,21,22,21,19,19,17,16,14,13,12,9,8,7,4,3,2,2,1,2,2,2,3,3,3,3,3,3,4,4,4,5,5,5,5,6,5,6,5,7,6,7,6,6,5,5,5,5,5,6,5,6,7,6,5,5,4,5,4,4,3,4,4,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,6,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,4,4,4,5,5,6,6,6,6,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,6,6,7,6,6,6,6,6,5,5,5,5,4,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,3,2,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,2,2,3,3,3,2,2,3,3,3,3,4,4,4,4,4,5,4,4,4,4,4,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,7,8,8,9,11,10,10,11,13,13,15,15,16,19,18,18,17,18,17,18,21,20,20,22,21,23,23,24,23,23,23,25,24,23,25,23,24,24,21,23,24,24,22,23,21,23,23,25,21,19,23,22],[28,28,28,28,28,28,28,28,28,27,27,27,27,26,26,26,27,28,27,27,28,26,26,28,27,26,28,28,27,28,27,27,28,28,27,28,28,27,28,27,28,27,27,27,26,26,26,24,24,24,24,23,22,21,21,21,20,20,20,19,16,14,10,6,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,6,6,7,7,7,7,8,8,8,8,9,9,8,7,7,7,7,7,7,7,7,7,6,6,7,7,6,7,7,7,6,7,7,6,7,7,8,7,7,7,7,6,6,7,7,6,6,6,6,5,6,6,5,5,5,6,6,6,6,6,6,6,5,5,5,5,5,5,6,5,5,5,5,5,5,6,5,5,6,6,6,5,5,5,6,5,5,6,6,5,5,6,5,5,6,6,7,7,7,6,7,7,7,7,7,7,6,6,6,6,6,6,5,5,6,5,5,5,5,5,4,5,5,5,4,4,4,4,4,4,4,4,4,5,5,5,6,5,5,6,6,5,5,5,5,5,5,5,4,4,4,5,4,4,5,5,6,6,6,5,5,4,4,4,4,4,4,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,4,6,7,8,9,10,12,10,10,13,13,11,13,13,14,13,15,17,17,18,19,20,20,20,21,20,18,21,19,18,19,20,21,19,22,22,26,25,27,26,25,26,26,26,27,27,27,27,27,27,26,28,27,27,26,27,26,26,26,26,25,25,25,26,24,25,23,23,25,22,22,22,21,21,20,19,19,17,16,14,13,12,9,7,6,4,3,2,2,1,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,4,4,5,5,5,5,5,5,5,4,4,4,4,4,5,5,4,4,4,4,4,3,3,3,3,3,3,2,2,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,6,6,6,6,5,5,5,4,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,3,3,4,3,3,4,4,3,3,3,3,3,3,4,3,3,4,4,4,5,6,6,7,6,6,5,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,5,5,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,2,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,2,1,1,2,2,1,2,2,2,2,2,2,3,3,3,3,2,2,3,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,3,4,4,4,4,4,4,4,4,5,6,7,8,8,9,11,10,10,10,12,12,14,15,15,19,18,17,16,17,17,17,21,17,20,21,20,24,23,21,23,24,22,24,23,23,21,22,23,22,18,20,24,23,20,23,21,22,22,24,19,19,22,19],[28,29,28,29,29,29,29,29,29,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,27,29,28,28,29,27,28,29,29,28,29,29,28,29,28,29,28,28,28,28,27,26,26,27,25,25,25,24,23,22,22,20,20,19,18,16,14,10,8,7,5,4,4,4,3,4,3,4,4,4,4,4,4,5,4,4,5,5,4,5,5,5,6,6,6,6,7,6,7,7,7,7,7,8,8,7,8,8,8,8,9,8,9,8,10,10,8,7,8,7,8,8,8,8,8,8,7,7,8,8,7,7,8,7,8,8,7,7,8,8,9,8,8,8,8,7,7,7,7,7,6,7,7,6,7,7,6,6,6,7,6,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,4,5,5,4,5,6,6,7,6,6,6,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,6,7,7,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,3,4,4,3,3,4,4,3,3,4,4,3,4,4,4,4,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,6,7,9,10,13,15,15,13,14,15,14,13,16,16,17,16,18,19,20,20,20,21,22,21,22,19,18,21,19,20,19,21,22,20,20,24,25,24,28,25,26,27,27,27,28,27,28,28,28,28,27,28,27,28,27,28,27,27,27,26,27,24,26,26,25,26,25,25,26,23,23,25,22,23,23,20,20,20,17,15,14,14,11,9,7,4,3,2,2,3,2,2,2,2,2,3,3,3,3,4,3,3,3,4,4,4,5,5,4,4,5,5,5,5,5,5,5,4,4,4,4,4,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,6,5,6,6,7,6,6,5,5,5,5,5,4,4,4,4,5,4,4,4,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,6,7,7,7,7,6,5,5,5,5,6,5,5,6,6,7,7,7,7,7,7,7,7,6,6,6,6,6,5,5,5,5,4,5,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,4,3,4,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,6,6,5,6,5,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,5,4,4,4,4,4,4,3,3,3,3,3,2,3,3,2,2,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,2,3,3,3,2,2,2,2,2,2,1,2,1,1,1,0,1,1,2,2,2,2,2,2,2,3,3,3,4,4,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,8,9,9,10,11,10,11,11,12,13,15,17,16,19,19,18,16,19,18,17,21,19,22,22,21,25,25,24,23,24,24,25,25,23,24,23,24,23,22,22,25,23,21,24,23,23,24,26,21,21,24,22],[28,28,28,28,29,29,28,28,28,27,27,27,28,27,27,27,27,27,27,27,27,26,27,28,27,27,28,27,27,28,27,28,28,29,27,28,27,28,28,28,28,27,28,27,28,27,27,25,26,24,25,24,24,22,23,23,21,21,20,18,16,15,11,9,7,6,5,5,5,4,4,4,4,4,5,5,5,6,6,5,6,7,7,6,7,8,7,8,8,8,8,9,9,9,9,9,9,9,10,10,10,11,11,11,11,12,12,12,12,13,12,11,11,11,9,10,11,11,10,10,11,9,10,11,11,10,10,12,10,10,10,10,10,10,11,11,11,11,11,11,10,10,10,10,9,9,10,9,9,9,9,8,8,8,9,9,9,9,8,9,9,8,7,8,8,7,7,8,8,7,8,8,8,8,8,8,8,8,9,8,8,8,8,9,8,8,8,8,8,8,8,8,8,8,9,10,10,10,9,10,10,10,10,10,10,9,9,9,9,9,9,9,8,9,9,8,8,8,8,7,7,8,8,7,7,7,7,6,7,7,6,6,6,7,7,8,8,8,8,8,8,7,7,8,7,7,7,7,6,7,7,7,7,7,7,8,8,8,7,7,7,7,6,7,7,6,6,7,7,6,7,7,7,7,8,8,8,8,8,8,8,7,7,6,6,7,6,6,6,6,5,5,6,5,5,6,6,5,5,4,4,4,5,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,3,3,3,3,3,3,2,3,3,3,3,4,4,6,7,7,9,10,13,14,15,13,14,17,15,15,17,16,18,16,19,20,20,22,23,22,24,21,23,21,19,22,19,18,21,21,21,20,22,24,25,25,28,25,27,27,27,27,28,28,27,27,27,28,27,27,28,28,26,27,26,27,26,26,26,22,27,25,25,26,24,24,26,24,24,25,23,24,23,22,21,21,19,17,15,14,11,10,7,5,4,3,2,2,2,2,2,2,2,3,3,3,3,4,3,3,4,4,4,4,5,5,5,5,6,6,6,6,5,6,5,5,4,4,5,5,6,6,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,5,5,5,5,5,6,6,7,7,8,8,8,8,8,7,7,7,6,6,6,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,6,6,5,5,6,6,5,6,6,6,5,5,6,7,8,8,8,8,8,8,7,8,7,8,8,7,8,9,8,10,10,10,9,10,9,9,9,8,8,9,8,8,8,7,7,7,6,6,7,6,6,6,6,5,5,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,4,5,5,4,5,5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,6,6,7,6,7,7,8,8,7,8,7,8,8,9,8,9,9,10,8,10,9,9,9,9,9,9,9,8,8,7,7,6,5,5,5,5,5,5,4,4,5,4,4,4,4,4,3,4,4,3,4,4,4,3,3,3,4,4,4,4,4,4,4,4,5,5,5,4,4,5,5,4,4,4,4,3,4,3,3,3,2,3,3,3,2,3,3,2,2,3,3,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,1,1,0,1,2,2,2,2,3,3,3,3,4,4,5,6,5,6,5,6,6,4,5,5,4,4,5,5,5,5,5,5,5,6,5,5,6,7,6,6,7,7,8,9,10,10,11,11,11,11,12,13,14,15,16,16,20,19,19,17,18,18,18,21,19,21,22,21,23,23,23,23,23,23,24,25,24,23,22,24,23,20,21,23,23,21,23,22,21,22,23,21,20,22,21],[29,29,29,29,29,29,29,29,29,29,29,28,29,28,28,28,29,29,28,29,28,28,29,29,28,28,29,28,29,29,28,29,29,29,28,29,29,29,29,28,29,28,28,29,28,27,27,26,27,26,24,25,26,23,23,23,22,21,21,19,17,14,12,10,8,7,6,7,6,6,6,5,6,6,7,7,8,8,8,8,7,8,9,8,8,10,9,11,10,10,11,11,11,11,12,11,10,11,13,12,12,13,14,12,13,14,15,14,13,15,14,14,12,12,12,13,12,13,12,13,13,11,11,13,13,11,12,13,11,11,12,12,10,12,12,13,12,12,12,12,12,11,12,12,10,11,12,11,9,11,11,9,10,10,10,11,11,12,11,12,11,10,10,11,9,9,10,10,9,9,9,10,9,10,10,10,9,10,10,10,10,9,10,10,10,9,10,10,9,9,10,9,9,10,10,12,12,12,11,12,12,12,12,12,12,11,12,11,11,11,12,11,9,11,10,9,10,10,9,8,9,9,8,8,8,9,8,7,8,8,7,7,8,8,9,9,9,9,10,10,9,9,9,9,8,8,8,8,8,8,8,7,8,8,8,9,10,10,9,8,8,7,8,7,8,7,8,8,8,7,8,8,8,7,8,9,9,9,8,9,9,8,7,7,7,7,7,7,7,7,8,6,7,7,7,7,7,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,6,5,5,5,5,4,5,4,4,4,4,4,5,5,4,4,5,5,4,5,5,7,9,11,11,12,15,16,16,15,16,16,17,15,18,18,18,18,20,22,22,21,23,23,24,22,24,21,19,22,21,21,20,21,22,21,21,25,25,26,27,27,26,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,27,27,26,27,25,27,27,25,26,25,26,27,25,25,25,24,25,24,23,23,21,20,18,17,15,14,11,9,6,5,4,3,3,2,3,2,3,2,4,4,3,3,4,4,4,4,5,5,5,6,6,5,6,7,8,7,6,7,6,6,6,6,5,6,5,7,7,5,5,6,4,4,4,4,4,4,4,3,3,3,3,2,3,2,3,3,4,4,4,5,5,4,5,5,6,5,6,6,6,7,8,7,8,9,9,8,8,7,8,8,8,7,7,7,7,8,7,7,7,8,7,7,8,7,7,7,7,6,7,7,7,6,7,7,6,6,7,7,7,7,7,7,7,8,8,10,10,10,10,9,8,9,8,9,10,9,9,11,11,12,12,12,11,12,12,12,11,11,11,11,10,9,9,9,8,8,7,8,7,7,7,7,6,7,6,7,6,6,6,6,6,6,5,6,5,5,5,6,4,5,5,5,5,5,6,5,5,6,6,5,6,6,6,7,6,6,6,6,6,6,6,6,5,5,6,6,5,6,6,6,6,6,7,6,7,7,8,8,8,9,10,10,10,9,10,9,10,11,11,10,12,12,12,11,12,11,11,11,12,11,10,11,11,9,9,9,7,7,6,6,6,6,6,5,6,6,5,5,5,5,5,4,5,5,4,4,5,4,3,3,4,4,5,4,4,4,5,5,5,5,6,5,5,5,5,5,5,4,5,4,4,4,5,5,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,4,5,4,4,4,3,3,3,3,2,2,2,2,2,1,1,0,1,2,2,3,3,3,4,4,4,5,5,6,5,6,6,7,6,6,6,6,5,5,6,6,5,6,6,6,6,6,7,7,7,7,8,7,8,8,9,10,10,11,11,13,12,13,13,14,14,16,18,18,21,21,20,18,20,19,18,23,19,21,23,20,24,24,24,24,24,23,25,25,23,24,24,24,23,21,22,24,24,21,24,22,23,25,25,22,21,24,20],[29,29,29,29,29,29,29,29,29,28,27,27,28,27,28,27,28,26,27,28,26,27,27,27,26,27,28,27,28,28,26,28,28,29,27,28,27,28,28,28,29,28,28,28,28,28,27,26,27,26,25,25,24,24,23,23,21,22,20,18,16,14,12,11,10,9,9,9,8,8,7,7,7,7,9,9,10,10,11,11,10,11,11,10,11,13,13,13,14,14,15,15,16,15,14,15,16,16,16,17,17,17,18,18,17,18,18,18,19,17,18,17,16,17,16,17,16,16,14,16,16,15,16,16,17,16,16,17,16,15,15,17,16,15,15,15,16,17,16,17,17,16,16,17,17,17,16,17,14,15,16,13,14,12,14,15,15,15,15,14,13,13,13,13,13,12,13,14,13,11,13,14,13,12,15,15,12,13,14,14,14,12,12,14,14,12,13,14,13,13,14,15,13,13,14,14,16,16,15,15,15,16,15,15,16,14,15,15,15,14,15,15,14,15,14,14,14,15,14,11,12,15,12,10,12,12,11,10,12,12,9,10,10,11,11,12,12,12,12,13,13,12,11,13,11,11,11,11,10,10,11,10,9,10,11,11,12,12,11,11,10,11,10,10,11,10,9,10,12,10,11,13,12,10,11,12,12,14,13,15,12,12,11,10,11,11,10,9,10,10,8,9,10,8,8,9,9,8,7,7,6,7,7,6,5,6,6,5,6,6,6,5,6,6,6,6,5,6,6,5,4,5,5,5,5,6,5,5,5,6,6,6,6,8,9,12,12,13,15,17,16,15,16,17,16,16,18,18,17,17,20,21,19,21,23,22,24,21,24,21,21,22,20,19,20,21,21,20,22,23,24,24,26,25,26,26,26,27,27,28,27,28,28,28,27,27,27,28,26,27,26,27,26,26,27,24,26,27,26,27,25,26,27,24,25,25,24,24,24,24,22,22,21,20,17,17,14,12,10,7,6,4,4,3,3,5,2,3,4,4,4,3,3,5,4,4,5,6,5,5,6,7,6,6,7,9,9,8,7,8,8,7,7,6,7,7,8,8,6,5,7,4,4,5,5,4,4,5,3,3,4,4,3,3,4,4,4,5,5,5,5,6,6,6,6,7,7,8,8,8,9,10,10,11,11,12,11,10,9,9,9,9,9,8,8,8,9,9,9,8,9,10,9,10,9,9,9,9,9,9,8,10,9,9,8,9,10,8,9,10,9,10,9,10,10,11,12,11,11,11,11,11,12,11,12,14,12,12,14,14,15,15,15,15,15,15,15,15,15,14,14,15,14,13,11,12,12,11,11,11,10,10,10,10,9,9,9,8,7,7,8,7,6,7,7,6,5,7,7,5,6,6,6,6,7,7,6,7,7,7,7,7,7,8,7,8,8,8,7,7,8,8,8,7,8,9,8,8,9,9,8,9,10,9,9,10,11,11,11,11,13,12,14,14,12,14,13,13,15,15,15,15,14,15,14,14,16,15,15,14,13,14,13,12,12,11,11,9,9,10,10,8,9,9,8,7,8,7,6,6,7,5,5,6,6,5,5,6,5,4,4,5,6,6,5,6,6,7,6,6,7,8,7,7,6,8,8,6,6,8,7,6,8,7,7,6,5,6,6,5,4,4,5,5,3,4,5,4,4,5,4,4,5,6,6,5,7,6,5,6,7,6,5,6,5,4,5,5,3,3,4,4,3,2,2,1,0,1,2,3,3,3,4,4,6,6,7,8,7,8,7,9,8,7,7,8,7,7,8,8,7,7,8,8,8,8,8,8,8,10,9,9,10,10,12,13,12,13,14,15,15,15,15,17,17,19,18,19,21,23,21,19,22,21,21,24,21,23,23,23,26,25,24,25,25,24,24,26,24,24,23,26,25,24,23,24,24,23,24,22,22,22,24,21,20,23,21],[30,29,29,29,29,29,29,29,28,28,27,27,28,27,28,27,28,27,28,28,27,27,28,27,27,28,28,28,28,28,26,28,28,29,28,29,28,28,29,29,29,28,28,28,28,28,27,26,26,26,25,25,25,24,23,22,22,21,19,20,18,16,14,13,12,12,12,11,11,11,11,12,12,12,12,14,13,15,14,15,14,15,14,14,16,16,16,17,17,17,17,17,18,20,17,17,19,18,19,19,20,18,19,19,20,21,19,20,20,19,19,19,19,21,20,20,19,19,18,19,20,18,19,18,20,19,18,20,19,18,17,19,17,17,17,17,18,19,18,18,19,19,18,19,19,19,19,19,18,18,18,18,18,17,17,18,17,17,18,16,17,16,15,17,17,16,17,17,16,16,17,17,16,18,17,17,17,17,17,17,17,17,18,16,17,16,16,17,16,17,16,16,15,17,17,16,17,18,16,17,17,17,17,17,17,16,17,17,17,17,17,18,16,19,16,16,18,17,17,15,16,17,16,16,16,16,14,14,16,16,13,15,13,15,13,15,15,15,15,15,17,15,16,16,16,15,14,16,14,15,14,14,13,15,15,14,15,15,15,14,14,14,13,14,15,14,12,15,15,13,14,15,15,13,14,14,15,16,15,16,15,15,14,14,14,14,13,14,14,13,12,13,14,11,12,14,13,11,13,11,10,9,11,10,9,9,10,8,8,9,9,8,8,9,9,8,7,6,7,6,6,6,8,7,9,8,6,8,8,8,8,9,10,10,12,13,13,14,15,17,17,16,15,17,17,16,17,18,17,16,20,21,20,20,23,23,23,21,23,21,19,21,19,19,20,21,21,19,21,23,22,22,26,25,26,25,26,26,27,27,27,27,27,27,27,27,27,27,26,27,26,27,26,25,26,25,26,26,25,27,25,26,27,24,26,25,24,25,23,24,22,21,21,18,17,16,15,14,9,8,6,5,6,5,4,3,3,3,5,5,6,6,4,6,5,5,5,6,7,6,6,6,6,8,10,10,10,8,9,8,9,8,7,7,8,7,10,11,6,7,8,7,6,6,6,6,5,5,5,5,5,4,4,5,5,6,7,8,8,7,9,9,8,8,9,9,9,9,10,10,9,14,12,14,14,15,14,13,13,12,13,13,13,13,13,12,13,13,12,13,14,14,12,12,13,13,12,12,12,13,11,12,12,11,10,12,13,11,11,13,12,10,12,12,12,13,13,13,13,14,13,14,15,15,15,15,15,16,16,16,16,16,17,16,17,18,16,17,16,15,16,16,15,16,15,15,15,14,14,14,13,13,14,13,12,13,12,12,11,11,11,10,11,10,10,9,10,10,10,9,10,10,9,9,9,11,10,9,10,11,10,9,10,9,10,10,11,11,10,8,9,10,10,8,10,10,9,10,10,11,10,12,12,12,12,12,14,13,14,14,15,15,16,16,16,16,17,17,17,18,16,17,16,17,15,16,17,18,16,16,15,15,15,14,14,14,13,13,12,13,12,12,12,12,11,11,10,10,10,11,9,8,10,10,8,8,10,9,7,6,7,6,5,7,7,6,7,8,7,7,8,9,8,7,7,8,9,7,7,9,9,7,9,9,10,9,8,9,10,8,6,8,7,7,5,6,6,5,5,6,5,4,5,6,6,6,7,7,6,6,8,7,8,7,6,6,7,6,5,5,6,6,5,4,3,3,1,0,1,2,3,4,4,4,5,5,7,7,6,8,7,9,8,7,9,8,7,8,9,8,8,8,9,9,9,10,10,11,11,12,13,12,12,13,14,15,14,14,16,15,16,16,16,17,19,19,21,19,22,24,21,20,22,22,21,24,22,23,24,22,25,25,25,25,26,25,25,26,24,24,25,25,24,22,24,25,24,23,24,22,23,24,25,22,22,24,23],[29,29,29,29,29,29,29,29,29,29,28,28,29,27,28,27,29,28,27,29,28,27,29,28,27,29,28,27,29,29,28,29,29,29,29,29,28,29,29,28,29,29,28,29,29,28,28,26,27,27,25,25,26,24,23,24,23,22,22,21,20,17,15,14,14,11,12,13,12,13,12,10,12,12,12,14,14,14,15,14,15,14,16,16,14,16,16,17,18,17,19,20,18,19,19,18,18,19,21,19,21,21,21,20,21,21,21,21,22,20,21,21,19,19,20,21,20,21,20,20,20,19,19,20,19,18,19,21,18,18,19,20,17,18,19,18,19,19,19,19,19,18,20,19,18,19,19,18,17,18,19,16,17,17,17,19,19,18,19,18,18,17,18,18,17,15,18,19,16,17,18,18,16,18,19,17,15,18,18,18,17,16,17,17,16,16,17,18,15,16,17,16,16,18,17,17,18,17,16,18,17,17,17,18,19,17,18,17,17,17,18,18,16,18,18,15,17,18,16,15,15,17,15,14,15,15,14,14,15,16,14,14,15,14,16,16,16,16,16,17,16,16,16,16,15,15,16,15,14,15,16,13,13,16,15,14,15,15,15,15,13,14,14,13,15,13,14,15,15,14,15,16,15,15,16,16,16,16,15,16,16,14,14,15,15,14,14,14,14,13,13,13,13,13,12,13,12,12,12,12,9,10,10,10,10,10,10,9,9,10,10,9,10,10,9,9,8,9,8,8,7,9,8,9,8,9,9,9,9,9,10,10,9,11,12,13,13,14,15,16,17,17,17,19,20,16,18,20,20,18,21,22,22,22,23,23,24,22,25,23,21,22,20,20,22,22,22,21,22,23,24,25,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,26,27,27,27,26,26,26,26,27,27,26,27,26,25,27,25,26,26,25,25,25,24,24,23,22,21,19,17,16,15,12,11,10,8,8,7,6,5,5,4,6,7,6,5,5,7,7,6,6,8,8,7,9,9,8,9,11,12,12,9,11,9,9,10,8,8,9,7,11,11,8,8,9,7,6,7,6,5,5,6,5,5,6,6,6,6,5,7,7,9,8,7,9,9,9,9,9,9,10,10,11,11,11,12,12,13,13,14,14,13,13,12,14,13,13,13,13,12,13,14,13,12,14,14,14,13,14,12,12,12,12,11,12,12,12,12,12,12,12,12,12,13,12,12,12,12,13,13,13,15,14,15,14,14,14,15,15,16,15,16,17,17,18,19,17,17,17,17,17,17,17,16,17,18,16,16,16,15,16,14,15,15,14,14,13,13,13,13,12,12,10,11,11,10,9,11,10,9,9,11,10,8,9,10,11,10,10,10,10,9,10,9,9,9,10,9,10,11,11,9,9,8,9,10,9,9,9,12,9,9,11,10,11,12,11,12,13,13,14,15,14,14,17,17,18,17,16,17,16,18,18,19,18,19,18,18,17,18,16,17,17,18,15,15,16,15,15,14,14,13,13,14,13,12,13,12,11,12,12,9,9,9,8,7,8,7,8,7,7,8,6,6,6,6,7,7,8,7,7,8,6,6,8,9,7,7,6,7,7,6,6,8,7,7,9,9,9,9,9,8,7,8,7,6,6,6,5,5,5,5,5,5,4,4,5,5,5,5,5,5,4,5,6,5,6,6,5,6,6,6,5,7,6,5,6,6,5,5,2,1,0,1,2,3,3,4,5,5,6,7,7,8,7,9,9,8,9,10,10,8,9,9,8,9,10,10,10,11,10,12,12,13,13,12,13,14,14,14,14,14,15,16,16,16,18,17,19,20,20,20,23,23,22,21,23,23,22,25,23,25,25,23,27,26,25,27,27,26,26,28,26,25,26,26,25,23,24,27,26,24,26,23,23,25,26,23,22,25,23],[29,28,28,28,28,28,29,28,28,28,27,26,28,26,27,26,28,27,27,27,26,26,27,26,26,27,27,26,27,28,26,28,28,28,27,28,27,28,28,27,28,28,27,27,27,27,27,25,25,25,24,24,24,23,23,22,21,21,20,19,17,16,14,12,12,11,11,10,11,10,11,9,11,11,12,13,13,13,13,13,15,14,14,14,14,14,15,15,14,16,16,15,16,17,17,17,17,17,19,18,20,18,19,19,19,18,20,20,19,19,20,19,17,19,18,19,18,19,18,18,18,18,18,18,18,19,16,19,18,18,17,19,17,16,17,16,18,17,16,17,18,18,18,18,18,18,18,18,16,16,17,17,16,16,15,18,17,17,18,16,17,16,15,15,16,16,15,16,16,17,16,16,15,17,16,17,15,16,16,15,15,16,14,15,15,15,15,15,15,16,15,15,15,16,16,17,16,17,16,17,16,17,17,17,17,17,17,16,16,16,16,17,15,16,16,15,17,16,16,15,14,16,15,14,15,15,14,14,14,14,13,14,13,14,14,14,15,14,15,14,16,15,15,15,16,15,14,15,13,15,14,13,14,15,14,13,14,14,14,14,13,13,13,13,13,13,12,13,14,13,13,14,14,14,14,15,14,14,15,14,14,13,13,13,13,13,13,13,13,12,12,11,12,11,12,12,12,11,12,12,9,10,10,10,8,9,9,7,8,9,9,7,8,9,7,7,7,7,8,7,6,8,8,6,8,9,8,7,9,8,8,9,8,8,11,11,10,12,14,14,16,14,14,16,16,15,16,17,18,16,19,21,20,20,22,23,24,22,24,21,21,21,20,19,19,21,21,20,20,23,21,22,25,23,25,25,26,25,26,27,26,27,27,27,26,27,27,26,25,27,25,26,27,25,26,23,26,26,24,26,24,25,27,23,25,25,23,23,23,23,22,21,20,18,17,15,14,13,11,9,8,7,7,5,6,5,5,4,5,5,5,4,5,6,5,5,6,6,6,6,8,8,7,8,9,9,10,9,9,8,8,8,6,7,9,7,12,11,7,8,9,8,6,7,7,5,6,6,6,4,5,6,5,5,5,6,6,7,6,6,7,8,7,8,9,9,9,9,9,10,11,11,12,13,12,13,13,13,12,12,12,12,12,11,12,10,12,12,12,11,12,13,12,11,12,11,11,11,11,11,11,11,11,11,10,11,12,11,10,11,11,10,10,11,11,13,12,13,13,14,13,13,13,13,14,14,15,14,16,15,16,16,16,15,15,16,16,15,15,15,15,16,15,14,15,15,14,13,13,13,12,12,13,13,11,11,11,11,10,10,10,10,9,10,10,8,8,10,10,7,8,8,9,8,9,10,9,8,10,10,9,9,10,9,9,11,10,9,9,8,8,9,8,7,9,10,8,8,10,9,8,10,10,11,11,12,12,13,13,13,14,15,15,15,16,15,15,15,16,16,15,16,15,16,15,15,16,15,16,16,14,14,15,15,14,13,13,12,12,12,11,11,11,10,10,10,10,9,8,9,9,7,7,8,7,6,7,7,6,5,5,6,6,7,7,6,6,7,7,6,7,8,7,7,6,6,6,6,5,7,6,6,8,8,9,8,7,7,7,6,6,6,6,4,4,4,4,3,4,4,3,3,5,5,5,4,6,5,4,5,6,5,6,5,5,4,5,6,4,5,6,5,5,4,4,3,3,2,1,0,1,3,3,4,4,5,7,7,7,9,8,8,9,8,9,9,9,8,9,9,8,8,9,10,9,10,10,10,11,12,12,11,11,13,13,13,15,14,16,15,17,16,16,17,18,20,20,19,22,22,22,21,22,22,22,25,23,25,25,22,26,24,25,25,25,25,26,26,25,25,24,25,23,23,23,25,25,22,24,22,21,23,24,21,22,24,22],[29,29,29,29,29,29,29,29,29,28,29,28,29,27,28,27,28,28,27,28,27,27,28,28,27,27,29,27,28,28,27,29,29,29,28,29,29,29,29,29,29,28,28,29,28,28,27,26,26,25,25,24,24,24,22,23,21,20,20,19,17,14,11,9,8,7,7,7,6,7,6,6,7,7,8,9,9,11,12,11,9,12,12,10,11,13,13,13,14,13,14,15,14,14,16,16,15,15,18,17,17,17,17,17,18,18,18,18,18,17,18,17,17,17,16,17,17,18,16,17,19,15,16,18,17,16,16,17,16,16,16,17,14,15,16,16,16,17,17,17,16,16,17,18,15,16,17,16,14,15,16,13,13,14,16,14,16,15,14,15,14,14,15,15,14,13,15,17,14,14,15,16,14,14,16,14,13,14,15,15,15,13,13,15,14,14,14,15,13,14,15,13,13,15,15,16,17,15,14,16,15,15,15,16,15,15,15,14,14,13,16,15,13,16,15,13,14,15,13,13,12,14,13,11,12,13,11,10,12,13,10,10,11,12,12,14,13,14,13,14,14,13,15,15,13,13,15,12,11,13,12,11,10,13,13,12,13,14,13,12,11,12,10,11,12,11,10,11,12,11,11,12,11,11,11,13,14,13,12,12,12,13,11,11,10,11,10,10,11,10,9,8,10,10,9,10,10,9,8,8,6,7,8,7,7,7,8,7,7,7,7,7,7,8,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,6,7,7,8,10,9,12,14,13,12,12,14,14,14,14,15,15,16,16,19,19,19,20,21,22,20,21,20,20,20,18,18,21,19,21,20,21,22,23,24,26,23,25,24,26,26,27,27,26,27,27,27,27,27,27,26,26,27,25,27,26,26,25,24,25,25,25,26,24,24,26,23,24,24,23,23,23,21,22,20,20,17,17,14,14,13,9,7,6,4,5,4,4,3,3,4,4,5,4,4,5,5,4,4,5,6,5,5,7,6,6,7,7,8,7,8,8,8,8,7,6,7,8,7,7,8,7,7,7,6,5,6,6,4,5,6,5,4,5,6,4,5,5,5,5,6,7,6,6,6,6,6,7,7,7,8,8,8,8,10,11,12,11,11,12,12,9,11,9,10,12,10,10,10,9,11,9,9,10,11,9,9,11,9,9,8,9,8,9,8,9,8,7,7,8,8,7,9,8,8,8,7,8,9,11,10,11,11,11,11,12,11,12,13,11,13,13,15,14,14,14,14,15,15,14,14,13,13,14,13,13,12,12,11,12,9,10,10,8,8,9,9,8,7,8,8,7,7,8,7,6,7,8,7,6,6,7,7,6,7,7,7,7,7,7,6,7,7,8,6,7,6,6,6,7,6,6,5,5,6,6,7,5,6,5,5,6,6,5,6,7,7,7,7,8,8,10,10,13,12,14,14,13,13,14,14,14,14,14,14,14,14,14,13,14,14,13,14,13,13,12,12,11,10,10,9,8,8,8,7,8,8,6,6,7,5,5,5,5,6,6,6,6,4,5,5,4,3,3,4,4,5,5,4,5,5,6,4,5,5,4,5,4,4,5,5,4,5,5,5,4,4,5,4,5,5,5,4,4,5,4,3,3,4,3,2,3,3,2,2,3,3,3,3,4,3,2,3,4,3,3,3,3,2,3,3,2,2,3,3,2,3,2,2,3,2,1,1,0,1,2,2,3,4,5,5,5,6,6,8,6,5,7,7,6,6,7,7,8,7,8,7,8,8,8,7,8,10,9,8,9,11,13,14,13,14,12,16,14,13,16,17,16,18,20,20,22,22,21,20,23,21,21,24,21,23,26,22,25,24,25,24,24,25,27,25,25,25,25,25,24,22,23,26,25,21,24,22,22,25,24,21,22,24,22],[28,29,28,28,29,29,28,28,28,28,27,26,28,27,27,26,28,27,26,27,26,26,27,27,26,27,27,27,28,28,27,28,29,29,28,29,28,28,29,28,29,28,28,29,29,28,27,27,26,26,25,25,23,22,23,22,21,21,20,18,16,15,11,10,8,8,8,8,8,8,8,7,8,7,8,9,10,11,12,10,10,11,12,10,11,12,12,13,13,13,13,14,14,14,15,16,14,14,17,17,15,17,18,18,16,18,18,18,18,17,18,18,17,15,16,17,16,18,16,17,17,14,15,17,17,17,15,18,17,15,16,16,15,14,16,15,17,16,17,17,14,16,16,17,15,14,16,16,13,15,16,13,13,13,14,14,15,15,14,15,14,14,14,14,14,12,13,13,13,12,14,14,13,13,16,14,12,14,15,14,14,12,13,15,14,13,14,15,13,13,15,13,13,14,14,14,16,15,15,14,15,14,14,15,14,14,14,14,14,14,15,15,12,14,14,14,12,14,14,12,11,14,13,11,12,12,11,10,11,12,10,10,12,12,13,13,13,13,14,15,13,13,14,14,12,12,13,13,10,12,12,11,10,11,12,12,13,13,12,11,11,12,10,10,12,10,9,10,12,9,10,12,12,10,11,12,12,13,12,13,12,11,11,9,10,11,8,9,10,9,7,8,10,8,7,10,9,8,8,8,7,7,8,8,7,7,8,6,7,8,7,6,7,8,7,7,6,7,7,7,6,6,7,6,7,7,7,6,7,7,8,7,8,8,10,10,10,13,12,13,15,11,13,15,14,13,15,17,16,15,17,19,17,19,21,21,23,20,22,22,21,22,19,18,20,21,20,19,21,23,22,22,25,23,25,25,26,26,27,27,27,27,27,27,27,28,27,27,26,26,26,26,26,24,26,25,25,26,24,26,24,25,26,24,24,25,23,23,23,23,21,22,20,18,17,16,14,13,10,7,6,4,5,4,5,4,4,4,4,5,5,5,5,5,5,6,6,6,7,6,8,8,7,8,9,10,9,9,9,9,8,8,7,7,8,8,8,9,8,8,8,7,6,7,6,6,6,6,6,5,6,6,5,5,5,6,5,7,6,5,6,7,6,6,7,7,8,8,9,8,9,10,10,11,11,10,12,11,9,11,10,11,10,9,10,8,9,10,9,9,9,10,8,9,9,9,8,8,9,8,8,9,9,8,7,8,9,7,9,10,8,8,8,9,9,10,11,11,11,12,11,11,11,11,12,13,11,12,13,13,15,15,14,13,14,14,15,13,13,12,13,12,13,12,12,12,12,9,9,10,9,8,9,9,8,7,9,8,7,8,7,7,6,7,7,6,6,7,7,6,6,7,7,7,7,7,6,6,7,7,6,6,7,6,7,7,8,6,7,7,7,7,6,6,7,7,7,7,8,7,7,7,8,8,7,8,9,10,9,10,13,11,13,13,12,13,12,14,14,14,14,14,14,14,13,14,13,14,14,15,12,12,13,13,12,11,11,9,9,9,8,8,8,8,7,7,7,6,6,6,5,5,5,5,6,5,5,5,5,4,4,5,5,5,6,4,5,6,5,5,6,6,6,6,6,7,6,5,5,5,7,5,6,6,6,6,7,6,5,5,4,6,5,3,3,4,3,2,3,4,2,3,4,4,3,3,4,4,3,3,4,4,3,4,4,3,3,4,3,3,4,4,3,3,3,4,3,3,2,1,1,0,1,2,3,4,4,6,5,6,6,7,7,7,7,7,6,5,7,7,6,6,8,7,7,8,8,8,8,9,9,9,9,10,11,12,12,13,13,15,15,14,15,17,16,18,18,19,21,20,21,19,21,21,20,23,20,23,24,22,25,25,24,23,24,23,25,26,24,24,23,25,24,23,22,24,24,21,24,21,22,22,24,21,20,23,22],[29,29,28,28,28,28,29,28,28,28,27,27,27,26,27,25,27,26,26,27,25,25,27,26,25,27,27,26,28,27,26,28,28,28,27,28,27,28,28,28,28,28,28,28,28,27,27,26,26,27,26,25,25,24,23,23,21,22,20,18,17,14,12,12,11,10,9,9,9,10,9,10,10,11,11,11,11,13,13,12,12,14,13,12,14,15,15,15,16,17,17,17,18,18,17,18,17,18,19,19,20,20,20,18,19,20,20,19,20,20,19,19,18,20,20,19,19,19,19,19,19,18,19,19,18,20,17,19,19,18,17,19,18,19,16,18,18,19,19,18,19,18,18,19,19,18,19,18,17,18,18,17,17,17,17,18,17,17,17,17,16,16,17,16,17,14,16,18,16,16,16,16,17,16,17,17,16,17,16,16,18,17,16,16,17,17,16,17,16,16,15,17,16,16,16,16,17,17,15,16,16,17,15,17,17,16,15,16,16,17,17,16,15,18,17,16,17,17,17,15,15,17,16,13,15,15,14,13,14,14,12,13,13,14,14,15,15,15,16,16,16,15,15,16,14,15,15,14,12,15,15,14,13,14,14,15,15,14,14,13,14,14,13,14,14,13,11,13,14,13,14,13,14,13,13,14,14,15,15,15,15,15,13,12,13,14,12,12,13,12,11,11,13,12,11,12,12,11,11,11,9,9,10,11,9,9,10,10,9,9,10,10,10,10,11,10,9,9,8,8,8,8,8,8,9,8,8,8,8,7,8,8,9,8,10,11,11,12,13,16,16,14,13,16,16,13,15,17,16,15,18,20,17,19,22,21,23,20,23,21,20,21,20,17,19,20,21,18,21,23,20,22,24,24,26,25,25,26,27,27,27,27,27,27,26,27,26,26,25,26,26,27,26,25,26,23,26,26,25,26,25,26,27,23,24,25,24,23,24,23,22,21,20,18,17,16,14,13,11,8,7,5,6,6,6,5,6,6,7,8,7,7,7,8,6,7,8,8,8,8,10,9,8,9,11,10,11,11,11,11,10,10,10,10,10,10,11,11,8,9,10,8,8,9,8,7,7,8,6,7,7,7,6,7,7,9,9,10,9,9,9,10,10,9,10,12,11,12,11,13,13,13,13,13,13,13,13,13,13,12,13,12,14,12,12,11,12,13,11,11,12,13,12,12,12,12,11,11,11,10,10,11,11,11,10,10,11,11,11,11,11,11,11,11,11,12,13,12,12,13,13,13,13,15,13,15,14,14,16,16,17,16,16,16,16,16,16,16,16,15,16,15,15,14,15,15,14,12,13,13,12,12,12,12,10,11,10,11,10,10,10,10,9,10,10,9,9,10,10,9,10,9,11,10,11,10,10,9,10,10,9,8,10,9,8,10,10,10,10,8,9,9,9,8,9,9,8,9,9,10,9,9,11,11,10,11,11,11,13,12,14,14,15,16,14,15,16,16,16,17,16,16,16,17,16,16,16,15,16,16,15,15,14,14,12,12,12,11,11,11,11,10,11,10,9,9,10,8,8,8,9,7,8,9,7,6,8,8,6,5,6,6,7,6,6,6,7,7,7,7,8,9,8,7,7,9,8,7,7,7,8,6,7,9,7,8,6,7,7,6,5,6,6,4,5,5,4,3,3,5,4,3,4,5,4,5,6,7,5,6,6,6,5,6,5,4,4,5,5,4,4,5,4,4,4,5,4,4,4,3,3,1,0,1,2,3,5,5,6,6,7,9,7,6,8,8,8,9,9,9,9,10,10,9,11,11,11,12,11,12,11,11,12,12,13,13,13,14,14,15,16,15,17,18,18,20,19,19,21,22,22,20,22,21,20,25,22,24,24,22,26,24,25,25,25,24,26,27,24,25,26,25,23,22,24,24,24,21,23,22,22,23,24,21,21,23,22],[29,28,28,28,28,28,29,28,28,28,27,27,27,26,27,26,27,26,26,27,26,26,27,27,26,27,27,26,27,28,26,28,28,28,28,29,27,28,28,28,29,28,28,28,28,28,27,26,26,26,24,25,24,24,23,22,22,21,20,19,19,16,15,14,15,12,14,14,13,14,14,15,14,15,14,16,16,16,18,17,16,17,18,16,16,19,18,20,19,19,20,20,21,21,20,20,20,21,21,22,21,22,22,22,22,22,22,22,23,21,22,21,21,22,22,22,22,21,22,22,22,21,21,21,22,22,21,22,22,20,21,21,19,19,20,20,21,20,20,20,22,20,21,22,21,21,22,21,19,21,21,20,20,20,20,21,21,20,21,19,19,19,21,20,20,18,20,20,20,20,19,20,19,20,20,20,18,19,20,20,20,18,20,20,20,18,18,19,18,18,18,19,17,19,18,19,20,20,18,19,19,19,19,18,18,18,19,19,18,19,20,20,18,20,20,18,19,20,19,17,18,20,18,17,18,19,17,16,18,17,15,17,17,17,18,18,18,18,18,19,19,18,19,19,17,19,19,18,15,18,18,16,16,17,16,16,17,17,16,16,16,17,15,16,17,16,15,17,16,15,16,16,16,15,17,17,18,18,16,18,17,17,15,16,16,16,14,15,17,15,13,15,16,15,14,16,16,15,15,14,16,14,14,15,15,14,13,15,14,14,15,15,14,14,13,13,13,12,12,13,11,13,11,11,13,11,13,11,10,11,12,11,12,10,12,12,12,13,15,15,16,15,15,17,16,15,15,17,16,16,19,20,20,20,22,22,23,21,23,21,20,20,19,18,19,19,21,18,19,21,21,21,24,23,24,25,25,26,27,27,27,27,27,27,27,27,27,27,26,27,26,27,27,26,27,26,26,27,25,27,26,25,27,25,26,26,25,25,25,24,24,23,22,19,18,17,15,15,12,10,10,8,9,9,9,9,8,9,10,9,9,9,8,10,8,8,9,10,9,10,11,11,9,11,12,11,12,11,14,12,11,13,12,13,13,12,13,13,9,10,12,9,8,12,10,9,9,11,8,9,10,10,9,10,10,10,11,13,11,11,13,14,11,12,13,14,12,14,15,14,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,15,16,17,15,16,16,17,14,15,16,14,14,14,13,14,14,13,13,13,14,12,14,15,13,15,14,14,14,14,14,14,14,14,15,15,16,16,16,15,17,18,16,18,18,18,19,19,19,19,19,19,20,20,18,18,19,19,19,17,18,17,16,16,16,16,14,15,16,14,14,13,14,13,14,13,12,14,15,13,12,11,14,13,14,12,14,12,14,13,12,13,12,11,13,13,11,10,12,11,12,11,12,10,11,8,11,12,12,11,10,14,12,12,12,13,14,14,14,15,14,14,15,15,16,16,19,18,20,20,19,19,20,20,20,21,20,20,19,20,18,19,19,18,19,19,18,17,17,18,16,16,15,15,14,15,14,14,13,13,13,14,12,13,13,12,11,10,11,10,9,10,9,8,8,8,8,7,7,8,9,7,6,8,8,6,7,10,9,9,9,10,9,10,8,11,11,8,11,13,12,12,12,12,11,10,10,10,12,7,8,7,6,6,6,6,4,3,4,6,4,4,8,7,4,7,9,8,6,8,6,5,6,8,7,5,7,9,7,9,6,7,7,6,5,4,5,2,2,0,1,3,4,5,5,6,7,7,8,8,8,8,9,8,10,9,9,10,13,11,12,14,15,16,14,15,16,15,15,16,16,16,16,15,17,16,16,17,18,18,18,20,20,20,22,22,22,20,21,23,22,25,22,25,25,22,26,25,25,24,26,25,26,27,25,24,25,26,23,21,22,26,25,22,25,22,22,24,24,21,21,24,22],[30,29,29,29,29,29,29,28,28,28,28,28,28,27,27,27,28,26,26,27,26,27,27,27,27,28,28,28,29,28,27,29,29,30,29,29,29,29,29,29,30,29,29,29,29,29,29,27,28,27,27,26,26,26,24,24,24,22,21,20,19,18,15,15,15,13,13,13,12,12,12,13,13,14,14,14,15,15,16,15,15,16,16,16,16,17,16,17,17,18,18,19,20,20,20,20,20,20,20,21,21,21,22,21,22,22,22,22,22,21,21,22,22,22,22,21,21,22,21,21,22,21,20,21,21,22,19,21,21,20,20,21,19,18,19,19,20,19,20,20,20,20,20,21,20,21,20,21,19,20,20,19,19,18,18,20,19,18,20,18,19,18,19,18,19,18,17,20,18,19,19,20,18,20,19,19,18,19,19,18,19,18,18,18,20,18,17,18,17,17,17,18,16,17,18,17,18,19,16,17,17,16,16,18,17,17,16,17,17,17,19,18,15,19,18,17,19,19,19,17,17,19,18,16,17,18,17,15,17,16,15,16,15,16,16,16,17,17,17,17,19,18,18,18,17,19,17,18,15,17,16,16,15,15,16,16,16,16,15,16,16,15,15,15,15,15,13,15,17,14,13,15,15,13,14,15,15,15,14,15,16,16,15,14,15,15,13,14,15,14,12,14,16,14,13,16,15,14,14,13,12,12,14,13,12,12,13,13,12,12,14,12,12,12,12,12,11,10,10,11,10,11,11,10,11,11,10,10,10,10,10,12,10,11,13,13,12,12,14,16,16,16,14,17,18,15,15,18,18,17,18,22,21,21,24,24,26,23,25,22,22,23,21,20,20,22,21,21,21,23,21,23,25,25,26,26,26,27,27,28,27,28,28,28,27,28,28,27,27,28,26,27,27,26,27,26,27,28,27,28,26,27,28,26,26,26,26,25,26,25,24,23,23,21,21,18,16,15,13,11,9,8,8,9,8,7,9,7,8,9,8,8,8,9,9,8,9,8,9,8,11,9,9,11,12,12,12,12,12,12,13,11,10,11,12,10,12,12,10,10,11,9,9,10,9,8,9,9,9,8,8,8,10,10,11,9,11,11,11,9,11,12,11,10,12,13,12,12,13,13,13,13,13,14,14,14,15,14,14,14,14,14,16,15,16,14,14,16,14,14,15,15,14,13,14,14,12,12,13,13,11,13,12,11,11,11,13,11,11,12,12,11,12,11,12,14,13,14,14,14,16,14,15,15,15,15,14,15,16,17,18,18,18,17,18,17,17,16,17,16,17,17,16,15,16,15,15,15,14,14,13,13,14,14,11,12,13,12,12,11,12,12,11,11,11,10,11,11,12,11,12,11,12,12,11,12,11,11,11,12,10,10,11,11,11,10,11,10,11,10,10,11,10,10,10,11,10,11,12,13,10,13,14,13,13,14,14,14,15,15,16,17,18,18,17,18,18,18,19,19,18,17,18,18,17,18,17,18,17,18,16,16,16,16,14,14,14,14,15,14,14,13,14,13,11,11,11,10,10,10,10,9,9,11,9,9,10,10,8,7,6,6,7,6,8,7,7,8,7,7,8,9,9,8,10,9,8,8,8,9,9,8,10,10,10,10,9,10,10,9,9,10,8,8,9,8,7,6,6,6,4,3,3,5,4,4,10,8,4,7,9,8,7,8,8,7,8,8,7,6,7,7,7,7,5,6,6,6,5,3,5,3,2,1,0,1,4,4,5,6,7,7,6,7,8,9,9,8,10,11,10,9,10,12,11,11,12,12,12,13,13,13,14,13,15,14,15,15,16,17,17,17,18,20,18,21,21,21,23,25,24,21,23,24,24,26,24,25,26,23,27,26,27,27,27,26,27,28,26,27,27,26,25,24,25,26,24,23,24,24,22,25,25,23,23,24,24],[29,29,29,29,29,29,29,28,28,28,27,27,28,26,27,26,27,25,27,27,27,27,27,28,27,27,28,27,27,28,27,28,28,29,28,29,27,28,28,28,28,28,27,28,27,27,27,26,25,26,25,24,24,23,22,22,22,22,19,20,18,16,15,13,14,11,13,11,11,13,12,13,12,13,12,15,14,14,14,14,14,14,14,13,14,15,14,15,15,16,16,16,16,18,16,16,17,17,17,18,19,18,18,18,19,18,18,18,19,18,19,19,19,20,20,20,19,19,18,19,18,18,18,18,18,18,16,18,17,16,16,17,15,15,16,16,17,17,17,16,18,16,17,17,16,18,17,17,16,17,17,16,17,16,16,18,17,16,17,16,17,17,17,16,16,16,15,17,16,16,16,16,15,17,16,16,15,15,16,15,15,16,15,14,15,14,14,16,14,14,14,14,14,16,14,15,15,15,14,15,14,14,14,15,15,14,14,14,13,14,15,15,14,15,15,14,17,16,15,13,14,16,14,14,15,14,14,14,14,14,14,15,15,14,14,15,16,15,16,15,16,16,15,15,17,15,14,15,14,15,14,13,13,14,15,12,13,13,13,13,13,13,12,13,13,13,11,13,13,11,11,13,13,12,12,13,14,13,13,12,14,13,11,14,13,12,11,12,13,12,12,13,13,12,12,13,13,12,13,12,13,12,12,13,14,11,11,12,12,12,12,12,12,12,11,12,11,12,11,12,10,12,11,10,12,10,11,11,10,10,11,11,11,10,11,13,11,13,13,15,15,14,15,16,16,15,16,18,17,16,19,21,19,20,22,23,24,22,24,22,20,22,19,19,21,19,20,19,21,21,23,22,25,25,25,25,26,26,27,27,27,28,28,28,28,28,28,28,26,27,27,28,27,26,27,25,26,27,26,26,26,26,28,26,26,26,25,24,24,23,24,22,21,20,19,16,15,13,12,10,9,8,9,8,9,8,8,7,8,8,7,7,7,8,8,8,8,9,8,9,10,9,9,11,11,10,11,10,11,10,10,11,11,11,11,10,12,12,10,10,10,9,8,10,9,8,9,10,9,7,9,10,9,8,10,9,10,11,9,9,10,12,9,10,11,12,9,12,12,11,11,13,13,14,13,14,13,13,13,14,14,14,14,13,13,12,14,13,12,12,14,13,11,11,12,10,10,10,10,11,10,11,10,10,10,11,11,11,10,11,10,10,11,11,10,12,11,12,12,12,12,12,12,11,13,13,13,14,15,15,15,14,16,14,14,14,15,14,14,13,15,14,14,14,14,14,12,13,13,13,12,12,12,12,12,12,11,11,11,10,11,10,12,11,11,9,11,10,10,10,11,10,11,10,9,11,9,9,9,9,8,8,9,8,7,8,8,7,8,8,8,8,9,8,9,10,9,9,10,10,10,11,11,11,12,12,12,12,14,12,15,14,15,15,17,16,17,16,17,17,16,16,15,18,14,14,16,14,15,15,14,14,16,14,13,13,12,12,12,13,12,12,12,11,11,12,11,10,12,10,9,9,9,9,8,6,7,7,6,6,6,6,5,5,7,6,5,6,6,6,5,6,6,5,7,8,7,7,7,8,9,8,9,9,11,9,9,9,9,8,8,7,8,8,6,5,5,6,5,5,4,3,2,4,4,4,6,6,4,5,7,5,6,6,6,5,6,7,6,6,7,7,7,8,6,8,7,7,5,4,4,4,3,2,1,0,1,3,6,4,5,6,5,6,7,7,7,6,7,8,8,7,8,9,9,10,10,11,10,12,14,12,12,14,14,14,14,14,16,15,16,18,18,19,18,20,21,20,23,23,22,22,23,22,22,26,24,24,25,23,26,24,25,26,26,24,26,27,25,25,25,26,24,22,25,25,24,22,24,24,22,24,24,21,23,25,23],[29,29,28,28,29,28,29,28,27,27,26,26,27,25,26,25,27,25,26,27,25,25,27,27,26,27,27,26,28,28,26,28,29,29,28,29,27,29,29,29,29,28,28,29,28,28,28,26,27,26,26,24,25,23,24,23,22,22,20,19,18,16,15,14,14,12,13,13,12,12,12,12,12,11,13,12,14,14,14,13,13,14,13,13,14,15,15,14,14,15,15,16,17,17,17,16,18,17,18,18,18,18,18,18,19,19,19,19,20,19,19,18,20,20,19,19,19,19,20,19,19,18,19,18,19,19,17,19,18,17,17,18,17,17,16,17,17,17,17,16,18,17,16,18,16,18,17,17,16,17,17,16,17,16,16,17,16,16,17,16,17,16,17,17,17,16,16,17,15,18,17,17,16,18,17,17,17,16,17,16,16,16,15,16,17,15,15,16,14,15,15,14,14,15,15,16,15,15,15,15,14,15,15,15,15,16,15,15,15,15,15,15,13,16,15,14,16,16,16,14,15,16,17,14,15,16,14,14,15,15,13,14,13,15,15,15,16,16,16,16,17,16,16,16,17,17,15,15,13,15,15,14,13,13,14,14,14,14,13,14,14,14,14,14,16,14,12,14,15,13,13,14,13,13,14,15,14,13,13,13,13,14,13,13,14,13,12,13,13,13,13,12,14,13,14,14,14,13,13,14,12,12,13,13,11,12,12,13,11,12,13,13,12,12,12,11,11,11,11,11,10,10,10,11,11,11,11,11,10,10,11,12,10,12,12,13,11,12,14,16,15,15,13,15,17,16,15,19,17,18,19,22,21,22,23,23,24,22,25,21,23,23,20,21,21,21,20,20,22,24,22,24,24,24,25,26,25,26,26,27,27,27,27,28,27,28,28,28,27,27,27,28,28,28,27,26,27,27,27,28,27,28,28,27,26,26,26,25,25,25,24,23,22,20,20,17,16,14,12,11,10,9,10,9,8,8,9,9,9,9,8,7,9,9,7,8,10,9,8,9,12,10,10,11,13,12,11,11,12,12,11,10,10,11,11,11,12,11,11,11,12,10,10,10,10,10,9,10,10,9,9,9,9,10,10,10,9,12,10,9,10,12,10,9,11,12,11,11,12,12,12,13,12,13,12,13,13,13,13,12,13,13,14,13,14,13,13,14,13,13,14,14,12,13,13,12,12,11,11,12,11,11,11,11,11,11,13,11,10,11,11,10,12,11,11,13,11,13,13,14,15,14,14,13,15,14,13,14,15,15,15,16,17,15,16,16,17,15,15,15,16,15,14,16,15,14,14,14,13,14,13,13,14,13,12,12,11,12,11,11,12,11,10,11,11,10,10,11,11,11,10,11,11,12,10,11,10,10,11,12,9,9,11,9,9,8,11,9,10,8,8,9,9,8,9,11,9,8,11,11,11,11,13,12,12,14,13,13,14,13,14,15,15,15,15,15,17,16,17,17,15,17,16,16,15,16,16,15,16,17,15,15,16,14,14,12,13,12,13,13,13,12,12,12,12,12,11,10,11,11,10,9,9,11,8,7,10,8,6,6,5,5,5,5,7,5,4,5,7,5,5,7,6,7,6,8,9,7,7,8,9,8,9,10,10,10,10,11,10,9,9,9,7,6,7,7,5,5,5,5,4,3,3,5,3,3,6,6,4,6,7,7,8,7,8,6,8,7,7,7,8,8,8,8,6,8,8,7,6,5,5,4,4,5,3,1,0,1,3,3,4,5,5,6,7,8,7,7,8,8,8,9,9,10,10,11,11,11,11,12,12,13,13,13,14,13,14,14,15,15,15,16,16,18,17,19,20,21,23,23,22,22,23,22,22,25,24,24,25,23,26,25,26,25,26,24,27,26,24,27,25,24,25,23,23,25,23,23,24,24,21,25,25,22,23,24,23],[29,29,28,28,28,28,28,27,26,27,25,25,26,23,26,24,26,24,26,26,25,26,27,25,26,27,27,26,28,27,27,28,28,28,28,29,26,28,28,28,28,28,28,28,28,27,27,24,25,26,26,23,24,24,23,22,22,21,19,20,18,17,15,14,14,12,13,14,12,15,13,14,13,14,15,16,15,16,16,17,15,17,17,15,17,17,16,17,17,18,18,18,18,20,19,18,20,19,19,21,21,20,20,20,21,20,21,21,21,20,22,21,20,22,21,21,21,22,21,21,20,20,19,20,20,21,18,20,20,19,19,19,19,17,18,18,20,18,18,17,18,18,18,20,19,19,19,19,18,19,19,19,20,19,19,21,19,18,20,19,20,19,19,18,18,19,18,20,19,18,18,20,19,19,19,18,18,18,19,18,18,19,16,17,19,17,15,17,16,15,15,16,16,17,15,16,17,16,15,16,16,16,16,17,15,17,15,15,15,16,17,17,15,17,17,16,18,18,18,16,16,18,19,17,17,18,16,16,17,17,16,17,15,17,16,18,18,17,17,16,19,18,17,19,19,17,16,18,16,17,15,15,15,14,15,14,15,14,13,14,15,15,14,13,15,14,12,14,16,14,11,13,14,13,13,15,16,14,15,15,16,15,14,15,14,15,14,15,15,14,15,14,14,13,14,16,14,14,14,14,13,13,14,14,14,13,14,13,13,13,14,13,13,13,13,14,13,14,12,13,12,12,12,12,12,12,14,12,11,11,12,11,12,10,12,12,11,14,14,15,16,16,14,15,17,16,14,18,18,16,17,21,21,20,20,22,24,21,25,21,21,21,20,18,20,21,21,19,21,22,23,24,23,23,24,26,25,27,26,27,27,28,27,27,28,28,28,27,26,27,26,28,27,27,27,25,27,27,26,27,26,26,28,25,26,27,24,25,25,23,24,22,22,21,19,18,17,15,13,12,12,10,11,12,11,11,12,11,11,12,10,10,10,10,10,10,12,10,10,12,13,11,11,12,13,12,12,14,13,13,14,13,11,14,13,12,14,13,10,12,12,11,11,13,11,10,10,12,12,11,12,12,12,11,13,12,12,13,11,11,13,14,10,12,12,11,10,13,12,11,12,13,12,14,14,13,14,13,13,13,14,13,14,15,15,13,13,15,14,11,13,13,13,11,13,12,12,10,11,13,11,10,12,13,11,12,13,14,11,12,12,11,12,11,11,13,12,14,13,14,13,14,14,15,15,15,16,16,16,17,16,16,17,16,15,16,16,15,16,15,16,16,16,15,17,17,15,14,15,15,14,14,16,15,14,14,13,14,13,12,13,12,13,12,13,12,13,12,12,12,13,11,12,12,10,12,12,9,10,13,10,7,10,11,9,8,10,9,9,9,9,11,10,10,11,13,11,9,13,11,11,12,13,15,14,13,15,14,16,15,17,17,18,18,18,19,20,19,19,20,19,19,17,19,17,16,17,16,17,16,15,16,16,16,14,15,15,15,13,15,15,15,15,13,13,13,13,12,13,12,12,11,13,11,10,10,11,9,7,9,7,6,7,5,8,7,6,6,6,6,6,7,9,6,7,8,10,8,8,10,11,10,11,12,12,11,11,12,12,10,10,11,10,9,9,9,9,8,6,6,5,4,4,5,4,5,5,7,6,6,7,8,7,8,8,7,8,9,9,9,9,10,11,11,10,9,10,9,8,8,5,5,5,6,3,2,1,0,1,2,3,4,3,5,5,7,6,5,6,7,8,7,8,10,9,9,10,12,11,12,12,12,13,13,14,13,13,14,14,15,15,16,17,18,17,20,21,21,22,23,23,20,22,23,22,25,22,24,23,21,26,23,24,25,24,23,26,26,23,23,25,24,22,22,23,24,24,22,24,23,22,23,25,23,22,24,24],[28,28,27,28,28,28,27,26,27,26,25,26,26,24,26,24,25,25,26,26,26,26,26,27,26,26,28,26,27,27,26,28,28,28,27,28,28,28,28,28,28,28,28,28,27,27,27,25,25,26,24,24,24,23,22,22,21,21,19,19,18,16,15,14,14,12,13,12,12,12,11,12,11,12,11,13,13,13,13,13,13,12,13,12,12,13,13,14,13,14,15,15,15,15,16,17,15,16,17,17,17,18,17,18,18,18,19,18,19,19,19,18,18,18,18,18,18,19,19,18,18,17,17,17,18,17,15,17,16,14,16,16,14,15,15,15,16,16,16,16,16,15,17,17,15,16,16,15,13,15,16,14,14,15,15,15,16,16,16,16,16,15,16,15,15,15,16,16,15,15,15,15,14,15,15,14,13,15,15,14,14,13,13,14,13,13,13,14,12,12,13,13,12,14,13,14,14,14,13,13,13,14,13,13,14,13,13,13,13,13,14,14,12,15,14,13,13,14,12,12,11,14,12,12,13,13,12,12,13,13,12,13,14,14,14,14,15,15,14,15,14,15,15,14,14,15,13,14,13,14,13,11,12,13,13,12,12,12,12,11,12,11,11,11,11,10,9,10,11,10,9,10,10,10,10,10,11,12,11,12,12,11,10,10,11,10,10,10,11,10,9,10,11,10,10,12,11,11,11,11,11,12,12,11,13,12,11,11,12,12,13,12,12,13,12,12,11,12,11,11,11,12,11,10,11,10,12,12,10,11,12,11,13,13,12,15,13,14,13,16,16,15,16,17,17,16,17,18,18,17,19,20,21,21,21,22,23,21,23,21,21,22,20,20,22,22,22,20,22,24,23,24,25,23,25,26,25,26,26,27,27,27,28,28,28,28,28,28,27,28,28,28,28,27,28,26,27,27,27,27,27,26,27,26,26,26,26,25,25,24,25,23,21,21,19,16,16,14,13,12,11,11,11,10,9,9,9,9,7,9,8,8,9,8,9,8,10,9,10,10,11,10,10,11,11,11,11,11,12,10,10,11,10,12,12,11,12,12,11,11,11,10,11,11,10,10,9,10,11,9,10,10,10,9,11,9,9,11,10,9,11,11,9,9,11,10,9,11,11,9,10,11,11,11,12,13,12,12,12,12,12,13,12,12,11,10,11,12,10,11,10,10,10,9,9,8,8,7,8,8,8,7,9,8,8,8,9,8,8,10,10,9,10,10,9,10,10,10,10,11,10,10,10,10,11,12,12,12,13,14,14,14,15,14,13,14,14,14,14,13,14,15,13,13,14,13,11,12,12,11,10,11,11,10,10,9,9,9,9,10,9,8,9,9,9,8,9,9,9,8,10,9,10,9,8,9,8,6,7,9,6,6,6,7,6,6,7,6,6,6,7,8,7,8,8,9,8,9,9,9,10,11,11,11,12,12,12,12,12,13,14,15,15,14,15,15,15,16,15,16,15,16,16,16,14,15,15,14,15,15,14,14,15,14,14,13,13,13,13,13,12,11,10,11,11,10,9,9,10,8,8,8,8,8,7,6,7,7,6,6,6,5,4,4,5,5,3,5,6,5,4,7,6,6,7,7,7,6,7,8,9,8,10,11,10,10,12,10,9,9,8,8,8,7,7,6,6,6,5,6,5,4,3,5,5,5,6,6,5,6,7,6,7,7,8,7,7,9,7,7,9,8,8,8,8,7,7,8,7,6,5,5,6,6,5,4,2,1,0,1,2,3,4,3,5,6,5,5,6,7,6,6,6,7,7,7,8,9,8,9,11,10,10,10,11,12,12,13,13,13,13,15,14,16,16,18,19,18,21,20,20,19,21,21,19,23,21,23,23,21,25,23,23,23,24,22,25,25,23,24,24,24,22,21,22,25,23,21,23,22,22,24,24,21,22,24,22],[29,28,27,28,27,27,27,26,26,26,24,25,24,23,25,24,25,22,25,25,24,25,26,23,25,26,25,25,27,26,25,27,26,28,27,29,26,28,28,28,28,28,28,27,28,27,27,25,26,26,25,23,25,24,22,22,22,19,19,21,18,16,15,15,14,14,13,14,13,14,14,13,13,12,13,13,15,16,16,14,13,15,15,13,15,16,13,16,15,15,17,16,17,17,18,17,17,18,18,18,19,18,18,18,19,19,19,19,18,19,19,18,18,20,20,19,18,21,20,19,19,19,20,18,18,19,18,18,18,17,18,18,16,16,16,16,17,16,17,17,17,16,17,19,17,17,18,18,16,18,18,17,17,17,17,18,18,17,18,18,19,18,19,18,18,18,17,17,16,18,17,18,16,18,17,17,17,17,17,16,17,16,16,16,17,14,16,16,14,14,15,14,13,14,14,14,16,15,13,14,14,14,13,15,14,14,14,14,14,15,16,15,13,17,16,13,14,16,16,13,14,17,15,13,15,16,14,13,15,16,14,15,15,16,16,16,16,15,16,16,17,16,16,17,17,16,15,16,15,15,15,13,13,14,12,14,14,12,12,11,12,13,12,11,12,12,10,10,12,11,9,11,11,10,10,11,12,12,11,13,12,12,11,11,13,11,11,12,13,11,11,12,13,12,13,15,13,11,13,13,12,13,13,13,14,13,12,14,12,12,12,12,12,12,11,12,13,11,11,14,13,13,12,11,13,12,13,12,12,12,11,13,12,11,13,13,12,15,14,16,16,16,14,17,17,17,17,19,18,18,18,22,22,21,22,23,24,22,24,21,22,22,21,20,20,21,21,19,21,22,21,22,24,23,24,26,25,27,25,27,27,28,27,27,27,27,28,28,27,27,27,27,27,27,28,24,27,27,26,27,27,26,27,25,25,25,25,24,24,23,23,22,22,21,20,18,17,15,14,12,12,11,11,12,11,10,10,10,9,11,9,8,9,10,8,10,11,10,10,10,12,10,11,10,11,11,11,12,11,12,11,11,12,13,12,11,12,11,12,11,12,10,10,11,11,10,10,11,11,11,11,11,10,11,12,12,10,11,9,9,11,13,9,10,10,9,9,10,10,9,10,11,11,12,12,12,12,12,11,12,12,12,12,13,13,12,12,12,11,11,11,11,10,10,10,9,10,8,9,10,9,8,9,10,9,8,11,10,9,10,11,10,11,9,9,11,12,11,10,11,10,11,11,12,12,13,13,13,14,15,15,15,15,15,16,15,16,15,15,14,15,15,15,14,15,14,12,12,13,12,11,11,12,11,11,11,10,10,11,11,11,10,11,11,10,10,11,11,10,9,11,10,11,10,9,11,9,7,8,8,7,6,7,7,6,6,8,7,7,6,7,8,8,8,8,9,9,9,10,10,11,12,13,13,13,14,13,14,13,14,16,16,17,16,16,16,17,18,17,18,17,17,16,17,16,16,16,15,16,16,14,15,15,14,13,14,14,14,14,13,13,13,13,12,11,12,10,9,11,11,10,9,11,9,8,7,8,6,6,6,5,5,4,4,4,5,4,5,6,5,5,6,5,6,7,8,7,8,8,9,9,10,11,11,12,12,11,11,10,11,11,10,9,8,9,8,8,7,6,6,6,5,5,5,5,5,7,8,6,7,8,8,7,9,9,8,9,9,9,9,9,9,10,10,8,9,9,8,6,6,6,6,5,6,4,4,4,3,1,0,1,2,2,3,4,5,5,4,5,6,5,5,7,7,7,7,8,9,9,9,10,10,10,10,10,11,11,11,13,13,13,14,15,17,16,20,21,21,23,22,24,21,22,22,21,24,21,24,25,21,26,23,25,25,24,21,26,26,23,23,25,24,22,22,24,25,23,22,24,23,22,25,25,22,22,25,23],[28,28,27,28,28,27,27,27,26,26,25,25,26,23,26,24,25,25,26,25,25,25,26,26,25,27,27,26,28,28,27,28,29,29,27,29,28,28,29,28,29,27,27,28,28,28,28,26,26,27,25,25,25,25,23,23,23,23,22,21,19,17,15,14,15,13,13,13,13,13,12,13,13,12,12,13,14,14,15,14,14,13,14,14,14,14,15,14,15,16,16,16,16,17,16,17,16,16,18,18,17,18,18,17,18,18,19,18,18,19,19,18,18,18,17,19,18,19,18,18,19,16,16,18,18,16,17,18,17,16,17,17,15,17,16,16,16,16,15,16,15,16,17,17,16,16,17,16,16,17,16,16,16,15,15,17,17,17,16,16,16,16,17,16,16,16,16,16,15,15,16,16,15,16,16,15,15,16,16,15,15,15,14,15,15,13,14,15,14,13,15,14,13,13,14,14,15,15,14,15,15,16,14,14,15,15,13,14,14,16,15,15,14,15,15,14,14,15,14,14,13,14,14,14,14,14,13,14,13,14,12,14,14,15,15,15,16,15,15,15,16,15,16,15,14,14,14,15,13,13,14,13,12,12,12,12,13,13,12,11,11,11,12,10,11,12,9,11,12,10,9,11,11,9,9,11,12,13,13,12,13,12,11,11,11,11,10,12,12,11,10,11,11,11,12,13,11,11,11,13,11,11,12,12,12,12,12,12,12,12,13,11,12,12,11,13,12,14,13,12,14,12,12,12,13,13,14,12,12,13,13,13,13,12,13,13,13,14,14,16,16,17,14,17,18,18,16,19,18,18,19,22,22,21,24,24,24,23,24,24,22,23,22,19,21,22,22,20,21,22,23,22,25,24,25,26,26,26,26,27,27,27,27,27,28,28,28,28,28,28,28,28,28,27,28,25,27,28,26,27,27,26,28,25,27,27,26,26,26,26,25,23,22,22,21,19,17,16,14,13,12,10,12,11,11,11,11,9,9,10,9,8,10,10,10,10,11,10,10,10,11,11,11,11,13,11,12,11,13,11,11,12,10,13,13,12,14,13,11,11,14,12,11,12,12,10,11,12,12,10,11,11,12,11,12,11,10,12,10,10,11,11,10,9,10,9,9,10,10,9,9,11,10,11,12,12,12,11,10,12,11,13,12,12,13,10,10,11,12,10,10,10,9,8,11,9,9,8,8,10,9,7,9,10,8,8,10,11,10,11,11,10,10,9,9,10,13,12,10,11,9,10,12,11,14,14,12,13,14,14,15,16,15,14,15,14,16,15,15,14,15,15,14,13,14,13,13,12,11,11,10,11,12,11,10,11,12,10,10,11,10,10,10,11,10,10,10,11,10,10,11,10,11,9,9,9,9,7,8,9,7,5,7,8,5,5,7,6,7,6,6,8,8,6,8,9,8,9,9,9,9,11,12,12,12,12,13,13,13,13,15,16,16,15,16,16,15,17,16,16,16,16,16,16,15,16,15,14,16,16,14,15,16,15,14,13,13,13,14,12,12,12,12,11,11,11,10,9,10,10,9,9,9,8,7,8,8,6,6,6,6,5,5,4,6,5,3,4,5,3,4,5,5,6,7,8,8,8,7,8,10,8,9,11,10,11,11,11,9,8,9,10,9,8,8,6,6,8,6,6,6,6,4,5,5,5,7,6,6,7,8,8,9,9,9,7,8,10,8,9,9,10,8,9,10,8,9,8,6,6,6,6,6,6,5,4,4,3,1,1,0,1,2,3,3,4,4,4,4,6,5,5,7,7,6,7,8,9,9,9,10,10,10,9,10,11,11,11,11,14,12,14,15,17,17,19,20,21,22,22,22,21,22,22,21,25,22,24,25,19,26,23,25,25,25,21,26,25,23,25,25,25,23,21,24,25,23,22,24,23,22,23,24,20,22,23,22],[28,27,26,27,27,26,26,25,25,26,23,24,23,22,24,22,23,22,24,24,23,24,26,23,25,27,26,25,27,27,26,28,28,29,28,29,28,29,28,28,29,28,28,29,28,28,28,26,27,27,26,25,26,25,24,23,22,22,20,21,20,18,17,14,13,14,12,12,13,13,13,13,13,13,13,14,14,16,15,13,13,16,16,13,14,15,15,16,15,15,17,17,17,18,17,17,18,17,17,18,19,17,18,18,18,17,18,18,18,19,19,19,19,20,18,19,19,21,19,18,18,18,18,18,17,18,17,17,17,17,18,17,16,17,16,18,16,15,15,16,15,15,16,18,17,18,17,18,16,17,17,16,18,17,17,18,18,18,17,18,18,18,18,18,18,17,17,18,15,16,17,18,14,17,17,16,15,16,16,16,16,14,16,15,16,13,16,15,14,14,14,13,14,15,15,15,17,15,13,16,15,15,14,15,14,16,14,15,13,15,14,15,14,15,15,14,14,16,15,14,14,16,14,13,16,16,13,12,15,15,13,13,14,16,15,16,17,16,16,15,17,15,16,16,14,15,15,15,13,13,13,13,13,13,15,13,13,13,13,12,13,13,12,12,13,13,11,12,13,11,10,11,11,11,11,13,14,13,12,12,13,13,11,11,12,12,11,12,13,12,11,12,12,12,13,14,13,13,13,13,11,12,12,13,13,13,12,13,11,12,11,12,11,12,11,12,11,12,11,11,12,11,12,11,13,12,12,11,11,12,12,11,12,11,12,14,13,15,15,14,17,17,15,17,19,18,16,19,19,18,19,22,22,21,23,24,24,24,25,21,23,23,22,20,20,22,22,21,19,21,23,24,24,22,25,25,25,26,26,27,26,26,26,27,27,28,27,27,27,27,27,27,28,26,27,25,28,27,26,27,27,26,27,25,27,27,25,25,25,25,26,24,22,21,20,19,17,15,14,12,12,11,11,10,10,11,11,10,9,10,8,9,10,10,9,10,11,9,11,11,11,10,11,10,10,10,10,11,11,10,11,11,10,12,11,11,11,11,10,11,13,11,11,11,10,11,10,11,10,10,10,10,13,11,12,9,11,12,9,8,9,10,8,9,10,10,8,9,10,8,8,11,10,11,11,11,12,12,10,11,10,11,12,12,13,12,10,12,12,11,11,10,10,9,10,9,9,10,9,11,9,10,9,10,10,9,11,10,10,10,11,9,10,9,9,11,12,11,11,12,10,11,12,11,13,13,13,12,15,16,15,14,16,15,15,16,15,15,16,15,16,15,14,14,14,14,12,12,12,12,11,11,13,12,10,11,11,11,11,11,11,10,12,12,11,10,10,11,10,9,11,11,11,9,8,9,8,7,7,9,7,7,6,7,8,8,8,8,7,6,7,7,7,7,9,9,8,9,9,10,10,11,11,12,13,12,12,12,14,12,16,16,16,16,16,17,18,18,17,17,17,18,16,16,17,16,16,16,17,16,15,16,14,15,14,14,14,14,12,13,13,11,12,11,12,11,10,10,11,11,10,10,10,9,7,8,9,7,6,7,6,5,5,5,5,5,4,6,7,4,5,6,6,6,6,8,7,7,8,8,9,9,9,10,10,10,11,11,10,9,11,10,9,10,9,7,7,8,6,7,7,6,5,5,6,7,7,7,8,8,8,9,8,9,9,10,10,9,11,10,9,9,10,10,10,11,9,8,8,7,7,8,7,8,6,5,5,4,3,1,1,0,1,2,2,3,5,4,5,6,6,6,7,8,8,7,7,9,9,9,9,10,10,9,11,12,12,12,11,15,12,13,15,18,17,21,20,22,21,22,23,19,22,22,21,25,21,23,24,22,26,24,25,25,26,23,26,25,24,25,24,23,24,22,22,24,23,23,25,22,22,24,25,21,21,24,24],[27,27,26,27,27,27,27,26,26,26,25,25,25,24,25,25,26,25,26,27,26,26,27,27,26,27,28,26,28,28,27,28,28,28,28,28,27,28,28,28,28,28,27,28,28,27,27,25,25,26,24,23,23,23,21,21,21,20,19,19,19,16,15,13,14,13,13,13,12,13,12,12,12,13,12,13,13,14,14,15,13,14,14,12,14,14,13,15,13,16,16,15,15,17,16,16,16,16,16,17,18,17,16,17,17,18,18,18,18,18,19,18,17,18,17,18,17,18,17,17,17,17,16,17,17,17,15,16,17,15,16,17,15,14,15,14,15,15,14,15,15,16,16,17,17,16,16,16,15,16,16,16,17,16,15,17,17,16,17,16,17,17,16,16,16,16,16,16,15,15,15,15,14,16,16,15,14,14,15,13,14,14,13,13,15,13,13,14,14,13,12,13,14,14,13,13,13,13,12,12,12,13,13,13,13,12,12,13,13,14,13,13,13,13,14,13,15,15,14,13,13,15,15,13,14,14,13,13,13,14,12,14,13,14,13,14,14,14,14,14,15,14,14,15,14,13,12,14,13,13,13,13,11,12,12,12,12,12,11,11,11,12,12,12,12,12,9,13,13,11,11,11,12,11,11,11,12,12,11,12,14,12,11,12,12,13,11,12,13,12,10,12,12,11,12,14,12,12,12,13,11,11,11,11,12,11,12,11,11,11,11,10,11,10,10,11,9,10,10,10,11,11,11,10,12,11,12,11,11,12,12,12,11,12,14,14,13,16,15,16,17,16,16,18,18,16,17,19,19,18,20,22,22,21,23,24,26,24,26,24,24,23,22,19,21,23,22,21,21,23,24,24,26,26,26,26,27,27,27,28,28,28,28,28,28,28,28,28,27,28,27,28,28,27,27,25,27,28,26,27,26,26,28,25,26,26,25,25,24,24,24,22,22,20,19,17,17,14,13,12,12,10,10,10,9,9,10,9,8,9,7,8,8,8,8,9,10,8,9,9,11,9,9,12,12,10,10,10,11,10,11,10,10,10,10,11,12,12,9,13,12,12,9,12,10,9,9,10,9,9,9,10,10,8,11,9,9,10,8,7,9,11,7,9,9,11,8,9,10,10,8,9,9,12,11,11,12,11,10,10,10,11,11,12,12,11,11,11,13,9,12,11,12,9,12,11,10,11,11,11,10,10,11,11,10,10,11,10,11,11,10,9,9,9,9,11,11,11,10,10,11,10,10,11,12,12,12,13,14,14,13,13,13,14,13,14,15,14,14,13,14,14,14,13,14,13,12,12,12,13,12,12,12,12,11,11,11,12,11,11,12,10,10,11,12,10,11,13,10,9,11,10,10,8,8,10,9,7,9,9,8,7,8,8,7,7,9,7,9,7,7,10,8,6,9,10,9,9,10,10,9,11,10,12,11,11,13,12,14,12,15,16,16,16,15,17,16,17,17,17,16,16,15,17,15,14,15,14,14,14,13,14,14,13,13,12,12,13,12,13,12,12,12,11,11,11,11,11,12,10,10,10,9,10,7,7,8,8,6,6,5,5,3,3,5,4,4,4,6,4,5,6,7,8,6,8,8,7,7,9,10,8,10,11,11,10,10,10,11,10,9,10,9,8,7,7,7,6,6,6,7,6,5,6,6,7,6,6,6,7,7,7,8,9,8,8,9,9,8,9,9,10,9,9,9,7,8,7,8,7,6,7,8,7,6,5,5,4,3,2,2,1,0,1,2,2,3,4,4,5,5,5,8,7,7,8,9,12,10,10,10,10,12,10,10,11,12,11,12,13,12,14,15,16,16,19,17,19,20,20,20,18,20,21,20,23,19,23,22,21,25,23,22,24,25,22,25,25,23,22,23,24,22,21,20,23,23,20,22,22,21,23,24,21,21,23,22],[28,28,28,28,28,28,28,27,27,26,26,26,26,25,26,25,26,25,26,26,26,26,27,26,26,27,28,27,28,28,27,28,28,29,28,28,28,28,29,28,29,28,28,28,28,28,27,26,26,26,24,24,24,23,22,22,21,21,19,19,18,16,14,13,13,12,11,11,11,11,10,9,9,8,9,10,12,11,11,11,10,11,11,10,10,11,11,12,12,12,13,13,13,13,13,15,14,14,15,15,14,15,16,15,14,16,16,16,15,16,16,16,15,15,14,16,15,16,15,15,16,13,14,15,15,14,13,15,14,13,13,13,13,13,12,13,13,12,13,13,13,14,13,14,13,14,14,13,12,13,13,11,12,13,13,13,14,14,14,15,14,13,14,13,13,13,14,14,13,13,13,13,12,12,13,12,11,12,12,12,12,10,11,11,11,10,11,12,10,9,11,10,10,10,11,11,11,12,10,12,11,12,11,11,12,11,11,12,11,12,12,11,11,12,12,11,10,11,11,10,10,11,10,10,11,10,10,10,10,11,9,11,12,11,13,12,12,13,12,12,12,13,12,11,11,12,11,10,10,10,10,9,9,9,10,10,10,10,9,8,9,9,8,7,8,8,6,8,9,8,7,9,9,9,8,8,10,11,10,10,10,10,9,9,9,9,8,9,9,9,8,7,9,8,9,8,8,8,8,8,8,9,8,9,9,9,8,8,9,9,7,8,9,9,7,9,7,10,8,8,9,9,9,9,10,9,10,9,9,10,10,11,11,11,11,13,13,12,14,15,16,15,15,17,18,18,18,19,19,19,20,22,24,23,24,25,25,25,25,24,24,25,23,23,23,24,24,22,23,24,25,26,27,27,27,27,27,28,28,28,28,28,28,29,29,29,29,29,28,29,28,29,29,28,28,27,28,28,27,28,28,27,28,26,26,26,26,25,26,24,24,23,22,20,19,17,16,14,13,11,10,9,9,9,8,8,8,6,7,7,6,7,6,8,8,7,8,9,9,9,9,10,9,10,11,10,10,10,10,10,10,9,9,9,10,10,11,11,9,10,11,9,9,10,9,9,8,9,8,8,7,9,8,7,7,7,7,7,6,7,7,6,6,6,7,7,8,7,7,6,7,8,7,8,9,8,9,9,8,8,7,8,8,9,8,7,7,8,9,8,7,7,7,6,6,7,7,5,7,8,6,7,8,8,7,8,9,8,10,8,8,7,8,8,9,9,10,10,10,9,11,9,10,9,10,11,9,10,12,12,12,12,13,13,13,13,13,13,13,12,14,13,12,12,12,11,11,11,10,10,9,10,10,9,8,8,8,8,8,8,8,9,8,8,8,6,7,8,7,6,7,8,8,6,5,6,5,5,5,6,5,4,5,7,5,5,8,7,6,6,7,7,8,7,7,8,8,9,8,9,8,9,10,10,10,10,11,12,11,11,13,12,12,13,12,12,13,13,13,13,13,14,13,14,14,13,13,13,13,13,13,13,14,13,12,11,12,11,12,11,11,10,9,9,10,8,8,8,8,7,8,7,7,7,8,7,10,6,5,7,7,4,3,3,4,4,2,5,5,4,5,6,6,6,7,6,7,8,6,7,7,7,8,9,9,9,9,9,7,7,7,7,6,6,7,6,6,6,5,5,5,4,4,5,5,5,6,7,5,6,7,7,7,8,7,7,7,7,7,7,8,8,8,8,7,8,7,8,7,5,6,5,6,5,5,4,5,5,2,2,3,2,1,0,1,2,5,4,3,6,4,4,6,6,5,5,7,6,6,6,6,7,8,7,8,9,10,10,11,12,12,12,14,16,15,18,17,18,20,21,21,17,21,21,20,24,18,23,22,21,26,23,22,24,25,23,25,25,24,22,23,24,23,20,21,23,23,20,23,22,21,23,24,20,21,23,21],[28,28,27,28,27,26,27,26,25,26,23,24,25,21,25,23,25,24,24,26,25,26,27,27,26,27,28,27,28,27,27,28,29,29,28,29,28,28,29,29,29,29,28,28,28,28,28,27,27,26,25,24,24,24,23,23,22,20,19,21,18,16,14,12,11,11,10,9,11,10,10,9,10,9,10,9,11,11,12,11,10,11,11,9,11,11,10,12,11,12,13,14,13,14,15,14,12,13,15,14,14,15,15,15,15,15,16,16,15,16,17,16,15,15,15,16,16,16,15,16,15,14,14,15,15,14,15,14,13,12,14,13,11,13,13,14,13,12,13,13,13,13,13,13,12,12,13,13,12,13,13,12,12,12,13,13,14,15,14,15,15,14,15,14,14,13,15,15,12,13,13,13,12,13,13,12,12,12,12,12,12,11,11,11,11,10,11,11,9,9,13,10,10,10,11,11,13,13,10,11,12,11,11,12,11,10,11,11,11,12,13,12,11,12,12,11,11,12,11,10,10,11,11,10,11,11,10,10,11,11,10,11,11,12,12,12,12,12,12,12,13,12,12,12,11,11,11,10,10,10,10,9,9,10,9,10,10,9,8,8,10,9,9,8,8,8,7,8,8,8,7,8,8,7,8,8,9,10,9,9,10,10,9,8,9,9,8,9,9,9,8,8,9,9,9,10,9,9,10,9,9,9,9,9,10,9,9,8,8,8,8,8,8,8,7,8,8,8,8,8,10,9,9,8,10,9,10,9,9,9,10,11,10,9,11,12,12,14,13,15,16,15,15,17,18,18,17,20,18,19,19,22,24,21,23,24,25,24,26,22,22,23,21,22,22,23,23,22,21,23,23,25,26,25,26,26,27,27,27,27,27,27,27,27,27,27,28,28,27,28,28,28,28,27,28,26,27,28,27,28,27,26,28,27,26,26,26,24,24,24,23,22,22,21,20,18,17,14,13,10,9,8,8,8,8,7,7,7,6,7,7,6,7,7,7,7,9,8,8,8,10,10,8,8,9,9,10,10,10,10,10,9,9,9,9,9,9,9,9,8,9,8,9,8,8,7,8,8,8,8,8,8,7,8,8,8,7,7,6,5,6,6,6,5,5,5,5,5,5,5,6,6,7,7,8,7,8,7,6,7,7,8,7,8,8,7,7,8,8,7,6,7,6,6,6,6,6,5,6,7,6,6,6,7,7,6,8,7,7,7,8,7,7,7,7,8,10,8,8,9,8,8,9,10,10,10,9,10,11,12,12,12,14,12,13,13,13,13,12,11,13,12,12,10,12,11,10,9,10,9,8,8,10,9,8,8,8,7,8,9,9,7,7,8,7,7,6,8,6,6,7,7,6,6,5,5,5,4,4,5,5,4,4,5,5,4,6,5,5,6,5,5,5,6,6,6,6,6,7,8,8,9,8,9,9,10,10,11,10,11,13,13,14,14,13,12,13,14,13,13,13,14,14,14,14,14,14,13,13,13,13,12,13,13,11,12,12,12,12,10,10,9,10,8,8,9,8,7,8,7,7,6,7,6,6,6,6,4,4,4,4,3,3,2,4,4,3,4,4,4,4,5,5,6,6,6,6,6,5,6,7,6,7,8,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,5,4,4,5,5,5,6,6,5,5,6,6,6,6,6,6,7,7,7,7,7,6,6,7,6,6,7,7,6,5,5,5,5,5,5,5,5,4,4,3,3,4,2,1,0,1,1,1,2,2,3,2,2,3,4,3,4,5,5,5,5,5,6,6,6,7,8,9,10,11,12,11,12,16,15,16,18,19,21,21,20,17,21,20,18,23,18,22,22,19,25,23,21,24,25,22,24,26,25,19,23,24,22,20,21,24,23,20,25,22,22,23,25,21,21,24,23],[27,27,25,26,26,25,27,25,25,26,23,23,24,22,24,23,25,24,25,26,24,25,26,26,25,26,26,25,26,26,25,27,26,27,26,27,26,27,27,27,27,26,25,26,26,26,25,23,23,24,23,21,22,21,19,19,19,18,16,17,16,13,12,10,10,9,8,9,8,8,7,7,7,7,7,7,8,9,9,8,8,9,8,8,9,9,8,9,9,10,10,10,10,11,11,11,10,11,11,11,12,12,12,12,13,13,13,13,13,14,14,14,13,14,13,13,13,13,12,12,12,11,11,12,12,12,10,12,11,9,10,11,9,9,10,10,10,10,10,10,10,10,11,11,9,10,11,11,10,11,11,10,10,10,11,12,12,12,12,12,12,11,11,11,11,10,11,11,10,9,11,11,9,10,11,10,9,9,9,8,9,9,8,9,9,8,8,9,8,7,8,8,7,8,8,8,9,9,8,8,9,9,8,8,9,8,8,9,8,9,9,8,8,9,9,9,9,9,9,8,8,9,8,8,9,8,8,8,8,8,7,8,8,9,9,10,10,10,9,10,10,8,8,9,8,7,7,8,7,7,7,7,6,6,7,7,7,7,6,6,6,7,7,5,6,7,5,6,7,6,6,7,7,6,6,6,7,7,6,7,8,8,7,7,8,7,6,7,7,7,6,7,7,6,7,7,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,6,5,6,6,6,7,7,6,6,7,7,8,7,7,8,8,9,9,8,10,11,10,12,12,14,14,14,13,15,17,15,15,18,18,16,18,20,21,19,21,22,23,21,24,20,21,21,20,19,20,22,21,20,20,23,23,24,24,25,25,25,26,26,26,26,26,26,26,26,26,27,27,27,26,26,26,26,26,26,26,25,26,25,25,26,25,24,26,25,24,24,24,23,24,22,22,20,19,17,17,15,14,12,11,9,8,7,7,7,6,7,6,6,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,8,8,10,8,8,8,7,7,7,8,7,9,9,7,8,8,7,8,7,7,7,6,7,7,6,6,6,6,6,6,5,4,4,3,4,4,3,3,4,4,3,3,4,4,4,4,5,6,6,6,6,6,6,4,5,5,5,5,5,6,5,5,5,6,4,4,5,5,4,4,5,4,4,5,5,5,5,6,6,5,5,6,6,5,6,6,5,6,6,6,7,8,8,8,7,6,7,6,7,7,8,8,8,9,10,10,10,10,10,10,11,10,11,10,9,9,10,9,8,9,9,8,7,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,6,5,4,4,5,4,4,4,4,4,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,6,5,5,5,5,5,6,6,5,6,6,6,6,6,7,7,8,8,8,8,9,10,10,10,11,10,11,11,11,11,11,11,12,12,12,11,12,12,12,12,11,11,11,11,11,10,10,9,9,8,8,8,8,7,7,7,7,6,6,7,5,6,6,5,5,4,4,4,4,3,4,3,2,2,2,3,3,3,4,4,4,3,4,5,5,5,5,5,6,5,5,6,6,6,7,7,7,6,6,6,6,6,5,6,6,5,5,5,5,5,4,4,4,3,4,4,5,5,6,5,5,6,6,6,6,6,6,6,6,6,7,6,6,6,7,6,5,5,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,2,2,1,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,4,4,5,6,7,8,10,10,11,11,12,14,13,16,17,16,18,20,18,16,20,20,17,22,17,22,21,19,26,23,21,24,25,22,24,25,24,21,22,25,21,18,20,23,22,18,23,21,19,23,23,18,20,22,21],[28,28,28,27,28,28,27,27,27,26,26,25,26,25,25,25,26,26,26,26,27,26,26,28,27,26,28,27,27,28,26,27,28,28,27,28,27,28,28,28,28,27,27,27,27,27,25,25,25,24,23,23,23,21,20,21,20,19,18,18,16,14,13,11,10,9,8,8,7,7,7,6,6,5,6,6,7,7,8,7,6,7,7,6,7,8,8,8,8,8,9,10,9,10,10,10,9,10,11,11,11,12,12,12,12,13,13,12,13,13,13,13,12,12,12,12,12,12,11,11,12,11,10,11,11,10,10,11,10,9,10,10,8,9,9,10,10,10,10,10,10,9,10,10,9,9,10,9,8,9,10,8,8,8,10,10,10,10,10,10,10,9,10,10,9,8,9,10,8,8,9,9,8,8,9,8,7,8,8,7,8,7,7,8,7,6,7,8,7,6,7,7,6,7,8,8,9,9,8,8,9,9,8,9,9,8,8,8,8,8,9,8,7,8,8,7,7,8,7,6,7,7,7,6,7,7,6,6,7,7,6,7,7,8,8,9,9,9,8,9,8,8,8,8,7,7,7,7,6,6,6,6,5,5,6,6,7,6,6,5,5,5,5,5,5,5,4,5,6,5,5,6,6,5,5,6,6,7,7,7,6,7,6,6,6,6,6,6,6,6,5,5,5,5,5,6,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,6,7,6,7,7,7,8,8,8,9,10,10,11,12,14,15,14,14,16,17,16,18,19,19,19,20,22,22,22,24,24,25,23,25,22,22,23,21,21,21,23,23,21,23,23,25,25,27,26,26,26,27,27,27,27,27,27,27,28,27,28,28,28,27,27,27,27,28,27,27,26,26,27,26,27,26,26,27,26,25,25,24,23,23,23,22,21,20,18,17,15,14,12,11,9,8,7,7,6,6,6,5,5,4,5,4,4,6,5,5,7,7,6,7,8,8,7,8,8,8,8,8,9,8,7,7,7,7,7,7,8,8,9,8,8,8,7,7,8,7,6,6,7,7,7,6,6,6,5,5,4,4,4,3,3,4,3,3,3,4,3,3,4,4,4,4,5,5,6,6,6,6,6,5,5,4,5,5,4,5,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,4,5,5,5,5,5,5,6,6,6,5,6,6,6,7,8,8,8,7,7,6,6,6,7,8,7,7,9,9,9,10,10,10,10,11,10,11,10,9,10,9,9,9,8,8,8,7,6,7,7,6,6,6,6,5,5,5,5,5,5,4,5,4,4,4,4,4,3,3,4,4,3,3,2,3,3,2,2,3,2,2,3,3,3,3,4,4,4,4,5,5,4,5,5,5,5,6,6,6,6,6,6,7,6,7,8,7,8,7,9,9,10,9,8,8,9,9,10,10,10,11,11,12,11,11,11,11,10,11,10,10,10,10,9,9,9,8,8,7,7,6,6,6,6,6,6,6,6,5,5,5,4,4,4,4,3,3,3,3,3,2,2,2,3,3,3,4,4,3,4,4,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,3,4,4,4,5,4,4,6,5,4,5,6,6,6,6,5,5,5,6,5,5,6,6,5,5,5,5,5,5,4,4,4,5,5,5,4,4,5,4,4,4,4,4,3,6,1,1,0,1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,4,5,6,8,8,10,11,11,11,12,14,12,15,16,17,20,20,17,16,21,20,18,22,17,20,21,18,24,22,20,23,24,22,23,25,23,22,22,24,22,19,19,23,21,18,22,20,19,22,23,18,17,21,20],[28,28,28,28,28,27,27,27,27,27,25,25,26,24,26,24,26,25,26,26,27,26,27,28,26,27,28,27,28,28,26,28,28,28,28,28,28,28,29,28,28,27,27,27,27,27,26,25,25,25,24,23,23,22,21,21,20,20,18,19,16,14,12,10,9,8,7,7,7,7,6,6,6,6,6,7,7,7,8,7,6,7,7,6,6,7,8,8,8,8,8,9,8,9,9,9,9,9,10,9,10,10,10,10,10,11,11,11,11,11,12,11,10,10,10,10,10,10,9,10,10,9,8,10,10,9,9,9,9,8,9,9,8,8,8,8,9,8,9,8,8,8,9,9,8,8,9,8,9,8,9,8,8,8,9,9,9,9,9,9,9,9,9,9,8,9,8,9,9,8,8,8,8,8,8,8,7,7,8,7,7,7,6,7,7,6,6,7,6,6,7,6,6,6,7,7,8,8,7,8,8,8,7,8,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,6,6,7,7,6,6,7,7,6,7,7,8,8,8,9,8,8,8,8,7,7,8,7,6,6,6,6,6,5,6,6,5,5,6,7,6,5,5,5,5,5,5,5,5,5,5,6,5,5,5,6,5,5,5,6,6,6,7,6,7,6,6,6,6,5,6,6,5,5,5,5,6,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,7,7,8,8,7,9,10,10,11,11,14,14,14,14,17,16,16,18,19,18,19,20,22,23,22,24,24,26,24,25,21,23,23,22,22,22,22,23,22,23,23,25,25,27,25,27,26,27,27,27,27,26,27,27,27,27,28,28,28,27,27,27,27,28,27,27,26,27,27,26,27,27,26,27,26,25,26,25,23,24,24,22,23,20,20,19,16,14,11,10,8,7,6,6,6,6,6,5,5,5,5,5,4,5,5,5,5,6,6,6,6,7,7,6,7,8,7,8,7,7,7,7,7,6,6,7,7,8,9,7,7,8,7,7,7,6,6,6,6,6,6,5,5,6,5,5,4,4,4,4,3,4,3,3,3,4,3,3,4,4,4,4,5,5,6,6,6,6,6,4,4,4,5,4,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,7,8,8,7,7,6,5,6,6,7,7,7,7,8,8,8,9,9,9,9,9,9,9,9,8,9,9,8,7,7,8,7,7,7,7,6,6,6,5,5,5,6,5,5,5,5,4,4,4,4,3,3,4,4,3,3,4,4,3,3,3,3,2,2,3,3,2,3,3,3,3,3,3,3,3,3,4,4,4,4,5,4,5,5,5,5,6,6,6,7,6,7,7,7,7,8,9,9,9,9,8,8,9,9,9,9,9,10,10,10,10,10,10,9,10,9,9,9,9,9,9,8,8,8,7,7,6,7,7,6,6,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,5,6,5,5,4,4,4,4,4,4,4,4,3,4,4,3,4,4,5,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,4,4,4,5,5,4,4,4,4,4,3,3,3,3,2,2,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,5,6,8,8,10,10,11,11,11,15,14,15,17,17,19,19,18,17,19,20,18,22,17,20,21,18,24,22,22,22,24,21,23,25,23,23,23,24,23,20,21,24,23,20,23,21,21,22,24,20,19,22,22],[28,28,27,28,28,26,27,26,26,27,24,24,26,22,25,24,25,24,26,26,26,27,27,28,26,27,28,26,28,27,26,28,28,28,27,28,27,28,28,27,28,27,27,27,27,27,26,24,24,24,23,22,22,21,20,20,19,18,16,18,16,13,12,9,8,8,7,6,7,6,6,5,5,5,6,5,6,7,7,6,6,7,6,6,7,7,7,7,7,7,8,8,8,8,9,8,8,8,9,8,9,10,9,9,10,11,11,10,10,12,12,11,9,10,10,10,9,10,10,10,10,9,8,9,9,9,8,9,8,7,8,8,7,7,8,8,8,8,7,8,8,7,8,8,8,7,8,8,7,8,9,7,8,8,9,9,9,9,8,10,9,8,9,9,8,8,8,9,8,8,8,8,7,8,8,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,7,8,7,6,7,7,7,7,8,7,7,7,6,6,7,7,6,6,7,7,6,6,7,7,6,6,7,6,6,7,7,6,6,7,7,6,7,7,8,8,8,8,7,8,7,8,7,7,7,7,6,6,6,6,6,5,5,5,5,5,6,6,6,5,4,5,5,5,4,5,5,4,5,5,5,4,5,5,4,5,5,5,5,5,5,6,6,5,5,5,5,5,6,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,4,5,5,5,5,5,6,6,6,5,6,6,6,6,6,7,7,7,8,8,8,11,10,12,13,14,14,12,14,16,16,15,16,18,17,17,18,21,21,20,22,22,23,22,24,22,21,21,21,19,20,21,22,20,20,22,23,25,26,25,25,25,26,26,26,26,26,26,26,26,27,27,27,27,27,27,26,27,27,26,27,25,27,27,26,27,26,25,27,25,26,26,25,24,23,22,23,21,21,19,18,16,15,12,10,9,7,6,6,6,6,6,5,5,4,4,5,5,5,5,5,5,6,6,6,6,7,7,6,7,7,7,7,7,7,7,7,6,7,6,7,7,7,8,8,7,8,7,7,6,7,6,6,6,6,6,6,6,5,5,5,4,4,4,3,3,3,3,3,3,3,2,3,3,3,3,3,4,4,5,5,6,5,5,4,4,4,4,4,4,5,4,3,4,4,3,3,4,3,3,3,3,3,3,3,4,3,3,4,4,4,4,5,4,4,4,5,4,5,5,5,6,7,8,7,6,5,5,5,6,6,6,6,6,7,8,8,8,10,8,9,9,9,8,8,7,8,7,7,7,7,7,6,6,6,6,5,5,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3,3,3,3,3,4,3,3,3,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,8,8,8,7,8,9,8,8,9,9,9,9,9,10,9,9,10,9,9,9,8,8,9,8,8,8,7,7,6,5,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,4,5,5,5,4,5,5,5,4,5,4,5,5,5,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,1,1,1,1,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,5,5,7,8,9,10,11,11,10,14,12,15,17,17,19,20,18,16,19,22,19,22,17,21,20,19,25,22,22,24,26,22,24,25,24,21,22,24,22,20,19,24,23,19,24,21,20,22,24,20,19,23,22],[28,28,27,27,28,27,28,27,26,26,25,25,27,24,26,25,26,27,26,26,27,26,26,27,27,27,27,26,27,27,26,27,28,28,27,28,27,27,27,27,28,27,26,27,27,26,26,24,24,24,23,21,22,22,19,19,19,19,17,17,15,13,11,9,8,7,7,6,6,6,5,4,4,4,5,5,5,6,6,5,5,6,5,5,6,6,6,6,6,7,7,7,7,8,8,8,7,8,8,8,9,9,9,8,9,10,9,10,10,10,10,10,9,9,9,9,9,8,8,8,9,8,7,8,8,8,7,8,8,6,7,7,6,7,7,7,7,7,7,7,7,7,8,7,7,7,8,7,7,7,8,6,7,7,7,8,8,8,8,8,8,7,7,7,7,7,7,7,7,6,7,7,6,6,7,7,6,6,6,6,6,6,5,6,6,5,6,6,5,5,6,6,5,5,6,7,7,7,6,7,7,7,7,7,7,6,6,7,6,7,7,6,6,6,7,6,6,6,6,5,6,6,5,5,6,6,4,5,5,5,4,5,5,6,6,7,7,7,6,6,6,5,6,6,5,5,5,5,4,4,4,4,4,4,4,5,6,5,4,4,4,4,4,3,4,4,3,4,5,4,4,4,5,4,4,4,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,4,4,3,4,4,4,3,4,4,4,4,4,3,4,3,3,3,4,3,3,3,3,3,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,6,6,6,6,6,8,10,10,11,12,14,14,13,13,15,16,15,15,17,18,17,18,20,22,20,22,22,23,22,23,21,20,20,20,19,20,22,22,21,22,23,24,25,26,26,26,26,27,27,27,27,26,27,27,27,27,28,28,27,26,27,27,27,27,26,27,25,27,27,25,26,26,25,26,25,25,25,24,22,22,22,21,19,19,17,17,14,12,11,9,7,7,6,5,5,5,5,4,4,4,4,4,4,5,5,5,6,6,6,6,6,7,7,7,8,7,7,7,8,7,7,7,6,5,6,6,6,7,8,7,7,7,6,6,6,6,5,5,5,5,5,4,5,4,4,4,3,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,4,4,5,5,5,6,5,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,5,5,7,6,6,5,5,5,5,5,5,6,6,6,6,7,7,7,8,8,8,8,8,8,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,7,7,8,7,7,7,7,7,8,8,8,8,8,9,8,9,9,9,8,8,8,8,8,8,7,7,7,6,6,6,5,5,5,4,4,4,4,4,4,3,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,4,4,5,4,4,5,5,4,4,4,4,3,4,4,4,4,3,4,4,4,4,4,4,3,3,3,3,3,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,3,4,5,7,8,9,10,10,11,11,13,12,15,16,15,18,18,17,16,20,19,15,22,16,21,20,20,24,23,22,22,24,23,23,24,24,23,22,25,23,20,19,24,24,20,23,20,19,22,24,20,19,23,21],[28,29,28,28,28,28,28,28,28,27,27,27,26,26,26,26,26,27,27,27,27,27,27,28,27,27,28,28,28,28,26,28,28,29,28,28,28,28,28,28,28,28,27,27,27,27,26,25,25,24,23,23,23,21,20,21,20,19,18,18,16,14,11,9,8,7,6,6,6,5,5,4,4,4,4,4,5,5,5,5,4,5,5,4,4,5,5,6,6,6,6,7,6,6,7,7,6,7,8,7,7,8,8,7,8,8,9,8,9,9,10,9,8,8,8,9,8,8,7,8,8,7,6,7,7,6,6,7,6,6,6,6,6,6,7,7,7,6,6,7,6,6,7,6,6,6,6,6,6,6,6,6,5,6,7,6,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,5,5,6,5,5,5,6,5,5,4,4,5,4,4,4,5,4,4,4,4,4,4,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,5,5,4,4,5,4,4,4,5,4,4,5,5,6,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,4,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,3,4,3,3,3,3,3,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,4,5,5,5,5,5,5,5,6,6,6,7,9,10,10,12,14,14,13,14,16,16,15,17,18,18,18,20,22,22,21,23,24,23,23,24,22,23,23,21,21,22,23,23,22,22,23,25,26,27,26,26,27,27,27,27,27,27,27,27,27,27,28,28,28,27,27,27,27,28,27,27,26,26,27,27,27,27,26,27,26,24,25,25,23,24,22,21,21,19,17,17,15,13,11,9,7,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,6,6,7,6,6,6,5,5,5,6,6,6,7,6,6,7,6,6,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,6,6,6,5,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,6,6,6,5,5,4,4,4,5,5,5,5,6,6,7,7,6,7,7,8,7,7,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,7,6,6,6,6,6,7,7,7,7,8,8,8,8,7,8,8,8,8,7,7,8,7,7,7,6,6,5,5,4,4,4,4,4,3,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,3,4,4,4,4,3,4,4,4,3,3,3,3,3,2,2,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,2,4,5,8,7,9,10,11,10,10,13,12,14,16,15,19,19,17,16,19,19,17,21,17,21,21,21,24,24,21,22,24,23,24,24,24,22,21,24,23,20,19,23,23,20,23,21,21,21,24,20,18,22,22],[29,29,28,28,28,27,28,27,26,27,26,25,26,24,26,24,27,26,26,27,27,26,28,28,26,28,28,28,28,28,26,28,29,29,28,29,28,28,29,28,29,28,28,28,27,27,26,25,26,25,23,23,23,22,20,20,20,18,17,17,15,12,11,9,7,7,6,6,6,5,5,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,7,6,7,7,7,7,7,7,7,7,7,8,8,8,8,9,9,8,7,7,7,8,7,8,7,7,7,7,6,7,7,7,6,7,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,6,7,7,7,7,7,7,7,6,6,7,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,6,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,5,4,4,3,4,4,4,3,4,4,3,4,4,4,3,4,4,4,3,4,4,4,5,5,4,5,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,4,4,3,4,4,3,4,3,4,4,4,5,5,4,4,5,5,5,5,5,5,5,6,6,6,8,9,8,11,11,14,14,13,13,16,16,15,17,18,18,17,18,20,21,20,22,23,24,22,24,21,22,22,20,20,20,22,22,21,21,24,24,25,26,25,26,26,27,27,26,27,27,27,27,27,27,27,28,28,27,27,27,28,27,27,27,26,26,28,26,27,27,26,27,26,26,26,24,24,24,22,22,20,20,18,17,15,14,11,9,7,6,5,5,4,5,4,4,4,3,3,4,4,4,4,4,5,5,5,5,6,6,6,6,6,7,6,7,6,6,6,6,5,5,6,6,6,7,7,6,6,6,6,6,6,6,5,5,5,5,4,4,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,5,6,6,6,5,3,3,3,3,3,3,3,3,2,3,3,2,2,3,3,2,2,3,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,7,6,6,5,5,4,5,4,5,6,5,6,6,6,6,7,7,7,7,7,7,7,7,6,7,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,7,6,6,6,6,6,7,7,7,7,8,8,8,8,7,8,7,8,7,7,7,7,7,7,7,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,3,3,3,3,4,4,3,4,3,4,4,4,4,3,4,4,3,3,3,3,3,2,2,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,2,4,6,7,8,8,10,11,10,10,13,13,14,16,15,18,18,16,14,19,18,17,21,18,20,21,19,24,23,21,23,24,22,23,24,24,20,22,24,24,21,19,24,24,21,24,21,21,22,24,20,19,23,22],[27,27,25,27,27,25,27,27,25,25,24,24,25,23,25,24,26,25,26,26,26,26,26,26,26,26,26,26,27,26,25,27,27,28,26,27,26,27,27,27,27,26,25,26,26,25,25,23,23,23,22,21,21,21,18,19,18,17,16,16,14,12,11,8,8,7,6,6,6,5,5,4,4,4,4,5,5,6,6,5,5,5,5,5,5,5,5,6,6,6,6,7,6,7,7,6,6,7,7,6,7,7,7,7,8,8,8,8,8,9,9,8,8,8,8,8,7,7,7,7,8,7,6,7,7,7,7,7,6,6,6,6,6,6,6,7,6,6,6,6,6,6,7,6,6,6,7,6,6,6,7,6,6,6,6,7,7,8,7,7,7,6,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,5,5,5,5,4,5,5,5,6,6,5,6,6,6,5,6,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,4,5,5,5,4,5,5,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,4,4,4,4,3,4,4,4,5,5,4,3,3,4,3,3,4,3,3,3,4,3,3,4,4,3,3,4,4,4,4,5,5,5,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,4,3,4,4,3,4,4,3,3,4,3,3,3,4,3,3,4,3,4,4,4,4,5,4,4,4,5,5,5,5,5,5,6,6,7,8,9,8,10,11,12,13,12,11,13,14,14,14,16,17,16,17,19,20,20,21,21,22,21,22,19,20,20,19,18,18,20,20,18,19,22,23,23,25,24,24,25,25,25,25,25,25,25,25,25,26,26,27,26,26,26,26,26,27,25,26,23,25,25,24,26,25,24,25,25,24,23,23,22,22,21,19,19,18,17,16,14,12,11,9,8,7,5,5,5,5,5,4,4,4,3,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,6,6,6,7,6,6,7,6,6,5,6,5,5,5,5,5,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,5,5,5,4,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,6,6,6,5,4,4,4,4,5,5,5,5,5,6,6,7,7,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,5,4,5,5,5,5,5,5,5,6,6,7,6,6,6,7,7,7,7,7,7,8,8,8,8,7,8,7,8,7,7,7,8,7,7,7,6,6,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,4,5,5,4,4,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,3,3,3,3,3,3,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,2,4,6,6,7,7,10,8,8,10,11,11,14,15,13,17,17,15,14,17,19,16,21,16,20,19,17,24,22,19,21,23,20,22,24,23,19,21,24,21,18,20,22,23,18,23,20,20,21,23,19,18,22,20],[28,28,28,28,28,28,28,27,27,26,26,26,26,26,26,26,26,27,27,26,27,27,26,27,27,27,27,27,27,27,26,27,28,28,27,27,27,27,28,27,28,27,27,27,26,26,26,24,25,23,23,22,22,21,20,20,20,18,17,17,15,13,10,8,7,6,5,5,5,4,4,4,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,6,7,8,7,7,8,9,9,8,7,7,7,7,7,6,6,6,7,6,6,6,6,6,5,6,6,5,6,5,5,5,6,6,5,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,5,5,6,6,6,7,6,7,6,6,6,6,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,4,4,4,4,4,4,3,4,4,4,4,4,4,3,4,5,5,5,5,5,5,5,6,5,5,6,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,4,3,4,4,4,3,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,4,4,4,4,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,7,8,8,10,11,12,13,12,12,15,15,15,16,18,17,18,19,21,21,21,22,21,23,21,23,21,21,21,20,18,20,21,22,19,20,22,23,25,27,25,25,26,26,26,27,26,26,26,26,26,27,27,27,27,27,27,26,26,27,26,26,24,26,25,25,26,25,25,26,24,24,24,24,22,21,20,20,19,19,16,15,13,12,10,9,7,6,5,5,4,4,4,3,4,3,3,3,4,4,4,4,5,5,5,5,5,6,5,6,6,7,6,7,6,6,6,6,5,5,5,6,5,6,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,5,5,5,4,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,5,6,6,5,5,4,4,4,4,4,4,4,5,5,6,6,6,6,6,6,7,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,6,7,7,6,6,6,5,5,5,4,4,4,3,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,4,4,4,3,4,4,4,4,3,4,4,3,3,3,3,3,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,2,4,5,6,6,7,9,10,9,10,11,12,14,15,15,18,18,16,16,19,18,16,20,17,20,20,20,23,23,21,22,23,22,23,24,24,22,21,23,23,20,19,22,23,18,22,19,20,22,23,20,20,22,21],[29,29,28,28,28,28,28,28,27,27,27,26,27,26,27,26,27,28,27,27,28,28,28,28,28,28,28,28,28,28,27,28,29,29,28,28,28,28,29,28,29,28,28,27,27,27,25,24,25,24,24,23,24,21,22,21,20,20,19,19,16,14,12,9,8,7,6,6,5,5,4,4,4,3,4,4,4,5,5,5,4,5,5,4,4,5,5,5,5,5,6,6,5,6,6,6,6,6,7,6,6,7,7,6,7,7,8,7,7,9,8,8,7,6,6,7,7,7,7,6,7,6,6,6,6,6,5,6,6,5,6,6,5,5,6,6,6,5,6,6,5,5,6,6,5,5,6,5,5,6,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,4,5,5,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,5,5,5,5,5,6,6,5,6,6,6,6,5,5,6,6,5,4,5,4,4,4,5,4,3,4,4,3,4,4,4,3,4,4,4,3,4,4,5,6,6,5,6,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,3,2,3,3,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,8,9,10,11,12,14,15,14,15,17,16,16,18,19,19,19,20,22,23,21,22,23,24,24,24,22,23,23,21,22,22,23,24,23,23,24,26,27,28,26,27,27,27,27,27,27,27,27,27,28,27,28,28,28,28,27,28,28,28,27,28,27,27,28,26,27,27,26,27,26,25,25,25,24,23,22,21,22,19,18,17,16,13,12,9,8,6,5,5,4,4,4,4,3,3,3,4,4,4,4,4,4,5,5,5,5,6,5,5,6,7,6,6,6,6,5,5,5,5,5,5,5,7,7,6,6,7,6,5,5,5,5,4,5,5,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,4,4,5,6,5,4,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,4,4,4,4,5,5,6,6,7,5,4,4,4,4,4,5,4,5,5,6,6,7,6,7,7,7,7,7,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,4,4,4,4,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,8,7,8,7,8,7,7,7,7,7,7,7,6,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,5,4,4,4,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,5,4,4,5,5,4,5,5,4,4,5,5,4,4,4,4,4,3,4,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,2,3,5,7,7,7,10,10,10,10,12,13,14,16,16,19,18,17,16,19,19,17,20,17,21,20,20,24,24,21,22,23,23,24,23,24,22,22,23,24,20,20,24,23,21,22,21,21,22,23,20,19,22,22],[28,28,26,27,28,26,28,27,26,26,25,24,26,24,26,24,26,26,25,27,26,27,27,27,26,27,28,27,28,27,26,28,28,28,28,28,27,28,29,28,28,27,26,26,26,26,25,23,24,24,22,21,22,21,19,20,19,18,17,16,14,13,11,9,8,7,6,6,6,5,5,4,4,4,4,4,5,5,5,5,5,5,5,4,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,6,7,7,7,7,7,8,8,7,8,9,9,8,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,6,6,5,6,6,6,5,6,6,6,6,6,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,4,5,5,5,4,5,5,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,3,4,4,4,5,4,4,3,3,4,3,3,3,4,3,4,4,3,3,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,4,4,4,3,3,4,4,3,4,4,3,3,4,4,3,4,4,3,3,4,3,3,4,4,3,3,4,3,3,4,3,4,4,4,4,5,4,4,4,5,5,5,5,5,6,6,6,6,8,9,9,10,11,12,14,12,13,15,15,15,16,17,17,17,17,20,21,20,21,22,24,22,24,21,21,21,20,19,19,22,21,19,20,22,24,24,26,24,25,25,26,26,26,26,25,26,26,26,26,26,27,26,26,26,26,26,27,25,26,25,25,26,25,26,26,26,26,25,24,24,24,23,21,23,20,19,19,17,17,15,13,12,9,8,6,5,5,5,5,4,4,4,4,4,3,4,4,4,4,5,5,5,5,6,7,7,6,7,7,6,7,6,6,5,5,5,5,6,6,6,7,7,6,6,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,5,6,5,4,3,3,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,6,7,6,5,5,4,4,5,5,5,5,5,6,6,6,7,7,7,7,7,7,7,7,6,6,6,6,5,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,3,3,3,3,3,2,3,3,2,2,2,2,2,2,1,2,2,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,8,7,8,7,7,7,8,7,7,7,7,7,7,7,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,4,4,4,4,4,4,3,4,4,3,3,4,3,3,3,3,3,3,4,4,4,4,5,4,5,5,4,5,5,4,4,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,2,3,5,7,6,7,9,9,9,9,12,13,14,16,14,18,18,16,15,19,19,16,22,19,19,18,18,23,21,20,20,23,21,22,24,24,21,21,24,22,20,21,24,24,21,24,21,21,22,24,21,19,23,22],[28,28,27,27,27,26,28,27,26,26,25,25,26,25,26,25,26,26,27,26,27,27,26,26,27,27,27,27,27,27,26,27,27,28,27,27,26,27,27,27,27,26,26,26,25,25,24,22,23,22,21,21,21,20,17,19,18,18,16,16,15,12,11,9,8,7,6,6,6,5,5,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,5,6,6,6,6,6,7,6,6,6,7,6,7,7,7,7,7,8,8,7,8,9,9,8,7,7,7,8,7,7,7,6,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,5,6,6,5,6,6,6,6,6,6,7,7,7,7,7,7,6,6,7,6,6,6,6,6,5,6,6,6,5,6,5,5,5,5,5,5,4,4,5,5,4,5,5,4,4,5,5,4,5,5,6,6,6,5,6,6,6,6,6,6,5,5,5,5,6,6,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,4,4,5,5,5,6,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,5,5,4,3,3,4,3,3,4,4,3,4,4,3,3,4,4,3,3,4,4,4,4,5,5,4,4,4,4,4,4,4,4,3,3,4,4,3,3,4,3,3,3,4,3,4,4,3,4,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,4,5,4,5,5,5,5,5,6,6,6,7,8,9,10,10,11,12,13,12,13,14,15,14,15,16,16,16,17,19,19,19,20,21,22,21,22,20,19,21,20,19,19,20,20,18,20,22,23,24,26,24,24,25,24,25,25,25,25,26,26,26,26,26,26,26,26,26,26,27,26,25,26,23,25,26,25,26,26,25,25,24,24,23,23,21,22,21,20,19,18,17,15,14,12,11,9,7,7,5,5,5,5,5,4,4,4,4,4,5,5,5,4,5,5,5,6,6,6,6,6,7,7,7,7,6,6,6,6,5,5,6,6,6,7,8,6,6,6,6,6,6,6,6,5,5,5,5,5,5,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,4,5,4,4,3,3,2,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,2,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,6,6,6,5,5,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,7,7,6,6,6,6,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,7,6,6,6,6,6,7,7,7,7,8,8,8,8,7,8,8,8,8,7,8,8,7,7,7,6,6,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,3,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,5,4,4,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,3,5,7,7,7,9,9,8,9,10,11,13,13,15,19,20,17,15,20,20,16,22,18,22,20,21,25,22,21,22,24,23,22,24,24,20,21,24,22,17,19,22,23,19,22,20,19,22,23,19,18,21,20],[28,28,28,28,28,28,27,27,28,26,26,27,26,26,26,26,26,27,27,26,27,27,26,27,27,27,27,27,27,27,26,26,27,28,27,27,27,26,27,27,27,26,26,26,26,25,24,24,24,23,23,22,22,20,19,20,19,19,17,18,15,13,11,9,7,6,5,5,5,4,4,4,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,5,5,5,5,5,5,5,5,6,5,5,6,6,6,6,6,6,6,6,8,8,6,6,6,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,4,5,5,4,4,5,4,4,5,5,4,4,4,5,5,5,6,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,4,4,4,4,4,3,3,4,3,3,3,4,3,3,3,4,3,3,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,3,4,4,3,3,4,4,3,3,4,3,3,3,4,3,3,4,4,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,3,4,4,3,3,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,3,3,3,3,3,2,3,2,2,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,6,5,6,8,9,9,10,12,12,15,13,13,15,16,15,17,18,17,18,18,20,22,21,22,22,23,22,23,21,20,22,20,21,22,21,22,21,21,22,25,25,28,25,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,26,27,25,25,27,26,27,27,25,26,24,23,23,23,22,22,21,20,19,17,16,15,14,12,10,9,7,6,5,5,4,4,4,4,3,3,3,3,4,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,6,6,5,5,5,5,5,5,5,6,7,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,3,3,4,4,4,4,3,2,2,2,2,2,2,2,2,1,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,5,6,6,6,5,4,4,4,3,4,4,4,4,4,5,5,5,5,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,6,6,7,7,7,6,7,7,7,7,6,7,7,6,6,6,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,2,3,4,7,6,7,9,9,8,9,10,11,13,15,16,19,19,17,15,19,18,16,20,17,20,20,20,23,23,21,21,22,22,23,23,23,20,22,23,22,19,19,23,22,19,22,21,21,22,23,20,19,22,21],[28,28,28,28,28,27,28,27,27,27,26,26,26,25,27,25,27,27,26,26,27,27,26,27,27,27,27,27,27,27,26,27,28,28,27,27,27,27,27,27,27,26,26,26,25,25,24,23,24,24,23,22,22,21,19,20,19,19,18,17,15,14,11,8,8,7,5,5,5,5,4,4,4,3,4,4,4,4,4,4,4,4,5,4,4,4,5,5,5,5,5,6,5,6,6,5,6,6,6,6,6,6,6,6,6,6,7,6,7,7,7,7,6,6,6,6,6,6,6,6,6,5,5,5,6,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,5,5,6,5,5,5,5,5,4,5,5,4,4,5,4,4,4,4,4,4,4,3,4,4,3,4,4,3,3,4,4,3,3,4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,4,4,4,4,4,3,4,4,3,4,4,4,3,4,4,4,3,4,4,5,5,5,5,5,5,5,5,4,4,4,4,3,4,3,3,3,3,3,3,3,3,4,4,4,3,3,3,3,2,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,4,4,3,4,3,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,6,6,6,7,8,9,10,11,12,13,13,13,15,15,15,16,17,17,17,17,20,21,20,22,22,23,22,23,21,21,22,20,20,21,21,23,21,21,22,24,24,27,24,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,26,26,25,25,26,26,26,26,25,27,24,24,25,24,23,22,22,20,19,19,17,16,14,13,11,9,7,6,5,5,4,4,4,3,3,3,3,3,3,4,4,4,4,5,4,5,5,6,6,5,6,6,6,6,6,5,5,5,4,4,5,5,5,7,7,6,6,6,6,5,5,5,5,4,5,4,4,4,4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,4,4,5,5,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,3,4,4,4,5,6,6,6,5,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,2,2,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,5,5,5,6,6,6,6,6,7,7,7,7,6,7,6,7,7,6,7,7,7,6,6,5,5,5,5,4,4,4,4,4,3,4,3,3,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,3,3,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,4,4,5,4,4,4,4,4,4,4,4,3,4,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,2,3,4,6,6,7,8,9,10,9,11,13,14,16,16,17,18,16,15,18,19,17,20,18,21,21,19,23,23,22,21,22,22,25,24,22,22,22,22,23,20,20,24,22,20,21,21,21,23,22,21,18,22,22],[28,28,27,28,28,27,28,27,26,27,25,26,27,25,26,26,26,27,26,26,27,27,26,27,26,27,27,27,27,27,26,27,27,28,26,27,26,27,28,27,27,26,25,26,26,25,25,24,24,23,23,22,22,21,19,20,20,18,17,18,15,14,12,10,9,8,7,7,6,6,5,5,5,4,5,5,5,6,6,5,5,6,5,5,6,6,5,6,6,6,7,7,6,7,7,7,6,7,7,6,7,8,7,7,7,8,8,8,8,9,9,8,8,8,7,8,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,6,6,6,6,7,6,6,6,6,7,6,7,7,6,6,6,7,6,6,7,6,6,6,7,7,7,7,7,8,7,7,7,7,7,6,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,5,4,5,5,4,4,5,6,6,6,5,6,6,6,6,7,6,6,6,6,6,6,6,5,5,6,5,5,5,6,5,5,5,6,5,5,5,6,4,5,5,5,4,5,6,6,7,7,6,6,7,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,4,5,4,4,3,3,4,3,3,4,4,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,4,5,5,4,4,4,4,3,4,4,4,3,4,4,3,3,4,4,4,4,4,3,4,4,4,3,4,4,3,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,5,6,6,6,7,7,7,8,10,10,11,12,13,14,13,13,15,16,17,17,18,18,19,19,21,22,21,23,22,23,23,24,21,21,21,20,20,20,21,21,19,21,23,24,24,26,24,25,25,25,26,26,26,26,26,25,26,26,26,26,26,26,26,27,26,26,25,26,25,25,26,25,26,26,25,26,25,25,25,24,23,22,22,20,20,19,17,17,15,13,12,10,8,8,7,6,6,5,5,4,5,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,8,8,7,8,7,7,6,6,6,6,6,7,7,8,9,8,8,8,8,7,6,7,6,6,6,6,5,5,5,5,4,4,4,3,3,3,3,3,2,2,2,2,2,2,3,2,3,3,3,4,4,5,5,5,4,3,3,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,6,7,7,7,6,5,4,4,5,5,5,6,6,6,7,7,7,7,7,8,8,8,8,7,7,7,7,6,6,6,6,5,5,5,5,5,4,5,4,4,4,4,3,3,3,3,3,3,3,3,2,3,3,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,5,6,6,6,6,7,7,7,6,7,7,7,7,7,7,8,8,8,8,9,8,9,8,9,8,8,8,8,8,7,8,7,6,6,5,5,5,4,5,4,4,4,4,4,4,4,4,3,3,3,3,2,3,3,3,3,3,3,3,3,4,3,4,4,4,4,4,4,5,5,4,4,5,5,5,5,6,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,6,6,6,5,6,6,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,0,1,1,1,2,3,5,8,6,7,8,8,8,8,11,13,15,15,15,20,21,17,14,22,21,18,22,17,21,21,21,25,23,21,22,23,21,22,24,24,21,23,23,23,19,21,22,23,20,23,21,22,23,24,21,20,24,23],[28,28,27,27,27,27,27,27,26,26,26,26,26,26,25,26,25,26,26,26,26,26,26,27,26,26,26,27,27,26,26,26,27,27,26,26,26,26,27,26,27,26,26,25,25,25,24,23,24,23,23,22,22,22,19,20,19,19,18,18,16,14,12,10,9,8,7,7,7,6,6,5,5,4,5,5,5,6,6,6,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,9,9,8,7,7,7,8,7,7,7,7,7,7,6,7,7,7,6,7,7,6,6,6,6,7,6,7,6,7,6,6,7,6,6,7,6,6,6,6,6,7,7,6,6,6,7,7,7,8,7,8,7,7,7,7,7,6,6,6,6,6,6,6,6,5,6,6,5,5,6,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,6,6,6,6,6,7,7,6,6,7,6,7,7,6,7,7,6,6,6,6,5,5,6,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,6,6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,4,4,3,3,4,4,5,5,4,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,4,3,4,4,3,3,3,4,4,4,4,4,4,4,3,3,4,3,4,4,4,4,4,4,4,4,4,5,5,5,5,6,5,6,6,6,6,6,6,7,7,8,9,10,10,11,12,13,14,14,13,16,17,15,17,18,18,18,18,19,21,20,21,22,22,22,23,21,20,21,20,20,20,20,21,21,21,23,23,24,25,24,25,26,26,26,26,26,27,27,27,27,26,27,26,27,26,27,26,27,27,26,26,24,24,26,25,26,26,25,26,24,23,23,23,23,22,21,20,19,19,17,16,14,13,11,9,8,8,6,6,5,6,5,5,5,5,5,5,5,6,6,6,6,7,6,6,7,8,7,7,8,8,8,7,7,7,6,6,6,6,6,7,7,8,8,8,7,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,4,3,3,3,3,3,3,3,3,2,3,2,3,2,3,3,3,4,4,5,5,5,4,4,3,2,3,2,3,3,2,2,2,2,2,2,2,2,2,2,3,2,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,8,7,7,6,6,5,5,5,6,6,6,6,6,7,8,7,7,7,8,9,8,8,8,7,7,7,7,6,6,6,6,6,5,6,5,5,5,5,4,4,4,4,4,4,3,3,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,8,7,7,7,7,7,7,7,7,8,9,9,9,9,8,9,9,9,9,8,9,9,8,8,8,7,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,3,4,4,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,5,6,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,5,5,5,5,5,5,5,5,5,5,5,6,5,6,5,6,5,5,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,1,1,1,1,1,0,1,1,2,3,5,7,6,7,9,9,8,8,9,11,13,13,14,18,18,15,15,19,19,15,21,17,20,20,19,24,22,22,21,20,21,23,22,22,21,20,23,22,18,17,22,22,18,22,19,21,21,24,20,18,22,21],[28,28,27,27,28,27,27,27,27,26,27,26,27,26,27,25,27,27,27,27,27,27,27,27,27,27,27,28,27,27,26,27,27,28,27,27,27,27,28,27,27,27,26,26,26,26,25,24,24,24,23,22,22,21,21,21,20,20,19,19,17,14,13,11,9,8,8,7,8,6,6,5,6,5,5,6,6,6,6,6,5,6,6,5,5,6,6,7,7,6,7,7,7,7,7,7,7,7,8,8,8,8,8,7,8,8,8,8,8,9,9,8,8,8,7,8,8,8,8,8,8,7,7,7,7,7,6,7,7,6,6,6,6,6,7,7,7,6,6,7,6,6,7,7,6,6,6,6,6,7,6,6,6,6,7,7,7,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,5,5,6,6,5,5,4,4,5,5,4,4,5,4,4,5,5,4,4,6,6,6,6,6,7,7,7,7,7,7,7,7,7,6,7,7,6,6,6,5,5,5,5,5,5,5,5,4,5,5,5,4,5,5,5,5,5,6,6,7,7,7,7,7,6,6,6,5,5,5,5,4,4,4,4,4,4,3,4,4,5,5,4,4,3,3,4,3,3,4,4,3,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,5,5,4,5,4,4,4,4,4,3,4,4,4,3,4,4,5,5,6,6,6,6,6,6,7,6,6,6,7,7,8,7,8,10,10,11,12,13,14,15,15,14,17,18,16,19,19,19,19,19,20,21,21,22,24,24,23,24,22,21,22,21,20,22,21,23,22,23,24,25,25,27,25,26,27,27,27,26,27,27,28,28,28,27,28,28,28,27,27,28,28,27,27,27,26,26,27,27,27,27,26,27,24,25,25,24,23,23,21,20,20,18,17,16,15,13,11,10,9,8,6,6,6,6,5,5,5,5,5,5,6,6,6,6,6,6,6,7,8,8,7,8,9,9,8,8,7,7,6,6,6,7,7,7,7,9,9,8,8,8,7,8,7,7,7,7,7,6,6,6,6,5,5,5,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,4,3,3,2,3,3,3,3,3,2,2,2,2,2,2,3,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,7,8,8,7,6,6,6,5,5,6,6,6,6,6,7,7,8,7,7,8,8,8,8,8,8,7,7,7,7,7,6,6,6,5,5,5,5,5,5,5,5,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,2,2,3,2,2,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,6,5,6,6,6,6,7,6,7,6,6,7,7,8,7,7,7,7,7,7,7,8,8,9,9,9,10,9,9,9,10,9,8,9,9,8,8,8,7,7,6,6,6,5,5,5,5,5,5,5,4,4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,6,5,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,6,6,6,7,6,6,6,6,6,7,6,6,6,6,6,5,6,5,5,6,6,5,6,5,6,6,6,6,5,6,6,5,5,5,4,5,4,4,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,0,1,2,3,5,7,6,7,9,10,8,8,11,12,13,13,14,18,18,16,14,18,18,14,20,17,20,21,19,23,22,22,21,20,20,23,22,21,21,20,22,21,19,19,22,21,19,21,21,22,22,24,20,18,22,22],[28,29,28,28,29,28,29,28,27,28,27,26,28,26,27,26,28,28,27,27,27,27,27,28,27,27,28,28,28,28,27,28,28,29,28,28,27,28,28,28,28,28,27,27,27,27,26,25,26,26,24,24,25,23,22,23,21,21,19,19,17,15,13,11,9,8,7,7,7,6,6,5,5,4,5,5,5,6,6,6,5,6,6,5,6,5,6,6,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,8,7,8,8,8,8,9,9,8,7,8,7,8,8,8,8,8,7,7,7,7,7,7,6,7,6,6,6,6,6,6,6,7,7,6,6,7,7,6,6,7,6,6,6,6,6,6,6,6,6,6,7,7,7,7,8,8,7,7,7,7,7,6,7,7,6,6,6,6,6,6,6,6,5,6,6,5,5,5,5,5,5,4,5,5,5,4,4,5,4,5,5,6,6,6,6,7,7,7,6,7,7,7,7,7,6,7,7,6,6,6,5,5,5,5,5,4,5,5,4,5,5,5,4,5,5,5,4,5,6,6,7,7,7,6,7,6,6,6,6,5,5,5,4,4,4,4,4,4,3,3,3,5,5,5,4,3,3,4,3,3,4,4,3,4,4,4,4,4,4,4,4,5,5,5,5,5,4,5,4,5,4,4,4,4,4,4,4,4,4,3,4,4,3,3,4,4,4,5,4,4,4,4,4,3,4,4,3,3,4,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,6,7,6,8,8,8,10,11,12,12,14,15,16,15,15,18,19,17,19,20,20,21,22,23,24,24,24,25,26,24,26,23,22,24,22,22,24,23,24,23,24,24,26,26,27,26,27,27,28,27,27,28,28,28,28,28,28,28,28,28,28,27,28,28,28,27,27,26,27,27,27,27,27,27,28,25,25,25,25,24,24,21,22,21,19,18,17,15,14,12,10,8,8,6,6,6,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,8,8,8,7,8,9,9,8,7,7,7,7,6,6,6,7,8,9,9,9,8,8,7,7,7,7,7,6,6,6,6,5,5,5,4,4,4,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,4,4,5,5,5,4,4,3,3,2,3,2,3,3,3,2,2,3,2,2,2,3,2,2,2,2,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,7,8,8,8,7,6,5,5,5,5,6,6,6,6,7,8,8,7,8,8,8,8,8,7,7,7,7,7,6,6,6,6,6,6,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,3,3,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,5,6,6,6,5,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,8,9,8,8,9,8,9,8,9,8,8,9,9,9,8,8,7,6,6,6,6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,3,3,4,3,4,3,4,4,3,4,4,4,4,5,5,4,5,5,5,5,5,5,5,6,6,5,6,6,6,5,5,5,5,5,5,4,5,5,5,4,5,5,4,4,5,5,5,5,5,6,6,7,6,6,6,6,6,6,6,5,6,6,5,6,5,5,5,6,4,5,5,5,6,5,6,6,6,6,6,5,6,6,5,5,5,6,5,4,4,3,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,0,1,3,4,7,6,7,9,10,10,9,11,13,14,15,16,18,18,16,16,18,19,16,21,18,20,21,21,24,23,23,22,22,22,24,24,23,23,22,22,23,20,21,23,22,20,22,21,21,23,23,20,19,22,22],[29,29,28,28,29,27,29,29,27,28,27,27,28,27,27,27,28,28,28,28,28,28,28,29,28,29,29,29,29,29,29,29,30,30,29,30,29,30,29,29,30,29,29,29,29,29,28,28,28,27,27,27,27,27,26,27,25,25,24,23,23,20,18,18,16,15,15,14,13,13,12,13,12,12,13,12,12,12,14,14,13,13,14,13,13,14,14,15,14,15,14,14,15,15,15,16,15,15,14,14,15,14,15,15,15,15,15,14,14,15,16,16,15,15,15,16,14,15,15,14,14,14,14,13,14,14,15,14,13,13,14,13,13,13,13,15,13,14,14,14,14,15,14,14,13,15,14,14,15,14,14,13,14,14,13,15,15,14,15,15,15,15,16,15,15,13,14,15,14,13,13,14,13,13,13,13,12,13,12,12,12,11,11,12,12,10,11,13,10,10,13,12,11,12,13,13,14,13,13,16,15,13,14,16,15,14,14,14,13,14,14,14,12,14,14,11,14,13,12,11,13,14,11,12,13,13,10,12,13,13,10,12,12,12,12,14,13,12,12,12,12,12,13,12,13,10,10,12,10,9,9,8,7,8,8,9,9,9,8,7,8,9,8,8,9,9,8,9,10,10,10,10,11,10,11,12,10,11,11,12,11,12,11,12,12,10,10,11,11,9,10,11,9,8,10,11,8,8,10,12,10,10,10,9,10,10,8,9,9,8,7,9,9,9,7,9,9,10,10,11,10,11,12,12,12,12,12,13,12,13,13,15,14,14,16,17,17,19,18,19,20,20,21,22,22,22,24,24,23,24,25,26,27,26,27,27,28,27,28,26,26,26,24,23,25,25,25,25,25,26,28,27,27,27,28,27,27,28,28,28,28,28,28,28,28,28,28,29,28,28,28,29,29,28,28,28,28,28,28,28,28,28,28,28,28,28,27,27,26,27,25,24,24,21,23,19,19,18,15,15,15,13,13,13,12,11,13,11,11,11,11,11,11,12,12,12,12,12,12,13,14,14,14,16,15,16,14,13,13,12,12,13,13,13,14,15,16,16,15,15,16,15,13,14,14,13,12,13,13,11,11,11,11,11,11,9,10,8,8,9,7,5,7,7,6,6,7,6,6,7,7,7,8,8,9,8,8,7,5,6,5,6,6,6,8,7,5,6,6,5,4,6,6,5,6,8,7,8,9,8,9,10,9,9,10,10,12,11,12,13,12,12,11,12,12,13,13,14,14,13,12,12,13,13,13,15,14,13,14,15,16,15,16,14,15,15,16,15,15,15,15,15,14,14,15,15,14,13,13,13,13,13,13,13,12,11,12,10,11,11,8,8,10,9,7,9,8,7,7,7,7,5,5,7,6,5,8,8,7,8,9,8,9,9,10,12,10,10,10,10,13,11,14,12,12,13,12,10,13,12,12,13,14,13,13,15,14,15,14,14,15,14,15,15,15,14,14,15,15,15,15,15,15,16,15,16,16,16,17,16,15,15,16,15,14,14,14,14,13,14,13,13,13,12,12,13,11,12,12,11,12,11,12,9,12,11,10,8,10,10,10,8,10,9,10,12,12,11,12,11,13,12,12,11,12,12,11,11,12,13,12,12,12,13,13,12,12,12,11,12,12,12,11,11,11,11,11,11,11,11,12,11,12,11,12,13,13,13,12,13,13,11,13,13,13,12,13,13,11,12,12,13,13,14,11,12,11,11,12,11,12,12,12,12,12,12,12,14,11,11,11,13,11,10,10,9,9,10,9,8,9,8,7,7,6,6,6,4,4,4,4,2,2,0,1,4,7,6,8,9,10,10,10,13,16,16,16,17,21,20,17,18,23,21,18,22,20,21,23,22,24,23,22,23,24,24,24,26,24,22,25,25,25,21,24,25,25,23,25,23,23,24,25,22,21,24,24],[27,28,27,28,29,27,28,29,27,28,28,28,29,27,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,28,28,27,27,26,25,24,24,25,25,24,24,23,22,22,22,22,22,23,23,24,24,22,23,24,22,21,23,23,26,25,23,26,25,23,26,25,25,22,25,25,23,25,25,26,24,25,24,24,24,24,23,24,25,25,25,25,25,24,25,25,23,24,25,25,24,25,23,25,26,24,22,24,25,22,20,24,22,22,23,24,25,24,23,25,25,22,25,25,23,22,25,25,22,24,25,25,25,26,25,24,24,26,25,26,25,25,24,24,26,23,24,25,25,23,24,25,23,23,25,24,20,23,22,19,22,22,20,20,23,21,19,21,21,21,20,22,20,22,22,20,22,23,22,22,23,23,22,23,22,22,23,23,22,22,24,23,22,23,24,22,21,22,24,21,21,22,23,21,22,23,22,21,22,22,22,23,23,23,23,23,24,24,24,22,23,24,21,18,21,20,19,17,18,16,15,15,17,18,16,13,14,14,18,16,13,16,19,17,16,21,20,18,21,21,19,20,21,21,21,20,22,21,20,21,21,22,20,19,21,20,18,21,22,19,17,20,20,17,17,19,22,21,21,21,18,21,21,17,19,21,19,18,21,21,19,18,21,20,22,21,22,20,22,22,21,22,23,23,22,23,24,24,25,23,23,24,26,26,25,26,26,26,27,27,28,27,28,29,28,28,29,28,29,30,29,29,29,29,29,30,29,29,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,27,27,28,26,25,26,24,23,24,22,23,25,23,22,22,22,21,22,21,21,22,22,21,23,22,22,22,23,25,23,24,25,24,24,23,22,22,20,19,22,22,24,24,24,24,24,23,24,25,24,24,26,25,23,23,25,25,22,22,23,22,21,22,22,20,19,16,20,20,16,17,19,15,14,18,16,15,15,19,15,14,15,16,14,14,11,12,13,11,14,12,15,16,13,11,12,13,10,9,12,11,9,10,14,12,14,14,13,18,20,20,20,20,21,22,21,20,21,20,19,21,21,18,21,20,20,20,21,19,21,20,21,23,22,22,24,24,25,26,25,25,25,25,25,26,25,26,24,25,27,25,25,27,25,23,23,24,21,20,23,22,20,20,21,21,19,20,21,18,16,20,18,16,15,18,16,11,15,17,12,12,15,10,12,14,13,8,11,15,14,12,18,18,18,18,18,19,20,20,20,22,20,20,22,21,19,23,23,22,24,24,23,25,25,25,25,24,24,26,25,26,26,25,24,25,26,25,25,26,25,24,25,24,25,26,24,25,25,24,25,25,24,24,24,23,24,24,25,23,24,22,21,23,22,21,22,21,20,19,21,21,20,19,20,19,17,19,21,20,17,18,16,19,20,21,21,21,21,20,20,20,20,22,21,22,21,23,23,22,24,22,24,23,24,24,22,22,24,23,20,22,23,21,20,22,22,21,21,23,21,21,22,21,21,21,23,23,21,21,21,22,23,24,23,22,24,22,24,22,24,23,23,23,21,22,21,22,22,22,22,22,21,20,21,21,21,19,19,18,20,18,18,17,17,18,18,19,18,19,13,13,13,10,9,10,10,7,6,7,6,4,2,0,2,3,5,7,9,12,11,10,15,18,19,20,20,23,23,21,21,25,22,21,23,23,23,25,24,25,25,25,24,26,26,26,26,26,25,26,26,27,24,24,27,26,25,26,25,25,26,27,25,23,26,26],[28,29,27,28,29,28,29,29,28,28,28,29,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,30,31,30,30,30,31,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,28,28,27,26,27,26,27,27,25,26,26,24,25,23,24,26,26,25,26,27,24,26,27,25,25,27,26,28,27,26,28,28,26,28,27,27,26,27,27,26,27,27,27,26,27,26,26,25,26,25,26,27,27,27,27,26,26,27,26,26,26,26,26,25,26,25,26,26,26,24,25,26,24,22,24,24,27,25,27,27,26,26,27,26,25,27,26,26,25,27,26,25,26,27,26,27,28,26,27,26,28,28,27,28,28,27,27,28,26,27,27,27,25,25,26,25,24,25,25,22,25,24,21,24,25,22,22,25,24,21,24,24,23,21,24,23,25,24,23,25,26,24,25,27,26,26,26,25,25,26,26,26,24,27,26,24,26,26,25,23,25,26,24,23,25,26,23,23,25,25,21,25,24,26,25,26,25,24,25,24,25,25,24,25,25,22,21,24,23,22,21,21,19,17,16,20,20,18,16,16,16,22,20,15,19,22,20,20,24,23,21,23,24,22,23,25,23,24,24,25,24,24,23,24,24,23,22,24,23,22,22,24,22,21,22,23,20,19,22,24,22,23,23,22,22,23,21,22,22,23,19,23,22,21,19,23,22,22,23,22,22,24,24,22,24,25,26,25,26,24,26,26,26,26,26,27,27,27,28,28,28,28,28,29,28,29,29,30,29,30,29,30,30,29,30,30,30,30,30,30,29,29,29,28,29,28,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,28,28,27,26,26,25,24,26,25,25,26,25,25,23,24,22,23,23,24,24,24,23,25,24,24,25,25,26,25,25,26,25,25,25,23,23,22,21,24,23,24,24,25,26,26,25,26,26,26,26,26,25,26,25,26,25,25,24,24,24,24,23,23,21,21,20,21,20,18,20,20,17,15,20,19,15,16,18,17,14,14,17,16,13,11,12,14,12,16,15,17,20,17,13,14,15,14,11,15,15,11,13,17,15,18,19,19,20,24,22,23,23,24,24,23,24,24,23,22,24,24,23,25,24,24,24,24,24,24,24,24,26,26,25,26,26,27,27,27,27,27,27,27,27,27,28,27,27,27,27,27,27,28,27,26,27,25,25,25,25,24,23,24,23,22,22,23,22,21,22,21,19,20,20,20,15,18,18,15,14,18,14,12,18,18,14,17,20,19,19,22,22,23,22,23,23,23,24,23,24,24,24,24,24,24,25,26,25,27,26,26,26,26,27,27,27,27,27,27,27,28,27,27,27,27,27,27,27,27,26,27,26,26,27,26,27,26,26,26,27,26,26,27,25,26,25,27,26,26,25,25,26,24,23,25,25,22,22,24,23,23,24,22,22,22,23,22,22,22,22,22,25,24,25,25,24,24,24,24,24,22,25,25,25,24,26,27,24,26,25,26,26,26,26,25,26,27,24,23,25,26,23,23,25,24,23,24,25,23,25,24,25,25,25,25,26,24,24,25,26,25,27,26,25,26,25,26,24,26,25,24,24,23,23,24,24,24,24,25,24,23,24,24,24,25,22,24,22,24,23,21,22,22,21,22,21,20,20,18,16,15,14,13,11,11,10,8,7,7,7,3,1,0,2,4,5,7,9,9,9,14,16,17,20,20,23,23,20,20,24,22,19,23,20,22,24,22,25,25,24,23,26,25,25,26,26,25,25,26,27,24,24,26,26,26,25,25,25,26,26,25,23,25,26],[28,29,27,29,29,28,30,30,28,29,29,29,30,29,30,29,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,30,31,31,31,30,31,30,30,30,30,30,30,30,29,28,28,28,28,28,29,28,28,29,28,27,28,25,27,28,28,28,29,29,27,28,29,28,26,28,28,29,29,28,29,29,29,29,28,29,28,29,29,28,29,29,28,28,29,28,27,27,28,27,28,29,29,29,29,28,28,28,29,27,27,29,28,26,27,27,27,27,27,26,25,27,26,26,25,26,26,27,28,27,27,28,29,27,26,29,28,27,28,29,29,26,29,29,29,29,29,28,29,28,29,29,29,29,29,29,29,29,28,29,29,29,27,27,28,27,26,27,26,25,26,25,24,25,26,25,25,26,26,24,26,25,26,24,25,26,25,26,25,26,27,26,26,27,28,28,27,27,28,27,27,27,27,28,26,26,28,28,26,25,28,27,26,26,27,27,25,26,27,27,24,27,28,27,27,28,27,27,26,26,28,27,26,26,27,25,24,25,26,24,24,24,21,21,19,22,22,20,18,17,20,24,22,19,24,25,24,23,26,26,25,26,26,26,26,27,26,26,27,27,26,26,27,28,27,25,25,27,25,25,26,27,25,24,25,26,24,23,25,26,26,27,26,26,27,26,25,27,26,26,24,27,26,25,25,26,26,27,26,26,27,27,27,27,27,28,28,28,28,28,28,28,27,28,28,29,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,29,30,30,29,30,29,30,30,29,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,31,31,31,30,30,30,30,31,31,30,30,30,30,30,30,31,31,30,31,30,30,30,30,30,30,30,30,29,29,29,29,28,28,29,27,27,29,28,28,28,28,28,27,27,27,27,27,27,28,27,27,27,27,27,27,27,27,27,28,28,27,27,26,26,25,25,23,26,27,27,27,27,27,28,26,28,28,28,28,28,27,28,28,28,28,27,27,27,27,27,27,26,26,25,23,25,25,21,22,24,20,20,23,21,17,19,21,18,14,13,18,17,15,13,15,17,16,21,18,22,23,21,17,16,20,17,15,17,19,15,15,19,19,23,23,23,25,27,25,26,27,28,27,26,27,27,26,27,28,28,26,28,27,27,27,27,27,28,27,27,28,27,27,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,27,28,28,28,27,27,27,26,26,26,26,25,25,26,25,23,24,25,23,20,22,22,20,18,22,19,18,22,22,18,22,24,24,23,25,26,26,26,27,27,28,28,27,27,28,28,27,27,27,28,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,29,29,28,29,29,28,28,29,27,28,28,27,28,28,29,29,29,28,28,28,27,27,28,28,25,26,27,26,26,27,27,27,26,27,27,27,26,27,26,27,28,29,28,27,28,28,28,27,26,28,28,28,27,29,28,27,28,28,29,28,28,29,28,28,29,28,27,28,28,27,27,28,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,28,28,27,28,27,28,28,27,27,27,27,27,26,27,28,27,27,27,28,27,27,27,26,28,26,28,27,26,26,25,25,25,25,23,23,22,20,19,18,16,15,15,13,12,12,12,10,8,4,2,0,1,4,7,7,8,8,11,13,16,18,22,23,24,21,20,24,23,19,23,19,22,25,23,25,26,23,25,27,25,26,28,27,24,26,27,26,22,23,27,27,24,26,24,25,25,26,24,23,25,25],[26,28,27,28,28,28,29,28,28,29,28,28,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,31,31,31,31,31,30,31,31,31,30,30,31,30,30,30,30,30,30,30,30,30,29,29,29,29,28,27,28,27,28,28,27,29,28,27,28,27,27,28,28,28,28,29,27,28,29,28,26,28,28,29,29,27,29,28,28,29,28,28,28,29,28,27,28,29,28,28,29,28,28,28,28,28,28,28,28,29,29,28,28,29,28,28,28,29,28,27,28,27,27,28,28,25,26,27,25,26,26,26,26,26,27,28,27,28,28,28,26,29,28,27,27,29,28,26,28,29,28,29,29,28,28,28,29,29,29,29,29,29,28,29,28,28,29,29,27,27,28,27,26,27,27,26,27,26,25,25,26,25,25,26,25,24,26,24,25,24,25,25,25,25,24,25,26,25,26,26,27,26,27,26,27,27,27,27,26,28,26,25,28,28,26,25,28,27,25,26,28,27,26,27,28,27,26,27,27,27,27,27,27,27,27,27,27,27,27,27,28,26,25,26,27,24,23,25,22,21,18,23,24,20,18,16,19,24,22,18,22,23,23,21,25,26,21,24,24,25,24,25,24,24,25,26,24,26,26,27,27,24,25,27,25,24,26,27,25,24,26,26,23,23,25,26,26,27,26,25,26,27,25,26,26,26,23,27,26,24,22,26,25,27,26,26,26,27,27,26,28,28,28,28,28,28,28,27,27,27,27,28,28,28,28,28,29,29,29,29,29,30,30,30,30,30,29,30,31,30,30,30,30,30,31,30,29,29,29,29,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,30,31,30,31,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,29,30,29,29,29,28,28,28,27,27,27,27,27,28,27,28,26,27,26,26,26,26,28,26,26,26,26,26,26,27,26,26,26,27,26,26,25,25,24,24,23,25,26,27,27,27,27,26,25,27,28,27,26,28,28,27,27,28,28,27,26,27,27,26,27,26,26,24,22,25,24,21,22,23,20,20,21,20,17,17,17,16,13,13,17,15,15,12,15,16,16,20,17,22,23,23,18,17,21,18,15,15,19,15,15,17,18,20,21,22,24,25,24,26,25,26,26,26,26,26,26,26,27,27,26,26,26,25,25,26,26,26,26,26,27,26,26,28,28,28,29,28,29,28,28,28,28,28,29,28,28,29,29,28,29,29,29,29,29,27,28,29,28,26,27,28,26,26,26,25,26,25,26,25,22,24,25,24,20,23,24,20,18,23,18,18,23,22,17,22,23,22,21,24,25,24,24,25,25,27,26,26,27,27,27,27,27,26,28,27,28,28,28,29,29,28,29,28,29,28,29,28,29,29,29,28,29,28,29,29,29,29,28,28,27,28,28,28,28,28,28,28,28,27,28,28,27,28,27,29,28,29,28,28,28,27,26,27,28,25,26,27,27,26,26,27,26,25,27,26,27,25,26,25,26,27,27,27,27,27,26,27,25,27,27,26,28,28,28,28,28,28,27,29,27,28,28,28,28,28,28,27,28,28,27,27,27,27,27,28,27,27,28,26,26,27,25,28,27,26,26,27,28,28,28,28,27,28,28,27,27,28,28,27,26,27,26,26,26,26,27,26,26,25,26,26,25,26,25,25,25,26,24,25,24,23,24,24,22,21,23,20,19,20,19,15,15,16,13,11,10,12,11,7,6,5,2,0,2,4,5,8,7,11,11,14,16,18,19,21,18,15,22,21,18,22,18,22,22,21,24,23,22,23,24,24,23,25,24,22,24,25,23,20,21,25,25,21,25,22,24,25,26,22,20,24,23],[27,28,27,29,29,28,29,29,28,29,29,29,29,28,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,31,31,31,31,30,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,28,28,27,27,28,29,27,27,28,28,27,27,26,26,28,28,28,28,28,27,28,28,28,27,28,28,28,28,28,28,28,28,29,29,29,28,29,28,28,29,29,28,28,29,29,28,27,28,28,28,28,29,29,29,29,28,29,28,28,28,29,28,27,27,28,27,27,27,25,26,27,25,25,25,24,25,25,27,26,26,28,28,27,26,29,28,27,28,29,28,27,28,29,28,28,29,28,29,28,29,29,29,28,29,28,28,29,28,29,28,28,27,27,28,27,25,27,26,24,25,24,21,24,25,21,23,25,24,22,24,24,23,22,24,24,24,24,24,24,25,24,25,26,26,26,26,25,27,27,27,26,25,28,26,25,27,28,25,25,27,27,24,26,27,26,24,26,27,26,24,27,26,27,27,27,27,26,26,25,27,26,24,25,26,24,22,24,24,22,22,22,20,19,18,21,22,19,17,17,18,22,21,18,21,22,21,21,23,23,21,23,24,24,24,25,23,23,25,25,24,26,24,27,26,23,24,26,24,23,25,26,22,22,24,25,22,22,24,26,25,26,25,24,25,25,23,25,25,24,22,25,24,24,20,24,25,25,25,25,25,27,26,25,26,27,27,26,27,27,27,27,27,26,27,28,28,28,28,27,28,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,28,27,27,27,26,27,27,26,26,26,27,26,25,23,26,25,24,25,26,26,25,26,25,26,26,26,26,25,26,25,25,23,22,21,24,25,25,25,26,25,26,25,27,27,27,25,26,27,26,27,26,27,26,25,26,26,25,26,24,23,23,21,22,22,20,20,20,18,16,18,18,14,16,16,14,12,10,15,14,13,11,13,15,15,20,17,20,22,20,16,16,19,17,14,15,17,15,15,17,19,19,21,21,23,24,22,24,24,24,25,25,25,25,26,25,27,27,24,27,26,26,26,26,25,25,26,25,28,26,27,28,27,28,28,28,28,28,28,28,28,29,28,28,28,28,29,29,28,29,28,28,29,27,27,28,27,25,26,27,25,23,25,25,23,23,25,24,22,23,23,22,20,21,21,20,17,21,17,17,21,22,16,21,22,22,20,23,24,23,23,24,24,26,26,24,25,27,27,26,27,26,28,28,27,29,28,28,28,28,28,28,28,28,28,29,28,29,29,28,29,28,29,28,29,29,28,28,28,28,28,28,28,29,28,28,28,28,28,28,28,27,28,28,28,28,28,27,28,27,25,27,27,24,25,27,25,25,26,26,25,24,26,26,26,24,26,25,26,26,27,27,26,27,26,26,26,26,27,27,26,27,28,28,27,28,27,28,27,27,27,26,27,28,27,27,27,27,26,26,27,26,26,26,27,27,27,27,27,27,27,27,27,27,27,26,27,28,27,27,27,27,26,27,26,27,27,27,26,26,26,26,26,27,26,26,26,26,26,26,26,26,25,26,26,27,25,24,24,22,22,22,21,20,21,20,17,16,17,14,14,14,13,10,10,11,10,8,7,6,4,2,0,1,2,5,4,6,6,8,9,10,12,15,12,11,16,16,13,18,15,19,20,20,23,21,20,21,22,22,21,24,24,21,23,25,23,20,20,24,25,21,25,22,22,23,24,22,19,23,20],[27,28,27,28,28,27,28,28,28,28,27,28,29,28,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,30,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,27,28,27,27,28,26,28,27,26,27,26,26,28,27,27,27,28,27,28,28,28,27,28,28,28,29,28,28,28,28,29,28,29,28,28,28,27,28,28,28,27,29,28,27,27,27,27,28,28,28,28,28,28,28,28,27,27,27,27,27,26,27,27,25,27,27,24,25,27,24,23,24,23,25,24,27,25,26,27,27,26,25,29,27,26,28,28,27,26,28,27,27,28,29,28,28,28,29,28,28,28,28,28,27,28,28,28,28,28,26,26,27,26,23,26,25,24,25,24,21,24,24,21,23,25,23,21,25,24,22,22,24,24,26,25,24,26,26,25,25,27,27,28,27,26,27,27,26,26,26,28,26,24,27,27,24,23,27,26,23,24,27,25,23,26,27,25,24,27,25,26,25,26,26,26,25,25,26,26,24,24,25,25,23,23,25,21,21,21,20,19,18,21,21,19,18,16,20,21,20,16,18,21,20,20,23,23,20,23,24,24,23,25,23,24,25,25,23,26,25,27,26,23,24,26,23,21,24,25,23,21,24,23,22,20,24,25,25,25,24,23,24,24,22,24,23,24,22,24,23,21,21,23,24,23,23,23,24,25,25,24,26,26,27,26,27,26,27,26,27,26,27,29,29,28,28,29,29,28,29,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,28,28,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,27,26,28,26,26,26,26,26,26,26,25,25,23,24,23,24,24,23,24,24,23,23,24,24,24,24,24,26,25,24,25,23,23,21,21,20,22,22,23,24,24,24,25,24,26,26,26,25,26,26,25,25,25,26,25,25,25,25,25,23,23,23,22,21,22,21,20,21,21,19,18,19,17,15,16,16,13,13,10,12,14,12,12,15,17,15,20,18,20,20,20,18,17,19,18,14,15,19,13,13,17,19,20,20,20,22,23,21,23,24,25,26,25,25,25,25,25,27,26,25,27,25,26,26,26,25,25,26,26,27,26,26,28,28,29,28,28,28,29,28,29,29,29,28,28,28,28,29,28,28,29,29,28,29,28,27,28,27,25,26,27,24,24,25,24,23,22,24,24,21,21,23,21,21,21,21,19,18,22,17,19,21,21,17,21,23,21,20,22,23,24,21,23,23,24,24,24,25,26,26,27,27,25,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,29,28,28,28,28,28,28,29,28,28,28,29,28,28,28,28,29,28,28,28,28,27,28,27,28,27,28,28,27,28,27,26,27,27,25,26,26,26,24,25,25,24,22,24,24,24,24,24,24,24,25,25,24,26,24,24,25,25,25,26,27,26,27,28,28,27,27,27,28,27,27,27,27,27,27,28,25,27,27,26,26,27,26,24,26,26,24,25,26,25,26,26,27,27,26,26,26,27,27,27,27,26,27,26,26,26,27,26,26,25,25,24,24,25,25,25,25,25,24,25,24,24,25,22,24,23,24,24,24,23,23,24,24,22,22,22,21,20,18,19,16,16,16,13,10,11,11,11,8,7,6,4,2,1,0,1,2,2,4,5,8,8,11,12,16,11,12,16,17,13,17,13,16,17,19,19,19,19,20,21,21,21,24,22,20,21,24,22,21,19,22,23,21,23,20,21,20,22,19,18,19,19],[27,28,27,28,28,28,29,29,28,28,27,27,28,28,29,28,29,28,29,30,29,29,30,29,29,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,31,31,30,30,30,30,29,30,30,30,29,30,30,29,29,29,29,27,28,27,28,28,28,28,27,28,28,26,27,24,26,28,28,27,28,29,26,28,28,28,27,28,28,28,29,28,29,29,28,28,29,29,28,29,29,29,29,29,29,28,28,29,28,28,28,27,28,29,29,29,29,29,28,28,28,28,27,28,27,26,28,27,25,27,28,25,25,28,26,24,25,24,27,25,28,27,26,28,28,28,26,29,28,27,28,28,28,27,28,28,28,28,29,28,29,29,29,29,29,28,29,28,28,29,28,28,28,28,27,27,27,27,24,25,25,24,26,23,22,23,25,20,22,24,23,20,22,24,21,21,22,21,24,23,22,24,26,24,24,27,28,27,28,25,27,28,28,26,25,28,26,24,28,28,25,24,27,27,24,26,27,26,23,26,27,25,23,27,25,27,25,27,27,26,25,25,27,25,24,25,25,23,22,22,23,22,21,21,19,19,18,20,20,18,17,18,18,20,19,19,20,22,19,21,22,22,20,22,24,23,21,24,22,23,24,25,23,26,24,27,26,22,23,25,24,21,24,25,22,21,23,24,21,21,24,26,24,25,24,23,25,24,23,24,24,24,24,25,24,23,21,25,24,25,24,23,24,25,25,23,25,25,26,26,26,27,26,27,27,27,28,28,28,28,28,28,29,28,29,29,29,29,29,29,29,29,29,30,30,30,29,30,30,30,30,29,29,29,28,28,28,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,29,30,29,29,29,29,28,28,26,27,27,25,26,27,26,26,26,25,26,24,26,26,25,26,25,25,24,24,26,25,23,25,24,25,25,26,26,25,26,23,22,21,23,21,22,23,23,23,24,25,26,24,27,27,27,26,25,26,25,25,26,26,25,24,25,25,24,24,23,24,24,22,23,23,23,22,22,20,21,21,19,16,16,15,13,13,9,13,14,13,13,17,17,18,21,18,20,20,20,18,18,20,19,16,16,17,15,15,16,19,18,19,19,22,21,22,23,23,23,25,24,25,25,26,25,28,27,25,27,28,26,26,25,23,24,26,25,28,26,26,29,28,29,28,28,28,29,28,29,28,28,28,28,28,29,29,29,28,29,29,29,29,27,27,28,28,25,27,27,25,23,25,25,23,22,24,24,21,22,23,21,22,22,23,21,20,23,19,20,22,22,18,22,22,22,20,22,23,23,23,23,24,24,25,25,25,27,27,26,27,27,28,28,27,28,28,28,28,28,28,28,28,28,28,29,28,29,28,28,28,29,29,29,28,29,28,29,28,28,29,28,28,29,28,28,28,28,28,28,27,28,27,28,28,28,28,27,28,27,25,27,27,23,25,26,25,24,25,25,23,23,25,24,26,25,25,24,25,26,26,25,26,27,25,26,27,25,27,27,27,26,28,29,27,27,28,28,27,27,27,25,27,28,26,25,27,27,24,24,27,26,24,26,26,25,26,26,27,28,27,28,27,26,28,26,26,27,27,27,27,27,26,27,26,26,25,25,26,24,25,25,24,25,25,25,26,24,26,25,24,27,23,25,22,24,25,23,23,23,24,23,21,22,22,22,19,20,21,16,16,18,15,10,12,13,12,9,8,6,6,4,3,1,0,1,2,3,5,8,7,9,11,13,12,11,14,14,13,17,14,17,19,18,21,20,20,20,23,21,20,24,22,21,21,24,22,20,18,23,23,20,24,18,21,21,22,19,16,19,19],[25,27,26,27,27,27,28,28,28,28,28,28,28,28,29,28,29,29,29,29,29,29,29,29,29,30,30,29,30,30,29,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,29,29,29,29,29,27,28,28,28,28,28,28,28,28,28,26,27,24,26,28,28,28,28,28,26,28,29,27,27,28,29,28,29,28,29,29,28,28,29,29,28,29,29,28,29,29,29,28,29,29,29,28,28,28,29,29,29,29,29,29,28,29,28,28,28,28,27,27,28,27,25,28,28,25,26,28,25,24,25,25,26,25,28,28,26,27,28,28,26,28,28,27,27,28,28,27,28,29,29,29,29,29,29,29,29,29,29,29,29,28,28,29,28,28,28,28,27,27,28,27,24,27,26,25,27,23,23,25,25,21,23,25,23,23,23,24,22,22,24,24,24,24,23,25,26,24,25,26,28,28,27,26,27,28,28,27,25,28,26,24,27,28,25,24,27,27,24,25,28,26,23,26,27,25,24,26,26,27,27,28,26,27,26,26,26,26,25,26,25,24,24,24,23,23,23,22,22,21,20,21,21,19,19,19,19,21,20,20,21,22,21,22,22,21,20,22,25,22,22,24,22,23,25,26,23,26,24,27,27,23,23,25,24,22,23,25,23,23,24,24,23,23,25,26,25,27,25,24,26,25,24,24,25,25,23,24,24,24,21,24,23,26,24,24,26,26,24,24,25,26,26,25,27,28,26,27,26,27,28,28,27,28,27,28,28,28,28,29,29,28,29,29,29,29,29,30,30,29,29,29,29,29,30,28,28,29,28,28,28,28,29,28,28,28,28,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,29,29,28,28,25,27,26,25,27,27,26,27,26,26,26,23,26,24,23,23,25,25,23,24,25,25,22,24,24,25,23,24,26,24,24,22,22,21,22,20,20,23,22,23,25,24,25,25,26,27,26,25,25,26,25,25,26,26,25,24,26,25,24,25,23,24,22,21,22,22,21,21,21,19,17,19,17,15,13,15,12,10,9,13,13,13,13,15,18,18,22,20,21,22,20,19,18,19,19,16,16,18,14,16,17,19,19,19,20,22,22,22,23,23,23,25,24,24,25,27,25,28,27,26,27,27,25,25,26,24,25,26,26,27,26,27,28,28,29,29,29,29,29,29,29,28,28,28,29,28,28,29,29,29,29,29,29,29,28,28,28,28,26,26,27,25,23,24,25,23,23,24,24,23,22,24,22,22,21,22,21,19,21,18,20,21,22,19,21,22,22,21,22,22,22,22,23,23,25,25,25,25,27,26,27,28,26,28,28,28,29,29,28,28,28,28,29,28,29,29,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,28,28,28,29,28,28,28,28,28,28,28,27,28,26,26,27,27,24,25,26,25,24,25,25,24,23,25,25,25,24,25,23,24,25,25,24,25,26,24,25,26,25,27,27,27,26,28,28,27,27,28,28,28,26,28,26,27,28,26,25,27,27,25,25,27,26,25,25,27,25,25,26,25,27,25,27,26,26,27,26,27,28,27,27,27,27,26,26,27,27,25,26,27,25,26,25,24,26,26,26,26,25,24,25,24,25,23,23,23,23,23,22,20,21,23,23,19,20,21,20,16,18,19,15,14,15,14,12,11,13,13,11,10,10,8,6,4,3,1,0,1,3,5,7,7,8,10,12,9,10,13,12,12,16,14,18,18,18,19,20,18,18,19,20,18,21,21,20,19,23,21,19,19,22,23,20,23,18,20,19,22,19,16,19,18],[26,27,27,28,28,28,29,28,29,29,27,28,28,28,29,28,29,28,29,29,29,29,30,29,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,28,29,29,28,28,28,27,28,27,27,27,27,28,28,27,27,25,26,27,27,27,27,28,27,27,28,27,26,27,28,28,28,28,28,28,28,28,28,28,27,28,28,27,28,28,28,27,28,28,28,27,27,27,28,27,28,28,28,28,27,28,27,26,27,27,26,27,27,26,25,27,27,23,25,27,24,22,23,23,26,24,26,25,25,27,28,26,24,28,27,25,27,28,28,26,28,28,28,28,28,28,28,28,29,28,28,28,28,28,28,28,27,28,28,28,25,26,27,25,24,26,25,24,25,23,23,24,25,22,23,25,23,23,24,25,22,23,24,22,24,25,23,25,26,25,24,26,26,27,27,25,27,26,27,27,24,28,25,23,27,27,24,23,27,27,23,25,27,24,22,26,27,24,24,26,25,26,26,27,25,25,25,24,25,26,24,23,25,24,23,24,25,21,22,22,23,20,20,22,22,18,17,18,20,22,22,20,21,22,22,21,22,23,21,23,24,24,23,24,22,23,25,26,23,26,23,27,26,22,23,26,23,21,25,25,22,22,24,24,23,21,24,25,26,25,25,23,25,25,23,24,23,24,23,24,24,22,20,21,22,23,23,23,23,25,25,24,25,25,26,27,27,26,26,25,26,26,27,28,27,26,28,28,27,28,29,28,27,28,28,28,28,29,28,29,29,29,30,30,30,30,30,29,29,29,29,28,28,29,28,28,28,29,29,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,29,29,30,29,29,29,28,28,28,26,26,26,25,25,26,24,26,26,25,24,22,23,23,22,22,22,22,22,21,22,21,22,22,22,23,22,24,24,22,22,20,20,18,21,18,20,21,21,21,21,21,23,22,25,24,24,23,23,24,24,23,24,24,23,24,23,24,23,23,22,22,22,20,21,21,20,19,20,19,17,17,16,14,14,13,11,11,9,11,13,13,12,15,17,18,21,19,22,22,21,21,18,20,19,16,17,18,16,17,17,20,19,20,20,21,21,21,23,23,23,24,24,24,25,26,25,28,27,25,26,26,25,26,25,23,24,26,25,27,25,25,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,28,29,28,29,28,28,28,27,25,26,27,24,23,25,25,23,22,25,23,21,22,23,22,20,22,21,20,18,20,18,19,21,21,18,20,22,22,20,22,23,22,22,22,23,25,24,23,24,25,25,26,27,26,27,27,28,27,28,28,28,28,28,28,28,29,28,28,28,29,28,28,28,28,28,28,28,28,28,27,27,28,29,28,28,27,28,29,28,27,28,28,28,27,27,28,28,28,28,27,28,27,26,27,27,23,25,26,25,23,24,24,23,23,25,24,24,23,22,22,25,24,23,23,25,24,24,26,25,25,26,26,26,26,26,27,27,27,27,28,27,26,27,27,27,27,27,26,27,26,25,25,26,25,24,25,26,24,25,24,24,25,25,27,26,24,25,26,25,26,27,26,26,27,25,25,25,27,26,26,25,25,22,23,24,24,26,24,23,23,24,23,23,22,22,23,22,22,21,21,22,19,21,22,20,19,21,19,17,17,18,16,13,16,15,11,10,13,13,9,8,8,7,6,4,3,3,1,0,1,3,4,4,6,7,8,8,8,10,11,10,14,12,15,17,18,19,19,19,18,19,19,18,20,20,20,18,21,20,20,17,20,20,19,21,18,19,18,20,18,16,18,18],[26,26,26,26,27,27,27,28,28,27,27,26,27,27,28,27,28,28,28,29,28,28,29,29,28,29,29,29,29,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,29,29,29,29,28,29,28,28,27,28,27,28,28,28,27,28,27,28,25,27,24,25,27,28,27,28,28,26,27,27,27,26,27,27,27,28,28,29,29,28,28,29,29,27,29,29,28,28,28,29,27,28,29,28,28,28,28,29,28,28,28,28,28,28,29,28,28,28,28,26,27,28,27,25,27,27,24,25,27,23,23,24,24,27,25,28,27,25,27,28,26,26,28,27,26,27,28,28,27,28,27,27,28,29,28,28,28,29,28,29,28,28,28,28,28,28,27,27,27,26,26,27,26,24,24,23,23,25,23,21,22,24,21,22,23,23,22,22,23,23,22,23,23,24,24,24,25,27,25,25,26,27,27,28,26,27,27,27,27,25,27,25,25,26,27,23,24,26,26,23,24,27,24,22,25,27,24,24,26,25,27,27,27,25,26,25,24,25,24,24,23,24,23,23,23,24,22,21,22,21,20,21,20,21,19,18,18,20,20,21,20,20,21,22,22,22,23,21,22,24,24,22,23,22,23,24,25,23,24,25,26,26,23,24,25,23,22,23,24,22,22,23,23,22,20,22,24,24,24,23,22,23,23,22,22,22,23,22,22,22,22,21,22,21,24,22,23,23,24,24,23,24,25,25,26,26,27,26,27,27,26,28,28,28,28,28,28,28,28,28,28,28,29,28,29,29,29,29,29,29,29,29,29,30,29,29,28,29,29,28,28,28,28,28,28,27,28,29,29,29,29,29,30,30,29,29,29,29,29,29,29,29,30,30,30,29,29,30,29,30,29,30,29,30,30,29,30,29,29,29,29,30,30,29,30,29,29,29,29,29,28,28,26,27,27,25,27,25,24,25,24,24,23,21,23,22,23,22,22,23,22,23,21,22,22,22,21,22,23,22,23,22,22,21,21,19,20,18,19,21,21,22,21,22,23,21,24,24,24,23,22,24,22,24,23,24,23,23,23,22,23,22,22,22,21,20,21,21,19,20,21,18,17,19,18,14,14,15,13,10,9,12,13,12,11,15,17,18,20,19,20,19,19,20,18,18,18,16,16,18,15,16,17,18,18,20,19,21,23,22,23,24,22,25,24,24,25,27,26,27,27,26,26,27,25,26,26,24,25,26,26,27,26,26,28,28,28,29,28,28,28,29,29,29,29,28,28,29,28,28,28,28,28,28,28,28,27,26,27,27,26,26,26,25,25,25,24,24,24,23,23,21,21,21,21,21,20,20,17,18,19,17,17,19,20,17,19,20,19,20,22,22,22,23,21,23,25,22,23,25,26,24,27,27,25,27,27,28,28,28,27,27,28,28,28,28,28,28,29,29,29,28,28,28,29,28,28,29,29,28,29,28,28,28,28,28,28,28,28,27,28,28,28,28,28,27,27,28,27,26,27,27,26,26,27,26,24,25,26,23,24,24,23,22,23,23,23,22,20,24,23,22,24,24,25,25,23,23,26,23,25,26,26,27,26,26,26,28,26,26,27,26,27,27,26,27,27,27,25,27,26,24,25,26,23,25,24,25,24,24,25,23,24,23,25,24,24,26,25,25,26,26,25,26,27,25,24,26,25,25,24,24,24,23,23,23,23,24,23,22,22,23,23,23,23,22,22,21,22,22,21,21,21,19,20,19,19,18,17,16,17,16,13,13,15,14,12,11,11,12,10,9,9,9,6,4,4,3,2,1,0,1,2,4,4,6,8,6,6,8,8,9,11,11,13,12,13,15,16,15,16,17,16,15,17,18,16,15,18,18,16,15,18,19,18,20,15,18,16,19,17,14,16,17],[26,28,26,28,28,28,29,29,28,28,28,27,28,28,28,28,29,29,29,29,29,28,30,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,30,29,29,29,30,29,29,29,28,29,28,28,28,29,28,29,26,28,25,27,28,28,29,29,28,28,28,29,29,28,29,29,29,29,29,29,29,29,29,30,29,28,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,30,30,28,29,29,28,29,29,28,28,29,28,26,29,28,26,27,28,26,25,25,26,28,26,29,28,27,28,28,28,27,29,29,28,28,29,29,28,29,28,29,29,30,29,29,30,29,30,29,30,29,29,29,29,29,29,29,28,27,28,28,27,25,26,26,26,27,24,24,24,26,23,24,24,24,24,24,24,23,24,24,25,26,25,24,27,27,26,25,28,28,28,29,27,28,28,28,27,26,29,27,26,28,28,26,26,28,28,26,26,28,26,25,27,28,26,26,27,27,28,28,28,27,28,26,26,27,26,24,24,25,24,23,23,24,24,23,22,22,22,20,22,22,20,18,19,22,22,22,21,22,21,21,24,22,23,22,24,24,24,24,25,25,24,26,27,25,27,26,28,27,24,25,27,24,23,24,26,24,23,24,24,24,22,25,26,25,27,25,23,25,24,23,23,24,24,22,23,24,23,20,24,23,24,24,24,24,26,25,25,27,27,26,27,27,28,27,28,26,28,29,29,29,28,29,29,29,29,29,29,28,29,29,29,29,30,29,29,30,30,29,30,30,30,30,29,29,29,29,28,28,29,29,28,28,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,29,30,29,30,29,29,29,29,29,28,29,26,27,28,26,27,28,25,26,26,25,24,24,24,24,25,25,23,24,24,23,22,23,23,23,24,23,23,25,24,25,24,24,23,22,23,21,22,23,23,23,22,25,26,23,26,26,25,24,25,25,25,24,24,25,24,23,24,23,23,24,24,23,23,21,22,23,21,19,21,19,18,18,17,14,14,15,13,11,10,14,14,13,13,16,18,18,21,19,21,20,20,20,19,18,20,18,18,18,18,18,19,19,19,21,22,22,21,22,24,24,23,25,25,25,26,27,27,28,28,27,28,28,27,27,28,25,26,27,27,28,27,27,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,29,28,29,28,29,28,29,27,27,28,27,25,26,26,24,23,25,24,22,22,24,23,21,21,22,20,19,20,20,21,21,21,19,21,23,22,20,23,24,24,23,24,24,25,25,24,26,27,27,28,29,28,28,29,29,29,28,28,29,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,29,29,29,29,29,29,29,29,29,28,28,29,29,29,28,28,28,27,28,27,26,26,28,27,24,25,27,24,23,25,25,26,24,25,25,25,26,26,24,25,27,25,27,27,25,28,28,28,27,28,28,28,28,28,28,28,28,28,28,28,28,28,27,28,28,26,25,28,26,25,26,26,25,25,27,26,27,27,28,27,27,28,27,28,28,28,27,28,28,27,28,27,27,26,25,26,25,24,25,23,24,26,26,26,23,25,24,25,25,24,25,23,26,25,24,24,23,24,20,22,21,21,19,18,19,18,17,14,16,15,13,12,12,13,13,11,10,10,8,6,6,5,3,3,1,0,1,3,3,5,7,5,4,7,7,7,9,8,12,12,15,17,17,14,15,19,17,15,20,20,16,16,21,19,17,15,19,20,18,21,16,19,17,20,18,16,17,18],[27,28,27,28,28,28,29,29,29,28,28,28,29,28,29,28,29,28,28,29,29,29,30,30,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,29,29,29,30,29,29,29,28,29,28,29,28,29,28,29,29,29,28,28,27,28,29,29,28,29,29,29,28,29,29,28,29,29,29,29,28,29,29,29,29,30,29,28,29,30,29,29,30,29,28,29,29,29,28,28,29,29,29,29,29,29,30,29,30,29,28,29,29,27,27,28,28,26,28,28,24,26,29,25,25,26,25,28,25,29,28,26,28,29,28,26,29,29,27,29,29,29,28,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,28,28,28,28,24,26,27,25,26,24,25,25,27,24,25,26,24,24,25,26,24,26,25,26,27,26,25,27,28,27,26,28,29,29,29,26,29,28,29,28,27,29,27,25,29,29,26,25,29,28,25,27,29,27,25,28,29,26,25,29,27,28,28,29,28,27,27,27,27,26,26,26,27,26,25,25,25,25,24,23,24,23,22,22,23,24,22,21,22,22,24,22,22,23,24,24,24,24,23,25,26,24,25,26,26,25,27,27,25,28,26,28,28,24,26,28,26,23,26,27,25,24,27,25,25,24,26,27,27,27,26,25,26,25,24,25,25,26,22,25,25,23,20,24,25,25,25,25,26,27,27,26,27,27,28,28,28,28,28,28,28,28,29,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,29,29,29,28,29,29,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,27,28,28,27,27,27,26,27,27,27,27,25,26,25,25,24,24,24,24,24,26,23,23,25,25,25,25,26,26,25,25,23,23,22,23,21,23,24,24,24,24,24,25,24,26,26,27,25,25,26,26,25,26,27,25,26,26,27,25,24,25,24,22,21,23,23,20,20,21,19,18,19,19,14,13,15,14,10,11,14,16,14,13,18,18,19,23,21,22,22,21,20,19,20,21,17,18,20,19,19,21,20,23,23,21,24,23,24,25,25,25,27,27,27,27,28,28,28,28,27,29,29,28,28,28,27,26,28,28,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,28,28,29,29,28,28,29,28,26,27,27,24,25,26,25,23,24,25,24,21,24,23,21,20,21,18,18,22,21,19,21,24,23,22,24,24,24,23,24,25,26,26,26,27,28,28,29,28,27,28,28,28,29,29,28,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,30,28,29,29,28,28,28,29,29,28,29,29,29,29,29,28,29,29,29,29,28,29,29,28,28,28,28,27,28,27,26,26,27,26,24,26,26,26,25,25,25,25,26,26,26,27,27,26,27,27,27,28,28,28,28,28,28,29,28,29,29,28,28,28,27,29,28,28,28,28,28,27,27,28,27,26,27,27,26,26,27,26,27,27,27,27,26,27,28,27,28,28,27,27,28,28,26,27,28,28,27,26,26,25,25,26,25,26,26,25,26,26,26,26,25,25,24,24,24,24,24,24,23,24,21,22,21,22,21,19,19,19,17,15,18,17,13,13,14,15,12,10,10,9,8,7,6,5,5,4,3,1,0,1,2,4,5,3,4,5,7,6,8,7,10,12,12,15,15,13,13,17,16,14,19,19,16,16,19,18,16,16,18,20,17,19,17,17,16,19,16,15,16,17],[26,27,26,26,27,28,28,28,29,27,28,28,28,28,28,28,29,29,28,29,29,28,29,29,29,29,29,29,29,29,29,30,30,30,29,30,29,30,29,30,30,29,29,30,30,30,29,29,29,29,29,29,29,29,28,28,29,28,28,28,28,27,27,27,28,27,28,28,28,28,28,27,28,26,27,27,28,28,28,28,28,27,28,28,28,28,28,28,28,28,28,28,28,29,29,28,28,29,29,28,29,29,29,28,29,29,29,29,28,29,28,29,28,29,29,29,29,29,29,28,29,28,27,28,28,27,26,29,28,25,26,28,25,24,26,25,27,27,28,28,27,27,28,27,27,28,28,27,28,29,28,28,28,28,28,28,29,28,28,28,28,28,28,28,28,28,29,28,28,28,28,28,26,28,28,27,26,27,26,26,27,25,24,26,26,22,24,26,24,24,25,25,23,23,25,25,26,25,24,26,27,26,25,26,28,27,28,27,27,27,28,27,26,28,26,27,28,28,26,26,27,27,24,27,28,26,24,27,27,25,25,27,26,27,27,28,27,27,27,26,28,27,26,26,26,25,25,26,24,24,23,22,23,24,22,23,22,20,19,22,21,22,21,22,22,21,22,23,22,22,23,23,26,24,24,24,22,25,25,26,26,27,26,27,27,25,26,27,25,24,26,26,24,23,25,25,24,23,24,26,26,26,25,24,26,25,23,25,25,25,23,24,24,24,22,26,25,25,25,25,24,26,25,25,26,27,27,27,27,27,27,27,26,27,27,27,27,27,28,27,27,28,27,28,28,28,28,28,28,28,29,28,28,29,29,29,29,28,29,28,28,28,27,26,27,28,27,28,28,28,28,28,29,29,29,29,29,29,29,29,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,27,28,26,27,27,26,27,27,26,27,27,26,26,24,24,26,25,24,24,24,24,24,25,23,23,24,23,24,23,27,26,24,25,24,23,22,23,21,24,23,24,24,23,24,25,24,26,26,26,24,25,26,26,25,25,26,25,24,25,25,24,24,24,23,23,23,22,22,21,21,21,19,20,19,18,16,15,15,14,13,11,15,16,16,15,18,22,20,22,22,21,20,20,19,20,20,19,19,20,20,19,18,20,19,22,20,22,21,22,22,22,23,22,25,25,24,26,27,26,27,27,26,27,28,26,27,28,25,26,26,27,27,27,27,28,28,28,28,28,27,28,28,28,27,27,28,27,27,28,28,27,28,28,28,28,28,27,27,28,28,26,27,28,27,24,25,26,23,23,25,24,22,23,23,23,23,23,22,21,20,18,20,20,21,20,19,21,21,22,21,22,21,22,23,21,24,24,25,24,26,27,27,28,28,26,27,27,27,28,28,28,28,28,28,28,28,29,28,28,28,28,28,29,28,28,28,28,28,28,28,28,28,27,28,27,27,27,28,28,27,28,28,28,28,28,27,28,28,28,28,27,27,28,27,27,26,26,27,27,27,25,25,26,24,23,24,25,25,24,23,24,23,24,24,24,26,25,24,27,26,26,26,26,27,27,27,28,27,27,27,28,26,27,27,26,28,27,28,27,27,27,27,26,27,27,25,25,26,25,26,27,25,27,26,27,27,26,27,26,27,27,27,26,26,27,26,26,27,27,28,26,26,26,25,24,25,25,26,25,25,25,25,25,25,25,25,24,23,25,24,24,22,23,22,21,21,21,19,20,18,19,18,16,15,18,17,14,15,14,15,14,12,11,10,8,6,6,5,5,4,3,2,1,0,1,2,3,3,4,4,6,7,7,8,10,10,11,14,13,12,14,15,15,14,17,16,15,14,18,17,14,13,18,19,16,18,15,16,15,18,16,14,15,17],[26,26,26,27,27,28,27,28,28,27,27,27,28,27,28,28,29,28,28,29,29,29,29,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,29,30,29,29,29,28,29,29,28,29,28,29,29,29,29,29,28,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,30,29,30,30,30,29,30,30,30,29,30,30,29,29,30,29,29,29,29,29,30,30,29,30,30,29,30,30,29,30,29,29,29,29,29,29,30,29,27,27,30,27,27,28,28,29,27,30,29,28,29,30,29,28,30,29,29,29,30,30,29,29,30,29,29,30,29,29,29,30,29,30,30,29,30,29,29,30,30,29,30,28,29,29,29,27,29,29,27,29,26,25,27,28,25,27,28,27,26,27,27,27,26,27,27,28,28,27,28,29,28,29,28,29,28,29,28,29,29,29,28,27,29,28,28,30,29,28,27,29,29,27,28,29,29,27,30,30,29,28,30,29,30,29,29,29,29,29,29,29,29,28,28,28,28,27,27,27,26,26,24,25,26,25,25,26,25,22,25,23,24,25,24,25,25,25,26,26,26,26,27,27,27,27,28,26,26,29,28,27,29,28,29,29,27,27,29,28,26,28,29,27,26,28,27,26,26,27,29,28,29,28,26,28,27,26,26,27,26,25,26,25,26,24,26,25,27,27,26,27,28,28,27,27,28,28,28,28,28,28,28,28,28,28,29,29,27,28,28,29,29,28,28,28,28,29,29,29,29,28,30,29,29,29,30,29,30,30,30,29,29,28,28,29,29,29,29,28,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,27,28,28,27,28,28,27,28,28,27,27,27,26,27,25,24,25,24,25,24,25,24,24,26,25,24,25,27,26,23,25,23,23,22,23,20,24,23,25,24,24,24,26,23,27,27,28,26,25,28,27,26,27,28,27,26,27,26,26,26,26,24,26,24,24,24,23,22,21,19,21,19,19,14,15,15,14,13,12,14,16,15,14,17,19,20,23,22,24,23,24,22,22,22,23,21,22,22,21,21,23,22,25,24,23,24,25,25,26,26,26,28,28,28,28,28,28,29,29,29,28,29,28,29,29,27,28,28,27,29,28,29,29,29,29,30,30,29,29,29,29,28,29,29,28,29,30,29,29,29,29,29,29,29,28,28,29,29,28,29,29,28,27,28,28,26,26,27,26,26,26,26,25,24,25,23,23,21,22,21,21,22,23,21,23,25,25,23,24,25,24,25,24,26,26,26,27,28,28,29,29,28,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,29,30,29,29,29,29,28,29,29,28,28,28,28,28,28,28,29,29,29,30,28,29,29,29,30,29,29,29,28,29,29,27,27,29,28,28,27,28,27,27,27,27,26,25,25,25,26,26,26,26,27,27,26,27,27,27,28,27,28,28,28,28,29,28,28,30,29,29,28,29,29,29,29,29,29,28,28,27,28,28,28,28,28,27,27,27,26,26,26,27,28,27,27,27,28,28,28,28,28,28,28,28,28,29,29,29,26,28,25,26,27,26,26,26,26,27,26,27,26,25,25,24,25,25,25,24,23,22,25,23,23,23,21,24,19,23,20,20,16,19,18,15,15,14,16,15,11,12,10,8,8,7,6,6,5,4,3,3,1,0,1,2,3,3,2,4,5,5,5,7,7,9,12,13,10,10,14,13,11,15,14,13,13,15,14,13,12,15,16,15,17,15,16,13,17,15,12,14,15],[25,27,26,26,27,28,28,28,28,27,28,27,28,28,28,28,28,28,28,28,28,28,29,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30,29,29,29,28,30,29,29,29,29,29,29,29,30,29,29,28,28,29,29,28,29,29,29,28,30,30,29,29,29,29,30,29,29,29,29,29,29,29,30,29,29,30,30,30,29,29,29,30,30,29,29,29,29,29,30,30,30,30,29,30,30,29,30,29,28,29,29,29,28,30,29,27,28,29,28,25,27,26,28,28,29,29,28,28,29,29,28,29,29,28,29,29,29,29,30,29,29,29,30,29,30,28,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,26,27,27,26,27,28,26,26,28,27,25,27,28,26,25,27,25,27,27,26,27,28,27,27,28,29,28,29,28,29,29,29,28,29,29,28,28,29,29,27,28,29,28,28,28,29,28,27,29,30,28,27,29,28,29,29,29,29,29,28,28,27,28,26,27,27,27,25,26,26,26,26,25,26,25,24,24,23,23,21,24,24,23,24,24,24,25,25,26,26,25,25,25,27,25,25,27,25,26,27,27,27,28,28,29,28,27,27,28,27,26,27,28,26,25,27,26,26,26,27,28,27,28,27,26,27,27,26,25,27,26,24,25,25,26,22,25,24,26,27,25,26,28,28,27,28,28,29,28,28,29,29,29,28,29,29,29,29,29,29,28,30,29,28,29,29,29,29,30,30,29,30,30,29,29,29,30,30,29,30,29,30,30,29,29,30,30,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,28,29,28,29,29,29,28,28,28,27,27,26,26,25,26,24,25,25,24,25,27,24,24,26,26,23,25,27,27,26,26,24,23,23,22,19,25,23,24,25,24,26,27,25,28,27,29,27,26,28,28,25,27,28,26,25,26,27,24,25,25,23,24,22,23,24,24,21,22,20,19,18,19,17,15,14,14,14,13,14,15,15,15,16,21,21,24,23,23,22,22,22,22,22,21,21,23,21,21,20,20,21,20,21,23,25,25,24,25,26,25,27,28,27,28,28,27,29,29,28,28,29,27,29,29,27,28,28,28,29,27,29,30,29,30,30,30,28,29,29,29,28,28,29,28,28,29,28,29,29,29,29,29,30,29,29,29,29,28,29,29,28,27,27,27,26,25,27,26,25,25,25,24,24,23,23,24,23,22,20,21,22,24,20,22,23,22,22,25,24,24,25,25,26,27,28,27,27,28,29,29,29,28,29,28,29,29,29,28,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,28,29,29,29,29,28,29,29,29,29,29,29,29,28,28,29,28,28,28,28,28,27,28,27,26,27,26,26,25,25,25,25,27,27,27,28,28,28,28,28,28,28,28,29,28,28,29,29,28,28,29,29,29,29,28,29,29,29,29,29,28,28,27,28,28,27,27,28,27,27,28,27,28,28,29,28,27,28,28,28,28,29,28,28,29,28,28,28,28,29,28,28,27,27,26,26,26,27,28,26,26,27,26,28,26,26,26,26,27,26,25,23,24,24,23,21,22,23,22,19,21,21,20,15,19,19,15,15,17,17,16,13,13,11,10,9,8,7,7,6,4,4,3,2,1,0,1,1,1,1,2,3,4,4,6,6,9,9,11,8,9,12,12,10,14,14,11,11,16,13,12,10,13,16,14,16,13,16,15,18,16,13,15,16],[25,25,25,25,26,27,26,27,26,26,26,26,27,27,27,27,28,28,28,28,28,28,28,29,28,29,29,29,29,29,29,29,30,30,29,29,29,29,30,30,30,29,29,29,30,30,29,29,29,29,29,29,29,30,29,29,29,29,29,28,29,28,28,27,28,28,28,29,28,29,29,28,28,27,27,28,29,28,29,29,27,28,29,28,28,29,29,30,30,29,29,29,29,29,29,29,29,29,30,29,29,29,30,28,29,29,29,28,28,29,29,29,29,29,29,30,28,30,29,28,29,29,27,28,28,28,27,29,28,26,28,29,26,24,28,27,28,27,29,29,27,28,29,28,27,29,28,27,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,28,28,28,28,27,28,28,26,28,26,26,27,27,25,26,27,26,25,26,26,26,26,26,26,27,27,26,28,29,27,27,28,29,28,29,28,29,29,29,28,28,29,27,27,28,28,26,27,28,28,26,28,28,27,26,28,29,27,26,28,27,29,28,29,28,28,28,27,28,28,26,26,27,27,27,25,25,24,25,24,25,25,24,25,25,24,22,24,25,23,24,24,23,24,25,25,24,26,25,26,27,25,25,27,26,26,27,27,26,28,28,28,28,26,27,28,26,25,26,28,25,26,26,26,26,25,26,27,27,28,27,26,27,26,25,26,26,24,24,24,23,23,22,23,22,24,25,25,26,27,27,27,27,27,28,28,28,28,28,27,27,27,29,28,28,28,28,27,28,27,28,28,28,29,29,29,28,28,28,29,29,28,29,29,29,29,29,29,28,28,29,27,28,28,28,29,29,28,29,29,28,29,29,30,30,30,29,30,29,29,29,29,30,30,30,29,30,29,30,29,30,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,28,29,29,28,28,27,27,27,26,27,28,27,28,27,27,27,26,26,25,25,24,24,23,23,24,26,22,22,26,25,23,24,27,26,24,25,22,21,20,22,20,22,21,22,22,23,23,26,23,27,26,27,26,24,27,27,24,26,28,26,25,26,26,24,25,24,22,23,22,21,21,23,21,19,19,20,18,19,17,17,15,14,15,14,14,15,15,15,18,20,22,22,24,22,21,21,22,21,21,22,21,22,20,22,20,22,23,23,23,23,24,24,23,25,26,26,27,27,28,27,27,27,29,28,29,28,28,28,28,28,27,28,28,28,29,28,28,29,29,29,29,29,29,28,29,29,28,29,29,28,28,29,29,28,29,29,28,29,29,27,28,29,28,28,28,28,27,27,27,27,26,26,27,25,25,25,25,24,24,23,21,22,21,19,22,21,20,22,21,22,23,24,23,24,24,23,25,25,26,26,27,27,27,27,28,28,28,28,28,28,28,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,28,29,28,28,28,28,28,28,29,28,28,28,28,28,28,29,28,28,29,29,28,28,28,28,28,28,28,27,27,28,26,27,27,26,27,26,26,25,24,26,24,25,26,26,26,27,27,26,27,27,27,27,26,27,28,28,28,28,28,28,28,29,28,28,28,28,28,28,28,28,28,27,28,27,27,27,27,27,26,26,28,26,25,25,25,26,26,25,27,27,28,27,27,27,28,28,27,28,26,28,28,26,25,26,25,25,26,25,25,25,25,27,25,26,26,25,26,25,25,25,25,24,21,22,23,22,22,21,21,22,20,20,19,20,18,18,18,16,17,17,17,17,13,13,12,11,10,7,8,7,6,5,4,3,2,2,1,0,1,2,2,2,3,4,4,5,6,7,8,10,8,8,12,10,11,14,12,10,12,14,12,11,12,16,12,13,15,15,14,14,16,14,12,14,16],[26,27,26,27,27,28,28,28,28,28,28,27,28,27,28,28,28,28,28,29,29,29,29,29,29,29,29,28,29,30,29,30,30,30,29,30,29,29,30,29,30,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,28,28,29,28,28,27,28,27,28,28,28,27,28,27,28,26,28,26,26,28,28,27,29,28,28,27,28,28,28,28,28,28,29,28,29,29,28,29,29,29,28,29,30,29,29,29,29,29,28,29,29,28,28,29,29,29,29,28,29,30,28,30,29,29,29,28,27,28,28,28,27,29,28,26,27,29,26,26,27,28,29,27,29,29,27,28,29,28,28,29,29,28,28,29,29,28,28,28,28,28,29,29,28,29,29,28,29,29,29,28,29,28,28,28,29,29,27,28,29,28,26,27,27,27,28,26,25,27,27,25,26,27,25,25,27,27,25,26,27,28,28,28,26,28,29,28,27,28,29,28,28,27,28,27,29,28,27,29,28,27,28,29,27,26,28,28,26,27,28,27,26,27,28,26,26,28,27,27,29,29,27,29,28,27,27,28,26,27,27,26,25,26,25,26,25,23,24,26,25,24,25,25,23,24,24,23,23,24,23,24,24,25,24,24,25,26,26,25,26,27,27,26,27,27,26,28,25,27,28,26,26,27,25,24,25,27,25,24,25,26,26,24,26,27,25,27,26,25,26,26,25,25,25,25,24,25,25,26,22,26,24,25,26,25,26,27,27,26,26,27,27,27,26,28,27,27,27,28,28,28,29,28,28,29,28,28,28,28,28,29,29,29,28,29,29,29,29,29,29,29,30,30,30,29,29,29,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,29,30,29,30,30,29,29,29,29,30,29,30,30,29,29,30,29,29,28,26,28,28,27,27,28,26,27,27,27,26,25,25,26,25,25,23,23,23,24,25,23,24,26,25,25,25,26,27,25,26,23,23,22,22,21,24,22,24,24,24,25,27,24,27,27,28,26,25,27,27,25,27,28,25,26,27,25,25,24,25,23,24,23,23,24,23,21,21,19,17,19,19,15,16,16,14,13,16,14,16,16,14,18,20,21,24,24,24,24,23,24,23,22,22,21,23,22,21,23,23,22,24,24,22,22,25,24,23,24,23,25,25,26,27,27,27,28,28,28,28,28,28,29,28,27,27,28,27,28,28,27,28,29,28,29,29,28,28,29,28,28,28,28,27,28,28,28,29,29,29,28,28,29,27,27,28,28,27,27,27,26,25,26,26,24,24,25,24,23,23,24,23,23,24,23,22,22,21,21,21,22,22,21,21,23,24,22,22,23,25,24,23,24,26,26,25,26,27,28,27,27,27,28,28,27,28,29,28,28,29,28,28,28,28,28,29,29,29,28,29,28,29,28,29,29,29,28,28,28,28,27,27,28,27,27,27,27,28,28,28,28,28,28,27,28,28,28,27,28,28,27,28,27,26,26,27,26,25,25,25,25,23,25,25,24,24,23,25,24,25,24,26,26,27,27,27,27,26,27,28,28,26,27,28,28,27,27,28,27,27,28,27,27,27,27,27,27,27,26,26,27,26,25,26,27,27,27,27,27,27,27,27,26,26,28,27,26,28,27,27,27,28,27,27,27,27,27,27,25,26,25,25,25,26,24,27,26,26,26,26,27,26,26,25,25,25,24,24,24,23,23,21,23,22,21,22,22,20,20,21,19,19,20,17,17,15,17,16,13,13,12,9,9,7,8,7,5,5,4,4,3,3,2,1,0,1,2,2,2,3,4,5,6,6,8,9,7,8,12,11,9,14,12,10,11,14,12,11,12,15,15,13,16,14,14,13,17,14,12,13,16],[25,26,26,27,27,28,29,29,28,28,28,27,29,28,29,28,29,29,28,29,29,29,29,30,29,30,30,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,29,29,29,29,29,29,29,28,29,28,29,28,28,28,29,28,29,27,28,26,26,28,29,28,29,28,27,28,29,28,27,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,30,30,29,29,29,29,29,30,29,30,30,29,30,29,29,30,29,28,28,29,29,27,29,29,26,27,29,26,25,26,26,28,27,29,29,27,28,29,28,27,29,29,28,28,29,29,28,29,29,29,29,30,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,27,28,29,28,25,27,27,26,27,25,24,26,27,24,25,26,25,24,25,25,24,25,26,26,28,27,24,28,28,27,26,28,29,28,29,28,28,28,29,28,27,29,28,26,28,29,27,26,28,28,26,26,28,27,25,27,28,26,26,27,27,28,28,29,27,28,27,27,27,26,25,26,26,25,24,25,25,25,24,23,24,24,23,23,24,22,22,22,22,23,23,23,23,23,23,25,24,24,24,26,25,24,24,26,25,25,27,27,26,28,26,28,27,25,25,27,25,25,24,26,25,25,25,25,25,24,26,27,25,27,26,24,25,26,24,24,25,26,23,25,25,26,23,25,23,25,25,24,26,26,26,25,26,27,27,27,28,28,27,28,27,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,30,30,29,30,30,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,27,29,28,27,28,28,26,27,26,26,25,25,25,26,24,24,25,25,24,24,26,24,23,25,26,25,24,27,26,24,24,22,23,22,22,19,24,23,24,24,24,23,26,25,26,27,28,25,25,28,27,25,26,27,25,25,26,26,25,25,25,23,24,22,24,24,22,20,23,20,20,19,21,17,15,15,14,14,14,14,16,15,15,18,19,20,23,23,23,22,21,23,22,22,21,20,21,20,20,20,22,22,22,23,23,24,23,25,25,24,24,27,26,26,27,27,27,28,28,27,28,29,27,28,28,27,27,27,27,28,28,27,29,29,29,29,29,29,28,29,29,28,29,29,28,28,29,29,29,29,29,29,29,29,28,28,28,28,27,27,27,26,24,25,26,25,24,25,25,24,23,24,24,23,22,23,23,21,22,22,22,22,24,22,22,22,23,22,23,24,25,25,23,25,26,26,26,26,27,28,27,28,28,28,28,28,29,29,28,28,29,29,29,28,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,28,28,29,29,28,28,29,28,28,29,29,29,29,29,29,28,29,28,28,28,28,27,27,27,28,25,26,27,27,25,26,26,24,24,25,25,25,24,26,25,25,26,26,25,26,27,27,27,28,26,28,28,28,27,28,28,28,28,29,28,28,28,28,27,27,28,27,26,28,27,26,25,28,26,25,26,28,25,26,27,27,28,28,27,27,28,28,28,28,28,28,27,28,28,26,28,28,28,26,27,26,26,26,25,24,27,25,27,27,26,27,26,28,27,25,26,25,26,25,24,23,23,24,22,21,20,22,21,18,20,20,18,14,20,17,15,15,16,16,16,13,12,12,11,9,8,6,6,6,6,4,3,3,2,2,2,1,0,1,2,2,3,3,5,5,6,8,9,7,8,10,10,9,12,12,10,10,15,13,11,11,14,16,13,17,12,14,15,18,15,14,16,16],[26,26,26,26,26,27,27,27,27,28,27,27,28,28,28,28,28,28,28,29,29,28,29,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,29,28,29,28,28,28,28,29,29,29,29,28,28,28,28,28,28,28,29,29,29,29,29,30,29,29,29,29,29,30,29,29,30,29,29,29,30,29,29,29,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,27,29,29,27,27,29,27,27,26,25,28,28,29,28,28,29,29,28,27,29,29,28,29,29,29,28,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,27,28,27,26,28,26,25,26,28,26,27,26,27,26,26,27,27,26,27,26,27,28,27,28,29,28,27,27,29,29,29,28,29,29,29,28,28,29,28,27,29,29,27,28,29,28,28,28,29,27,27,29,29,27,27,28,28,28,29,29,29,28,28,28,28,28,27,27,28,27,26,27,27,26,27,25,26,24,25,24,24,25,22,26,25,25,26,25,26,26,26,27,26,27,26,26,27,27,26,26,26,26,27,27,27,28,28,29,28,27,27,28,27,27,26,28,27,26,26,27,26,25,27,27,27,28,27,26,27,27,25,25,26,26,25,26,26,24,22,24,23,25,27,25,27,28,27,27,28,28,28,28,29,29,28,28,28,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,30,30,29,29,30,30,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,29,29,30,29,30,29,29,27,28,28,27,28,29,27,28,28,27,28,26,26,26,24,23,26,25,23,24,26,24,22,26,26,24,24,27,27,24,25,24,23,22,21,19,23,23,22,23,25,25,25,25,28,27,28,26,26,28,27,25,27,27,26,25,27,27,24,26,25,24,24,23,22,23,24,22,21,21,22,19,19,17,16,14,14,14,14,14,16,15,15,19,20,22,23,24,23,24,23,23,24,22,23,23,24,22,22,22,24,23,24,24,25,26,25,25,27,27,27,28,27,28,28,28,28,29,28,28,28,29,28,29,29,27,28,28,29,29,29,29,29,29,29,30,30,28,29,29,29,28,28,29,28,28,29,29,28,29,29,29,29,30,28,28,29,29,28,28,28,28,27,28,28,27,26,27,26,25,25,26,25,25,24,23,24,22,22,22,23,24,24,22,24,25,24,25,26,27,26,26,26,27,27,28,28,28,28,28,29,29,28,29,28,29,29,28,28,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,28,29,29,28,29,28,28,28,28,29,29,28,28,29,28,29,28,29,29,28,29,28,29,29,29,28,28,28,28,28,28,28,27,28,27,26,28,27,26,25,26,26,26,27,27,28,28,28,27,28,27,28,28,28,28,28,28,28,28,28,28,29,28,28,28,28,29,28,28,28,28,28,28,28,28,28,27,28,27,26,27,28,27,28,27,27,28,27,28,28,27,28,28,28,28,29,28,28,28,28,28,27,27,26,26,25,26,24,26,27,26,26,27,25,28,26,26,25,27,26,27,26,25,25,26,26,23,22,24,25,20,22,23,21,16,21,20,15,16,19,18,16,14,13,12,12,9,10,9,7,7,5,4,4,3,2,2,3,1,1,0,1,3,3,4,5,6,8,8,10,7,8,10,10,9,12,13,10,10,14,13,10,10,13,15,14,16,14,15,14,18,16,14,15,18],[25,25,25,26,26,27,27,27,27,28,26,27,27,27,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,29,30,30,29,29,29,29,29,29,29,28,29,28,28,28,29,29,29,29,29,28,29,28,28,29,29,28,30,29,29,29,30,29,29,29,29,30,30,29,30,29,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,29,29,29,29,29,30,29,30,30,29,30,30,29,29,29,28,29,29,29,27,29,29,27,28,30,27,26,28,28,29,28,30,28,28,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,30,30,30,30,29,30,29,29,29,29,29,29,29,29,29,27,28,28,27,29,27,25,28,29,25,26,28,27,26,27,28,26,27,28,27,28,28,27,28,29,29,28,29,30,29,30,28,29,29,29,29,28,30,29,28,29,29,28,28,29,29,27,28,29,28,27,29,29,28,27,29,28,29,29,30,29,29,28,28,28,28,28,28,28,27,27,27,27,25,26,26,25,25,23,25,25,24,23,25,25,25,25,24,25,26,26,26,26,26,26,27,28,26,26,27,27,28,28,28,27,29,28,29,29,27,28,29,27,27,28,29,27,26,28,27,27,26,27,28,28,29,28,27,28,28,26,27,28,26,24,27,26,25,22,24,25,26,27,27,28,28,27,28,28,28,28,28,28,29,28,28,28,28,29,29,28,28,28,28,29,28,28,28,28,29,29,29,29,29,29,29,29,29,30,29,30,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,30,29,30,30,30,30,29,30,30,30,30,30,30,29,29,30,29,29,29,27,28,28,28,27,28,28,28,28,28,28,26,27,26,25,24,26,26,25,26,26,25,25,26,27,26,26,26,27,26,26,23,24,22,24,22,23,24,24,25,26,26,26,26,27,27,28,27,26,27,27,27,27,28,27,26,28,27,26,26,26,24,25,24,23,23,23,23,21,20,23,21,20,18,20,18,16,16,16,16,18,18,17,21,22,23,25,23,25,25,24,24,23,24,23,22,24,24,23,21,24,25,25,25,24,26,25,26,27,27,26,28,28,27,28,29,28,29,29,29,29,29,28,29,29,28,28,29,29,29,29,29,29,30,29,30,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,28,29,29,29,27,28,28,27,27,28,27,25,26,26,26,25,25,24,24,23,22,22,22,24,23,22,23,25,26,25,26,26,26,27,26,27,28,28,28,28,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,30,30,30,29,30,29,30,29,30,29,29,29,30,29,29,29,29,29,29,29,28,29,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,27,28,28,28,27,26,28,26,26,27,26,26,26,27,27,27,28,28,27,28,28,28,29,28,29,29,29,28,29,29,28,29,28,29,29,29,29,29,29,28,29,28,28,28,29,27,28,28,28,27,28,28,26,27,27,28,28,27,28,28,28,28,29,28,28,29,28,27,28,28,29,28,27,28,26,26,27,26,26,26,25,27,27,27,27,26,27,27,26,25,26,26,25,23,25,24,24,23,23,24,24,22,22,22,20,21,20,18,19,19,19,19,15,16,14,13,12,10,9,10,8,8,6,5,4,4,3,3,2,2,1,0,1,2,3,4,6,6,6,9,7,7,10,10,9,13,13,9,11,14,12,11,10,14,13,13,14,14,15,14,16,15,12,15,17],[24,25,25,26,27,27,28,29,28,28,28,28,29,28,29,28,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,29,29,29,30,29,29,29,29,29,29,28,29,29,29,29,30,29,29,29,29,29,30,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,30,30,30,30,29,30,30,29,30,30,30,30,30,29,30,29,29,28,30,29,28,28,30,28,28,28,28,29,29,29,30,29,29,30,30,28,30,30,29,29,30,30,29,29,30,30,29,30,30,29,30,30,30,30,30,30,29,30,30,29,30,30,30,29,29,30,29,28,29,29,27,29,27,26,28,29,27,27,29,27,27,28,28,27,26,28,27,29,28,27,28,29,28,28,29,29,29,29,29,30,29,29,29,29,30,28,28,30,30,28,28,29,29,27,28,30,28,27,29,30,28,29,30,29,29,30,30,28,29,29,28,29,29,28,28,29,28,26,28,27,27,27,26,27,27,25,26,26,26,23,26,25,26,26,26,26,27,26,26,26,26,27,27,28,26,27,28,26,27,28,28,27,29,28,29,29,28,28,29,28,26,28,29,27,26,28,28,27,27,27,29,28,29,28,27,28,28,27,27,28,27,25,27,27,26,25,26,26,26,27,27,28,28,28,28,28,28,29,28,28,28,28,29,28,28,29,29,29,29,29,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,28,29,29,28,28,29,28,28,28,28,27,27,28,27,26,25,26,26,25,26,27,25,25,26,26,26,26,28,28,26,26,23,25,24,24,23,25,24,25,25,26,25,27,26,27,28,28,27,26,28,28,26,28,29,26,27,28,27,26,26,26,25,26,25,25,25,25,24,24,22,21,21,22,19,18,20,19,16,17,17,19,18,18,21,22,23,26,25,26,26,25,25,25,25,25,23,25,24,23,22,23,25,26,26,25,26,27,26,26,27,27,28,28,28,29,29,29,29,29,29,30,29,29,29,29,28,28,29,28,29,29,29,29,30,30,30,30,30,29,30,30,30,30,30,30,29,30,29,30,30,29,30,30,30,29,29,29,29,28,29,29,28,27,28,28,26,26,28,27,26,26,27,26,25,26,26,25,24,24,23,25,26,25,22,24,25,26,25,25,25,27,26,26,26,27,28,27,28,29,29,29,29,29,29,29,29,29,30,29,29,30,29,29,29,30,30,29,30,30,30,29,29,29,29,30,30,30,30,29,29,30,29,30,30,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,27,28,29,28,26,28,28,26,25,28,27,27,26,26,25,26,28,27,26,28,28,28,28,29,29,29,28,29,28,29,29,29,29,29,29,29,29,29,28,28,29,29,27,29,29,28,28,29,29,27,28,29,28,27,28,28,28,29,28,28,29,29,28,29,29,28,28,29,28,28,28,28,28,29,28,27,28,27,26,26,27,27,27,27,27,28,26,29,28,27,27,26,26,26,26,26,25,25,24,23,23,24,24,21,23,22,20,19,22,22,17,19,20,20,15,15,14,14,13,12,10,10,10,8,8,7,5,6,5,4,4,3,3,3,1,0,1,2,3,4,5,6,7,7,6,8,8,7,11,11,9,10,13,11,10,13,14,14,13,15,14,14,15,17,15,13,16,17],[24,25,24,25,26,26,27,27,26,27,26,26,28,27,28,28,29,28,28,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,29,30,30,30,29,30,30,30,31,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,31,30,30,31,31,30,31,31,30,31,31,30,31,31,30,30,30,30,30,30,30,29,30,30,28,28,30,28,26,29,27,30,27,30,30,28,30,30,29,28,31,30,29,30,30,30,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,28,30,29,27,30,28,26,27,29,27,26,28,28,27,27,28,27,25,27,27,28,28,26,28,29,29,28,29,30,30,30,28,30,30,30,29,28,30,28,28,30,30,27,28,30,30,28,29,30,29,28,30,30,29,28,30,29,30,30,30,30,30,30,29,30,30,29,29,29,28,27,28,28,26,26,26,26,25,24,26,26,24,22,25,25,26,26,25,26,27,26,25,27,27,26,25,28,27,25,27,27,26,28,28,27,30,28,30,30,28,28,30,28,27,29,30,27,27,29,28,27,26,28,29,29,29,28,27,29,29,26,28,28,27,25,28,28,26,24,25,26,28,28,28,29,29,29,28,29,30,30,29,30,30,30,30,29,29,30,30,29,29,29,29,30,29,29,29,29,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,30,29,30,29,29,29,27,28,27,26,26,27,28,26,27,28,27,25,27,27,27,27,27,28,27,27,25,25,25,25,23,25,25,26,27,27,27,27,27,28,29,29,28,28,29,29,28,29,29,28,28,29,28,28,27,28,26,26,25,25,26,25,25,23,24,23,22,22,21,21,20,17,18,16,16,19,19,18,21,23,23,25,24,26,26,25,24,24,25,24,22,23,24,24,20,22,25,24,23,25,27,25,25,27,28,26,28,29,28,28,30,29,30,30,29,30,30,29,29,29,27,27,29,29,30,29,29,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,27,29,29,27,27,29,28,26,27,28,25,25,26,26,24,23,24,24,24,24,25,23,25,25,25,24,26,27,25,25,26,28,29,28,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,28,29,30,29,28,29,29,28,26,29,28,27,26,27,25,28,28,28,27,29,29,27,28,29,29,29,29,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,30,30,29,29,30,29,28,29,29,28,28,29,28,29,28,29,29,29,29,29,29,30,29,29,29,30,29,29,29,30,30,29,28,28,28,28,28,28,28,29,28,28,28,27,28,28,27,27,27,26,26,26,25,24,26,25,24,23,24,25,22,23,23,21,20,22,20,18,20,20,19,16,16,15,15,14,13,11,11,12,9,9,8,6,6,5,5,5,3,4,4,2,1,0,1,2,3,4,5,6,5,6,7,7,7,10,9,8,10,12,9,9,11,13,12,11,14,14,14,15,15,15,13,16,18],[22,23,22,24,25,25,27,27,26,26,26,26,28,26,28,28,29,28,28,29,28,29,29,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30,28,29,29,29,29,28,29,28,28,29,27,28,27,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,28,30,30,28,28,30,28,26,28,27,28,28,29,29,29,29,30,29,28,30,30,29,29,30,30,29,29,29,30,29,30,30,30,29,29,30,30,30,29,29,29,30,29,29,29,29,29,29,30,30,28,29,29,27,29,27,25,27,29,26,26,28,27,25,26,28,26,25,26,26,28,28,26,28,29,28,27,29,29,29,29,29,29,29,30,29,28,30,29,27,29,29,28,27,29,30,26,27,29,29,27,28,29,28,27,28,28,29,29,29,28,29,29,29,29,29,27,28,28,28,26,28,26,26,26,26,26,24,24,24,26,24,23,24,24,26,25,25,25,26,25,25,26,26,25,26,28,25,26,28,26,26,28,29,26,29,27,29,29,26,26,29,27,25,27,28,26,25,28,28,26,26,27,28,26,28,27,26,27,28,26,25,28,27,25,26,27,27,25,26,25,27,27,26,27,28,27,27,28,28,28,28,28,28,28,28,28,28,29,29,28,29,29,29,30,29,29,30,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,29,29,29,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,30,28,28,29,28,28,28,28,28,28,27,28,27,26,27,26,26,25,28,27,25,25,28,26,25,27,28,26,26,28,27,27,27,25,25,24,25,24,25,25,26,26,26,26,27,26,28,28,29,27,27,28,28,27,28,28,27,27,27,27,26,26,26,25,26,25,25,26,26,24,26,24,23,23,24,22,20,21,20,18,17,19,21,19,18,22,23,24,26,24,26,26,25,25,24,25,25,23,24,22,23,21,23,25,25,25,25,26,26,26,26,26,26,28,27,27,29,29,28,29,28,28,28,29,28,29,28,27,27,28,28,29,29,28,29,29,30,30,30,29,29,30,29,29,29,29,30,29,30,29,29,30,29,29,29,29,29,29,28,29,27,28,29,28,25,27,28,25,25,27,27,25,25,26,26,24,25,25,25,24,25,23,25,25,25,25,25,25,25,25,26,26,26,26,25,26,27,27,27,28,28,29,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,29,29,29,29,29,30,29,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,28,28,29,29,29,29,29,28,28,28,28,27,28,28,27,26,27,27,25,25,27,26,26,26,27,26,26,28,27,26,28,28,27,27,28,28,29,29,29,28,28,29,28,28,29,29,28,28,28,28,28,28,28,27,28,28,27,27,28,27,26,27,28,27,27,28,28,29,28,28,28,28,28,28,28,29,28,27,28,28,27,27,28,28,28,27,27,27,27,26,25,27,27,27,27,26,28,26,28,27,27,27,26,26,26,25,25,25,26,25,25,23,25,24,22,23,24,21,19,23,21,18,19,21,21,17,16,16,16,14,13,11,11,13,9,10,7,6,7,6,5,5,5,4,4,4,3,1,0,1,2,3,4,4,4,4,6,6,6,8,8,6,8,10,8,7,8,12,11,9,14,11,13,14,16,12,11,16,16],[23,24,22,24,25,25,27,27,26,27,26,26,28,26,28,27,29,28,27,29,29,28,29,29,29,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,29,30,29,29,30,29,29,29,29,29,29,29,28,29,29,29,29,29,29,30,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,29,29,29,29,29,29,29,29,30,30,30,29,29,30,29,29,29,29,29,29,29,29,30,30,29,30,30,29,29,29,29,29,29,29,28,30,29,28,28,30,28,27,29,28,30,28,29,29,28,29,30,29,28,30,29,29,29,29,30,29,30,29,29,29,29,29,29,29,29,29,30,29,29,29,29,30,29,30,29,29,28,29,29,29,28,29,29,27,29,27,26,28,29,26,26,29,27,26,28,29,26,25,28,27,29,29,27,28,29,28,27,29,30,29,29,27,29,29,29,28,28,30,29,26,30,30,27,27,29,29,26,28,30,29,26,29,30,28,27,30,29,29,29,29,28,29,29,29,29,29,27,28,29,28,27,28,27,27,26,26,26,27,26,26,26,25,24,24,25,27,25,24,25,26,25,25,27,27,25,25,28,26,25,27,26,28,27,29,27,29,26,30,29,26,26,29,27,25,28,29,26,24,29,28,26,25,27,28,28,29,28,26,29,28,25,27,28,27,25,27,27,24,22,25,25,27,28,27,29,28,28,28,28,28,29,29,29,29,29,29,29,29,29,30,30,29,30,30,30,29,30,29,29,30,30,29,29,30,30,29,30,29,29,29,30,30,30,30,30,29,28,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,29,30,29,29,29,29,30,30,29,30,30,30,30,30,30,29,29,30,29,29,30,29,28,29,28,28,28,29,28,29,29,29,28,28,28,26,24,24,27,26,25,25,27,26,25,27,27,27,26,27,28,26,27,24,25,25,24,23,26,26,26,25,27,26,27,26,28,27,29,27,27,27,28,27,28,29,27,27,28,27,26,27,26,26,25,23,25,24,24,24,24,23,22,23,22,21,20,20,19,18,17,18,20,21,18,23,24,23,26,24,27,26,25,24,24,24,23,22,24,24,23,22,23,24,24,24,24,26,26,25,26,26,26,27,28,27,28,29,28,30,30,27,29,29,29,29,28,27,26,29,28,30,28,29,30,29,30,30,30,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,27,28,30,28,26,28,28,25,25,28,27,24,25,28,25,23,25,26,24,24,24,23,22,25,23,22,24,26,25,23,25,26,25,25,26,26,26,26,26,28,28,29,28,29,28,29,29,29,29,29,29,29,30,29,30,29,30,29,29,29,29,29,30,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,29,29,28,29,28,29,29,30,29,29,29,29,28,29,29,27,27,29,29,26,27,28,26,25,28,27,26,25,26,25,26,28,26,26,29,29,27,27,29,28,29,29,28,28,29,29,29,29,29,29,29,28,29,29,29,29,29,27,29,29,28,27,29,29,26,28,29,27,26,27,27,28,28,28,28,28,29,28,28,29,29,29,28,29,28,28,28,29,29,29,28,27,27,27,27,27,27,28,27,27,28,26,28,27,26,27,26,26,26,25,24,23,26,24,23,23,24,23,23,23,22,22,20,22,21,18,20,22,21,17,17,16,16,15,15,12,13,14,9,10,9,6,8,6,6,6,4,4,4,4,3,2,1,0,1,2,3,3,3,4,4,4,5,7,6,5,6,8,6,6,8,10,9,9,11,11,12,14,13,13,12,15,16],[23,24,23,24,25,25,27,27,26,27,27,26,28,27,29,28,29,29,28,30,29,29,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,29,30,30,29,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,28,29,28,30,29,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,27,30,30,28,28,30,29,27,28,29,27,27,28,27,29,29,28,29,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,30,30,29,30,30,30,29,30,29,29,29,30,30,29,29,29,30,30,29,30,30,29,28,29,29,28,27,28,28,26,26,25,25,25,25,25,26,27,27,26,26,28,28,27,28,28,27,27,29,28,28,29,28,28,30,30,29,30,29,30,30,29,29,30,29,28,29,30,29,28,29,29,29,27,29,30,29,29,29,28,29,29,28,28,28,28,26,28,28,27,25,27,26,28,28,27,29,29,29,28,29,29,29,29,30,30,29,29,29,30,30,29,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,30,30,31,31,31,31,31,31,30,31,31,30,30,29,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,30,29,29,29,29,29,28,29,27,27,26,28,28,26,27,29,28,27,29,29,27,27,29,29,28,27,26,26,26,24,24,26,26,26,27,27,27,28,28,29,29,29,29,29,29,29,28,29,30,29,28,29,29,27,28,27,28,27,27,26,27,27,26,26,25,25,25,25,22,21,22,20,20,18,20,22,21,18,23,24,24,25,25,26,27,27,25,25,27,25,23,25,25,24,24,26,26,27,27,27,27,28,28,29,28,28,30,29,29,30,30,29,30,29,30,29,30,29,29,29,29,29,29,30,30,30,30,30,30,30,31,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,28,29,30,29,28,29,29,28,28,28,28,27,28,27,26,25,25,25,25,27,27,25,27,27,27,27,28,28,27,28,28,29,28,29,29,29,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,28,28,29,28,27,26,28,27,28,29,28,28,29,29,28,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,28,30,29,28,29,29,28,29,29,29,30,29,29,30,30,30,29,29,29,30,29,29,30,29,29,30,29,29,29,28,28,29,27,27,28,28,29,28,27,28,28,28,28,27,27,29,27,28,26,27,27,26,27,24,25,26,27,23,24,24,22,20,23,23,19,20,21,21,18,17,18,17,15,14,12,12,14,11,11,10,8,9,7,7,7,6,5,5,4,4,3,2,1,0,1,2,3,2,4,4,4,4,5,5,4,5,7,6,5,5,7,8,8,11,9,11,13,15,12,12,14,14],[22,24,24,25,25,25,26,27,26,27,27,27,28,26,28,27,28,28,28,29,29,28,30,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,30,29,29,29,29,29,29,29,28,29,29,29,29,28,29,28,28,28,28,28,28,28,29,28,28,29,29,29,29,29,29,29,28,29,29,30,29,29,29,29,28,29,30,29,29,30,29,29,29,30,29,29,30,30,29,29,29,29,29,29,29,29,29,29,29,29,30,29,28,30,29,29,29,29,29,29,28,29,29,29,28,29,28,29,28,29,29,28,29,29,29,28,30,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,29,28,29,29,29,28,29,29,29,29,30,29,29,29,27,29,28,27,28,29,27,27,29,28,27,28,29,27,27,28,28,29,28,27,29,29,29,28,29,30,30,30,28,30,28,29,29,27,29,28,27,29,29,28,28,28,29,27,28,29,29,28,29,29,29,27,29,28,29,28,29,28,28,28,29,28,29,29,28,29,29,28,28,28,26,27,26,26,24,26,27,27,25,24,25,25,27,25,26,27,28,26,27,27,27,27,27,28,28,27,28,28,27,28,29,27,29,27,29,29,27,28,29,28,26,27,29,27,26,29,29,27,26,27,29,27,28,28,27,28,28,27,26,27,27,25,27,27,24,23,25,25,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,30,30,29,29,30,29,29,30,30,29,30,30,30,30,29,30,29,29,29,30,29,29,29,28,28,29,29,28,29,28,28,29,29,30,29,29,30,30,29,30,29,29,29,29,29,29,30,30,30,30,29,30,29,30,29,29,29,29,30,29,30,30,29,30,30,30,30,29,29,30,29,30,29,29,29,28,29,28,29,28,28,29,28,28,28,28,27,27,27,27,25,25,27,26,25,26,26,26,25,28,27,26,26,28,27,27,27,24,24,24,24,24,25,25,26,25,26,26,28,26,28,27,28,27,27,27,28,27,27,28,28,28,27,28,26,27,26,26,27,25,26,26,25,24,25,23,23,23,22,22,21,19,18,19,16,19,22,21,18,22,20,24,24,24,25,26,26,26,24,26,23,24,25,24,25,26,26,26,27,26,26,27,28,27,28,28,27,29,28,29,29,29,28,29,30,28,30,30,29,29,29,28,28,29,28,29,28,28,29,30,29,30,30,29,29,30,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,29,28,27,28,28,27,27,28,28,26,25,27,26,25,25,26,25,24,25,24,24,26,26,24,25,26,28,27,27,26,27,27,27,26,27,28,27,28,29,29,29,28,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,28,28,29,29,29,29,29,28,28,29,29,29,29,29,29,29,29,28,29,29,29,29,28,28,29,28,29,29,29,29,28,29,29,28,28,29,27,28,28,29,27,26,27,27,27,25,27,26,25,27,28,27,28,29,28,28,28,27,29,29,28,28,28,29,29,28,29,29,28,28,28,29,29,28,29,27,29,28,27,27,29,28,27,28,29,27,27,28,29,28,29,28,27,28,28,28,28,28,29,28,28,28,28,27,27,28,29,28,28,27,27,27,27,28,26,28,27,27,29,27,28,28,26,27,28,27,27,26,26,25,26,25,23,24,25,24,22,23,23,21,20,22,21,20,21,22,21,18,17,15,15,15,13,11,11,15,10,11,8,7,9,7,7,8,6,5,5,5,3,4,2,2,1,0,1,2,1,2,2,3,4,4,4,5,4,5,5,4,5,6,7,6,9,8,9,10,12,9,10,12,13],[21,23,23,24,25,25,26,26,26,26,26,26,28,26,28,27,28,27,26,28,28,27,29,29,28,28,29,28,29,29,28,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,30,29,29,30,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,29,30,29,30,30,29,29,30,29,28,30,29,30,28,29,30,28,30,30,29,28,30,30,29,30,30,30,30,30,30,30,30,30,29,29,29,29,30,29,29,30,29,29,30,30,30,30,29,29,30,30,30,29,30,30,28,29,29,27,29,29,27,29,30,29,27,29,29,27,27,29,28,28,29,27,29,29,29,28,30,30,29,29,28,30,30,30,29,28,30,29,28,30,30,28,28,29,30,28,29,30,29,29,30,30,29,28,29,29,29,28,29,29,29,28,29,29,29,29,29,29,29,29,29,28,27,28,27,27,26,25,26,27,27,24,25,25,27,26,24,28,27,27,26,28,28,26,28,29,27,27,29,28,29,29,29,28,29,28,30,30,28,28,30,29,27,28,30,29,27,29,29,28,27,29,29,29,29,29,28,29,29,28,29,28,28,26,28,28,27,25,27,27,28,28,28,29,29,29,29,29,28,29,29,29,29,29,29,29,29,30,29,29,29,30,30,30,29,30,30,29,30,30,30,29,30,30,30,30,30,29,29,30,29,30,30,30,29,29,28,29,29,28,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,29,29,29,29,29,30,30,29,29,30,30,30,30,30,29,30,30,29,29,29,29,28,28,28,29,30,29,29,29,29,29,28,29,27,27,27,28,27,27,27,29,27,26,28,28,28,27,29,28,26,27,24,25,25,25,24,26,26,26,26,26,27,27,27,28,28,28,28,27,28,29,28,28,29,28,28,28,28,28,27,27,27,26,25,26,26,26,26,24,24,25,24,23,22,21,20,18,18,15,18,22,21,19,23,24,24,25,25,26,26,25,26,25,26,25,23,26,25,24,23,25,27,24,25,26,27,26,28,27,28,28,29,29,28,28,29,29,29,29,29,30,29,29,29,29,28,28,29,29,30,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,29,30,30,29,27,29,29,28,28,29,29,26,27,28,26,26,27,26,25,24,25,22,25,25,25,23,26,26,26,25,27,27,26,27,27,28,28,27,28,28,29,29,30,30,29,30,29,30,29,30,30,30,30,30,30,30,29,29,29,29,30,30,30,29,29,30,30,30,29,29,30,29,30,29,29,30,29,29,30,30,29,30,29,29,30,29,29,30,30,30,29,30,30,29,30,30,28,29,30,29,28,29,29,29,27,28,29,27,27,27,26,27,29,27,27,29,29,27,29,30,29,29,29,29,29,30,30,30,30,30,30,30,29,29,30,29,30,30,29,30,30,29,28,30,29,28,28,29,28,27,29,28,29,29,29,29,29,29,28,29,29,30,29,29,30,29,29,29,29,30,29,28,28,29,27,28,28,28,29,28,28,27,27,28,27,27,28,27,26,26,27,25,22,27,26,23,23,26,25,22,24,23,22,20,23,21,18,20,23,21,18,17,15,15,14,14,12,11,14,12,12,10,8,11,9,10,10,7,7,7,7,5,4,4,3,2,1,0,1,2,2,2,2,3,4,4,4,4,5,5,5,5,6,7,9,9,9,11,11,12,12,11,13,15],[22,24,24,26,26,26,27,27,27,27,27,28,28,27,28,28,28,28,27,29,29,28,29,29,29,29,29,29,29,29,29,30,30,30,29,30,30,30,30,30,30,29,29,29,30,29,29,29,29,29,29,29,29,30,29,29,29,30,29,29,29,28,29,28,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,29,30,30,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,29,29,28,30,29,28,29,29,29,29,28,29,30,28,27,29,28,29,27,29,29,27,29,29,29,29,30,29,29,29,30,30,29,30,29,29,29,29,28,29,28,28,28,29,28,29,29,28,29,29,29,29,29,28,29,30,29,28,29,30,27,29,28,26,29,29,26,27,29,28,26,27,29,27,27,28,27,29,28,27,29,29,28,28,29,30,29,29,29,29,29,30,29,29,30,28,27,29,29,28,27,29,29,28,29,29,29,28,29,29,29,27,29,28,29,28,29,29,28,28,28,29,28,28,29,29,28,28,28,28,28,27,26,27,25,23,25,26,24,20,25,25,27,26,25,26,27,26,27,28,28,27,27,28,28,27,29,28,28,29,30,28,29,29,29,30,27,28,29,29,27,28,29,28,27,29,29,27,26,29,29,28,29,28,26,28,28,27,26,28,27,25,27,26,25,24,24,26,27,27,27,28,28,28,28,28,28,29,28,28,29,28,28,28,29,29,29,29,29,29,29,30,29,29,29,29,30,30,29,29,30,29,29,30,29,29,30,30,29,30,29,29,29,28,28,29,29,28,29,29,29,29,29,29,29,29,30,30,30,29,30,29,30,29,29,29,30,30,30,29,29,29,29,30,29,29,29,29,30,29,29,30,29,29,29,30,30,29,29,30,29,30,29,29,29,28,28,28,28,28,28,29,28,29,28,28,28,27,27,27,25,26,27,26,25,27,27,26,26,28,27,27,26,29,28,27,27,24,26,25,26,23,26,25,26,26,26,26,27,26,28,28,28,26,28,28,28,26,27,29,27,27,28,27,27,27,26,26,26,25,25,25,25,24,24,24,23,22,23,22,22,21,19,19,17,18,23,20,18,23,21,24,24,23,25,26,24,25,24,25,24,24,24,25,24,24,26,27,26,26,26,27,27,27,28,28,28,29,29,28,29,29,29,29,30,29,30,29,29,29,29,29,28,30,29,30,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,30,29,29,29,29,29,29,29,30,29,27,29,29,28,27,29,28,26,26,27,26,25,26,26,25,24,25,23,25,27,26,24,27,27,27,27,28,28,27,27,28,28,28,28,29,29,29,29,29,29,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,29,29,29,28,28,29,28,28,29,29,29,29,28,29,29,28,29,29,28,29,28,29,29,29,29,29,29,29,29,29,29,28,28,29,28,28,28,29,27,26,28,28,26,26,28,26,27,28,27,27,29,29,27,29,29,28,28,29,29,28,29,29,29,28,29,29,28,28,28,28,29,29,29,28,29,29,28,27,29,28,27,28,29,27,27,28,28,28,28,28,27,28,28,28,27,28,29,28,29,29,28,28,28,29,28,28,27,26,27,27,27,27,26,28,27,26,28,27,28,27,27,28,27,25,27,27,26,26,26,26,23,24,25,26,23,23,23,23,22,22,22,20,21,22,21,19,17,16,15,15,13,13,13,15,12,12,11,11,11,10,11,11,8,7,8,7,6,5,4,3,2,2,1,0,1,2,2,2,2,4,3,3,3,4,4,4,4,5,6,5,9,7,9,10,13,11,10,13,13],[22,23,24,25,25,25,27,27,26,27,27,27,28,27,29,27,29,29,28,29,29,29,30,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,30,30,29,30,29,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,29,30,30,29,28,29,29,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,29,30,29,30,30,29,29,30,29,29,30,30,29,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,29,28,30,30,28,28,30,29,27,28,29,27,26,29,28,29,28,27,29,30,29,28,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,30,30,29,30,29,29,29,29,29,29,29,30,29,29,29,29,29,30,29,30,29,29,29,29,29,28,28,28,28,27,25,26,26,25,24,25,26,28,27,26,27,29,27,27,28,28,27,27,29,27,26,28,27,28,29,29,28,30,29,30,30,29,29,30,29,28,28,30,29,28,29,29,28,27,29,29,28,29,29,27,28,29,28,28,29,28,27,28,29,28,25,27,26,28,28,27,28,28,28,28,29,29,29,29,29,29,28,29,28,28,29,29,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,30,29,29,28,29,29,28,29,27,27,25,29,28,27,27,29,28,27,29,29,27,27,29,29,27,26,25,26,26,25,26,27,26,27,27,28,28,28,28,29,29,30,28,29,30,29,28,29,30,29,28,29,28,27,28,27,27,27,26,26,27,26,25,26,25,24,23,25,23,21,21,19,17,16,20,23,21,18,23,24,23,26,24,26,28,27,27,26,27,26,23,25,25,25,23,24,27,25,24,26,27,28,27,29,28,28,30,29,28,29,30,29,29,30,29,30,30,29,29,30,28,28,30,30,30,30,29,30,30,30,31,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,30,28,29,29,28,28,29,29,27,27,28,28,27,27,27,27,25,25,24,25,27,26,25,27,27,26,27,28,27,27,26,27,28,28,28,29,29,29,29,30,29,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,29,29,30,30,30,30,29,30,30,29,29,29,29,29,29,29,30,29,30,30,29,29,30,30,29,29,29,29,29,28,29,28,28,28,28,28,27,26,28,27,29,29,28,27,29,29,26,28,29,29,29,30,30,29,30,30,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,30,29,27,28,30,28,27,29,29,30,29,29,29,29,30,29,30,29,30,29,29,29,29,29,29,29,29,29,29,28,29,28,27,28,28,29,28,27,29,27,29,27,26,26,26,24,26,27,24,26,26,26,23,24,26,26,24,24,23,23,20,24,22,19,21,23,22,19,18,17,16,16,14,12,12,14,11,11,10,8,10,9,8,9,7,6,6,6,5,5,3,3,2,2,2,1,0,1,1,1,2,2,2,2,2,3,3,3,3,3,5,5,7,6,8,9,12,10,9,11,12],[22,24,25,24,26,26,27,27,26,27,27,26,28,26,28,27,28,28,28,29,28,28,29,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,29,30,29,29,29,29,29,29,29,29,28,28,28,28,28,28,28,28,28,29,29,28,29,28,29,28,29,28,29,29,29,29,29,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,30,29,29,30,30,29,29,29,29,29,29,29,29,30,29,29,29,29,29,30,30,29,30,29,30,29,29,29,28,29,29,27,28,29,28,25,28,27,29,26,30,29,28,29,29,29,28,30,29,29,29,30,29,29,29,29,29,29,29,28,29,28,29,28,29,28,29,29,29,29,29,29,29,30,29,29,29,29,28,29,29,26,29,28,26,28,29,26,27,29,27,25,27,29,25,26,28,27,28,28,26,28,29,27,27,28,29,28,29,28,29,29,29,28,28,30,28,27,29,29,27,27,29,30,28,28,29,29,28,29,29,28,28,28,28,28,28,28,29,29,28,29,29,29,28,28,29,29,27,28,27,27,26,27,26,26,26,25,26,25,25,26,25,27,26,25,25,27,25,26,27,27,24,26,28,25,25,27,26,27,28,29,27,29,28,29,29,27,28,29,28,26,29,29,27,26,28,28,27,26,28,29,29,28,29,27,28,28,26,27,28,27,25,27,27,25,24,25,25,27,28,27,27,28,28,28,28,28,28,28,28,28,28,27,28,28,28,28,28,28,28,28,28,27,28,28,28,28,29,28,29,28,28,28,28,29,29,28,29,29,29,29,28,29,28,28,29,28,28,29,29,28,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,28,27,27,27,27,27,28,28,28,29,28,28,28,28,26,26,24,26,26,25,26,27,26,25,28,27,26,26,27,27,26,27,23,24,24,23,22,25,25,25,26,26,25,26,26,27,27,28,27,28,27,28,27,28,28,27,27,28,28,27,27,27,26,26,25,26,25,24,25,23,21,23,22,22,20,20,19,19,19,16,19,19,20,18,21,23,23,24,25,25,26,24,24,24,25,23,23,24,23,23,22,24,24,23,23,25,26,25,26,27,28,25,28,28,27,28,29,28,29,29,27,28,28,27,27,28,27,27,28,29,29,28,28,29,29,29,30,29,29,29,29,29,28,28,29,29,28,29,28,29,29,29,29,29,29,29,29,30,29,28,29,29,29,27,29,29,27,27,29,28,24,26,27,26,24,26,25,25,24,24,23,21,25,26,23,24,26,25,23,26,27,24,25,26,26,28,28,28,28,29,29,29,28,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,28,28,29,28,29,27,28,27,28,28,28,27,27,28,28,29,29,29,30,29,30,29,29,29,29,29,29,29,29,29,28,28,29,29,27,26,28,28,27,27,27,26,27,28,27,27,28,29,27,28,28,28,28,28,29,29,29,29,29,29,29,29,28,29,28,29,29,29,29,28,29,29,28,27,29,28,28,28,28,27,27,28,27,28,27,29,28,26,27,28,27,27,29,28,27,28,28,28,27,28,29,28,28,27,27,27,27,27,27,27,27,26,27,26,28,26,26,26,26,24,26,26,24,21,26,26,21,22,24,24,20,23,22,20,19,20,21,17,19,20,20,17,16,16,15,15,14,11,11,13,12,12,10,8,10,8,8,8,7,6,6,6,6,5,4,4,3,2,3,2,1,0,1,2,2,2,3,3,3,4,3,4,3,4,5,6,8,7,8,9,10,9,9,10,11],[22,22,23,24,24,26,26,26,26,26,25,25,26,25,27,26,27,26,27,28,27,28,28,28,28,29,28,29,29,29,29,29,29,30,29,30,29,30,30,30,30,30,29,30,29,30,29,29,30,30,29,29,30,29,30,29,29,29,29,29,29,28,29,28,29,28,28,29,28,29,29,29,29,29,29,29,28,28,28,29,30,29,29,30,29,29,29,29,30,30,29,29,30,29,29,30,30,29,29,29,30,29,29,30,30,29,30,29,28,28,28,28,28,30,28,29,29,29,29,29,29,29,29,29,29,29,29,30,29,28,28,29,28,26,28,28,29,28,29,29,29,29,29,29,29,30,29,29,29,30,29,29,29,29,29,29,29,28,29,28,28,29,28,28,29,28,28,28,29,29,28,29,29,29,29,30,29,29,29,28,29,28,26,29,29,27,26,29,28,26,28,29,26,26,28,27,28,29,27,29,29,28,28,28,29,29,29,29,29,29,29,28,29,29,28,29,30,29,28,28,29,29,28,28,29,29,28,29,29,29,28,28,28,29,28,28,29,27,27,28,29,28,28,29,29,28,28,29,28,27,27,27,27,24,24,26,26,24,24,24,25,27,27,25,25,27,26,26,27,27,25,27,28,27,26,28,27,29,28,29,28,29,28,29,30,28,28,29,29,27,28,29,28,27,28,29,28,27,28,29,28,28,28,27,28,28,27,28,28,27,26,28,27,26,25,27,27,27,27,28,28,28,28,28,28,27,28,29,28,27,28,27,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,27,28,27,27,28,28,28,29,28,28,28,28,27,26,25,27,27,26,27,28,27,26,28,27,27,27,28,28,26,26,23,25,25,24,22,27,26,26,26,27,25,26,26,28,27,28,27,28,26,29,27,27,28,28,28,27,28,28,27,27,26,27,25,26,26,26,24,24,24,25,24,24,23,22,19,19,19,16,19,23,22,18,24,22,24,25,23,26,26,25,26,24,25,25,24,24,25,24,23,23,26,25,25,25,27,25,28,27,28,26,29,29,27,28,29,28,29,29,28,29,29,28,28,28,27,28,28,29,29,28,29,29,29,29,30,30,30,29,29,29,28,28,29,29,29,29,30,29,29,29,29,29,29,29,29,30,29,29,29,29,29,27,29,29,27,27,29,28,26,27,27,27,26,26,26,25,25,25,24,24,26,26,24,25,26,26,25,27,27,26,26,26,28,28,26,28,29,29,29,29,29,28,30,29,30,29,29,29,29,29,29,29,30,29,29,29,28,29,29,30,29,28,29,29,28,28,28,28,27,28,29,27,29,28,28,29,29,27,29,29,28,28,28,29,29,29,29,29,29,29,29,29,29,28,29,29,28,27,29,28,28,27,28,28,27,27,27,27,27,28,26,26,29,29,27,28,28,28,29,29,28,29,29,29,29,29,29,29,28,28,28,28,29,29,29,28,29,29,29,28,29,29,27,28,29,28,27,29,28,28,28,29,29,28,29,28,28,28,29,29,28,29,28,28,27,28,29,28,28,28,28,27,27,27,27,28,27,27,27,26,28,26,27,26,25,25,26,27,24,23,27,26,23,23,25,25,22,24,24,22,21,24,22,20,22,22,21,20,17,17,15,15,15,12,11,13,12,11,10,8,10,10,10,10,7,7,7,6,5,5,4,3,3,2,2,3,2,1,0,1,2,2,2,3,3,3,3,4,4,4,4,5,7,8,9,10,10,10,10,10,12],[22,24,25,26,26,27,27,27,27,27,26,26,27,26,27,28,28,28,27,29,28,27,29,28,28,29,28,29,29,29,28,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,28,29,29,29,29,29,28,28,28,28,28,28,28,29,28,29,28,29,29,28,29,28,29,29,29,29,29,29,29,29,29,30,29,30,29,30,30,30,29,29,30,30,29,29,29,29,30,29,30,29,29,30,29,29,29,29,29,28,28,29,29,29,29,29,29,29,29,28,29,29,29,28,29,29,29,29,29,29,29,30,28,28,29,29,30,27,29,29,29,29,30,29,29,30,29,29,29,30,29,30,30,29,29,29,29,28,29,28,28,29,29,28,29,29,28,29,29,29,29,29,28,29,29,29,29,29,29,28,29,28,27,29,29,26,28,29,28,26,28,29,27,26,28,27,29,28,27,29,29,28,29,29,30,29,29,28,29,29,30,29,28,30,29,28,29,30,29,28,29,29,29,29,29,29,28,29,29,29,28,29,29,29,28,29,29,28,28,28,29,29,28,29,29,29,28,29,28,28,28,27,27,27,23,26,26,25,21,26,26,27,26,25,27,28,26,27,28,27,25,27,29,27,27,28,28,28,29,29,28,29,28,29,30,28,28,29,29,27,28,30,28,27,29,29,28,27,29,29,28,29,29,27,29,28,28,28,28,28,26,28,28,26,25,26,26,28,28,27,28,29,28,28,28,28,29,28,28,28,28,28,28,28,28,28,29,28,29,29,29,28,29,28,28,28,29,29,29,29,28,28,29,29,28,29,29,28,29,29,29,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,29,28,29,29,28,29,29,28,28,28,28,28,27,28,27,27,29,28,29,28,29,28,27,27,26,26,24,27,26,26,27,28,27,26,28,28,27,27,28,28,27,28,25,26,26,25,24,27,26,26,26,27,27,27,26,28,27,28,26,28,28,28,27,28,29,27,28,28,28,27,28,27,26,27,25,25,26,26,25,25,25,25,23,24,23,21,21,20,18,17,19,22,20,18,23,22,24,25,24,26,27,26,26,25,25,24,24,26,25,24,23,26,26,25,26,27,27,26,28,28,27,27,29,29,27,29,29,29,29,29,27,29,29,29,28,29,27,28,29,28,29,28,29,29,29,29,29,29,28,29,28,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,30,29,27,29,29,28,26,29,28,26,26,28,28,26,26,26,26,25,24,24,25,27,26,25,27,27,26,26,28,27,26,27,27,28,27,28,28,28,28,29,29,29,28,29,29,28,29,29,29,29,29,30,29,29,29,29,29,28,30,29,30,29,29,29,29,29,28,27,28,27,28,28,28,28,28,28,29,29,27,28,29,28,29,29,29,30,29,30,29,30,29,29,29,29,28,28,29,28,27,28,28,27,27,28,28,27,27,28,26,26,28,26,26,29,29,28,28,29,28,28,28,28,28,29,29,29,28,29,29,29,28,28,29,29,29,29,28,29,29,28,27,29,29,26,28,28,27,26,28,28,28,28,28,28,28,28,27,28,28,29,28,28,29,28,28,28,28,28,28,28,27,28,28,27,28,27,29,28,27,28,28,29,28,26,27,27,26,27,26,27,24,26,25,22,23,25,25,23,23,23,22,21,23,22,20,21,22,22,19,18,16,14,15,13,12,12,13,12,11,11,10,11,10,10,11,8,7,7,8,7,6,5,4,4,3,2,2,2,1,1,0,1,2,3,3,2,3,3,3,3,3,3,4,6,6,7,8,10,9,9,10,11],[23,24,25,25,26,26,27,27,26,27,27,27,28,27,28,28,28,28,27,29,28,28,29,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,29,30,29,29,29,29,29,29,29,28,28,28,28,28,28,28,28,29,28,29,29,28,28,28,29,28,29,28,28,29,29,29,29,30,29,29,30,29,30,30,29,29,30,29,29,30,30,29,29,29,30,29,30,29,30,29,30,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,30,29,29,29,30,29,29,29,30,29,27,28,29,30,29,30,30,29,29,29,30,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,28,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,28,30,28,26,29,29,27,27,29,28,25,27,29,27,26,28,27,29,29,27,28,30,29,27,29,29,29,29,29,30,29,29,29,29,30,29,28,29,29,29,28,29,29,28,28,29,29,28,29,29,28,27,28,28,28,29,29,29,28,29,29,29,28,29,29,28,28,27,28,27,26,26,27,26,25,25,25,25,24,24,24,24,26,26,25,24,27,26,25,27,27,25,26,28,27,27,28,26,27,28,28,28,29,28,29,29,28,28,29,27,27,28,28,27,26,27,28,27,26,27,28,28,28,27,27,28,27,26,26,27,26,24,26,27,26,24,26,25,26,27,26,27,28,28,27,28,28,28,28,28,28,28,27,28,28,28,28,28,28,28,29,29,28,29,29,28,29,29,29,28,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,27,27,29,28,28,29,28,28,27,27,26,25,25,27,26,25,26,27,26,26,28,27,27,26,28,27,27,26,24,24,25,23,23,25,25,25,26,26,26,28,27,27,28,29,28,27,28,28,27,28,29,28,26,27,27,25,25,26,24,24,25,24,23,24,25,24,22,23,24,23,22,20,20,19,16,18,20,21,21,18,22,21,24,22,23,23,25,25,24,24,24,23,23,24,23,23,23,23,25,25,24,24,26,27,27,27,26,25,28,28,28,28,29,28,29,29,28,28,29,27,28,28,26,27,29,29,29,29,28,29,29,29,30,30,29,29,29,29,29,28,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,28,29,28,28,28,27,26,27,27,26,26,25,25,26,26,24,25,25,23,25,23,25,25,23,24,26,26,24,27,26,26,26,27,27,27,27,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,28,28,29,28,28,29,28,28,28,28,28,28,28,28,28,29,29,29,29,30,29,29,29,29,29,29,29,29,28,28,29,28,27,28,28,26,27,29,27,27,25,26,27,26,28,27,27,27,28,27,29,27,27,28,28,29,28,28,29,29,29,29,29,28,28,29,28,29,28,29,28,29,28,27,27,29,28,26,28,28,27,28,28,27,28,27,29,28,27,28,28,28,27,29,28,28,29,29,28,28,28,29,27,27,26,27,26,27,26,28,28,27,27,27,26,27,26,26,25,26,25,26,26,24,23,26,25,22,24,24,24,21,25,23,21,19,23,22,19,21,21,20,19,17,18,15,16,14,13,12,14,11,11,11,9,9,8,9,9,8,8,7,7,6,5,4,4,3,3,3,2,2,2,2,1,0,1,1,1,1,1,2,2,2,2,3,3,4,4,6,7,8,8,8,8,9],[23,22,24,24,24,25,26,25,26,26,25,25,27,26,27,27,27,27,27,29,28,28,29,28,28,29,29,29,29,29,29,30,30,30,29,30,29,30,29,29,30,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,28,28,28,28,28,27,27,26,28,26,27,28,27,28,29,28,28,28,28,28,27,27,28,29,29,28,28,29,29,28,29,28,29,29,28,28,29,28,28,27,28,27,28,28,28,28,28,28,28,28,28,27,28,28,28,27,27,28,28,28,27,28,28,28,28,28,28,28,27,28,28,28,28,28,28,29,27,26,28,28,28,28,28,28,29,29,28,28,28,29,28,28,28,28,28,28,29,28,27,28,28,26,27,26,27,28,28,26,28,28,27,27,28,28,28,28,28,29,28,28,28,28,29,28,29,28,26,29,28,27,26,29,27,26,29,29,27,26,28,27,29,27,26,29,29,27,28,28,28,27,28,29,28,28,28,29,29,29,29,29,29,29,29,28,28,29,28,27,28,28,28,28,29,28,27,28,27,27,27,28,28,27,27,28,28,28,28,28,28,28,27,28,26,27,26,26,27,25,25,25,24,24,24,25,24,26,25,25,26,26,26,26,27,27,25,27,28,27,26,28,26,28,28,29,28,29,28,29,29,28,27,28,27,27,27,28,28,27,27,28,28,26,28,28,27,28,28,27,27,28,27,26,27,27,25,26,27,25,24,26,25,26,27,26,27,28,28,27,27,27,28,28,27,27,27,26,27,27,28,28,27,27,27,28,27,28,27,27,27,28,28,28,28,28,28,28,28,29,28,29,29,29,29,29,29,28,29,28,29,28,28,29,29,28,29,29,30,29,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,29,29,28,28,27,28,26,27,28,28,28,29,27,28,26,28,25,25,25,26,27,25,25,27,26,25,27,27,26,26,27,27,26,27,24,24,24,24,22,26,25,26,25,26,26,26,26,27,27,28,27,27,27,28,26,27,28,26,27,28,28,26,25,26,24,25,24,24,24,25,25,22,23,24,22,23,22,20,18,18,18,15,18,22,21,19,23,23,24,22,24,24,24,24,25,23,24,23,24,22,23,23,21,23,25,24,24,25,27,26,27,26,27,27,28,28,27,28,28,27,28,28,28,27,28,26,27,28,27,29,28,29,29,28,28,29,28,28,28,28,28,27,28,27,27,27,27,27,27,28,28,28,28,28,29,28,29,28,29,29,29,29,28,29,28,28,27,28,27,26,28,27,26,26,27,26,26,25,25,24,25,24,24,24,24,25,24,26,24,26,26,26,27,26,26,26,27,27,28,28,28,28,29,29,28,28,29,28,29,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,27,28,28,27,27,26,27,26,26,27,26,26,25,27,27,27,26,26,28,26,28,27,28,29,29,29,29,29,28,29,28,28,27,29,28,27,28,28,28,27,28,29,27,25,27,26,27,27,28,28,28,28,29,28,28,28,27,28,28,29,28,28,29,28,28,28,29,28,28,28,28,29,28,28,27,29,28,27,27,29,28,27,28,28,26,28,28,26,27,27,28,28,27,27,28,27,27,29,27,27,28,28,27,26,28,29,27,28,26,27,25,26,26,27,27,26,26,26,26,27,26,27,26,27,26,27,27,26,22,25,27,22,21,25,25,19,24,24,21,18,23,22,19,20,21,20,19,16,15,14,14,14,11,11,14,12,11,10,9,10,9,9,9,8,8,7,7,6,5,5,4,3,3,3,3,2,2,2,1,1,0,1,1,1,1,1,2,2,2,2,3,4,5,6,7,8,8,8,9,9],[24,24,24,24,25,26,27,27,26,27,26,26,27,26,28,27,27,26,27,28,27,27,29,28,28,29,28,28,29,29,28,29,29,30,29,29,29,29,29,29,30,29,29,29,29,30,29,29,29,29,29,29,28,29,29,29,29,29,29,29,28,27,28,28,29,28,28,29,28,29,29,28,29,29,29,29,28,28,29,29,29,28,29,29,29,29,29,29,30,29,29,28,29,29,28,29,29,28,29,29,29,29,28,29,28,28,29,28,28,28,27,28,28,28,28,28,28,28,29,28,28,28,29,28,28,29,29,29,29,29,28,29,28,26,28,28,28,28,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,28,29,28,28,27,28,29,28,28,28,28,27,28,29,29,28,29,29,29,28,29,28,29,29,28,29,28,26,29,29,26,26,29,27,25,28,29,26,26,28,27,28,28,27,29,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,27,29,29,28,28,29,29,28,29,29,29,28,29,29,29,27,28,28,28,28,28,29,27,27,28,28,28,28,29,29,28,27,28,27,27,26,26,27,24,23,26,25,24,22,24,25,27,26,24,26,27,24,26,27,27,25,27,28,26,26,28,27,27,28,29,27,29,27,29,29,27,27,29,28,26,27,29,29,26,28,28,28,25,28,29,27,28,28,26,28,28,27,26,27,27,25,26,26,25,23,25,24,27,27,26,27,28,28,27,28,28,28,28,28,28,28,27,28,28,29,29,29,29,29,29,29,28,29,29,28,29,28,29,29,29,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,28,29,29,29,29,28,27,27,27,27,27,28,28,28,28,27,28,26,26,24,25,22,26,26,25,25,26,25,24,27,26,25,26,27,27,25,27,23,24,24,25,23,26,25,26,25,26,25,26,25,28,27,28,25,27,27,28,26,27,29,25,27,27,28,26,26,25,25,25,23,23,24,24,22,24,22,22,22,23,22,19,20,18,18,16,18,21,20,17,22,21,22,23,23,25,26,24,24,23,24,22,23,25,23,21,22,25,25,24,25,26,26,26,27,27,26,26,29,28,27,29,29,28,29,29,28,29,29,28,28,29,27,28,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,28,28,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,27,29,29,27,26,28,28,24,24,26,26,23,23,25,25,22,23,21,24,24,22,23,25,25,24,24,26,25,26,27,26,27,26,27,28,28,28,28,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,28,29,29,29,29,29,29,29,28,28,27,28,27,27,28,27,28,27,28,29,28,27,28,28,27,29,29,28,29,29,29,29,29,29,29,29,29,28,28,28,27,26,27,27,27,24,27,26,25,23,25,24,25,27,24,25,27,27,26,28,28,27,27,28,28,27,28,29,29,28,28,29,28,28,28,28,29,28,28,27,29,28,27,26,28,27,25,27,28,25,25,28,27,26,27,27,27,27,28,28,28,28,29,28,28,28,27,27,27,28,28,27,27,25,27,25,26,26,25,27,26,25,27,25,28,26,25,25,25,25,25,26,24,24,24,22,23,22,23,23,22,22,22,22,20,22,21,19,19,21,20,18,16,15,13,14,13,11,11,14,12,12,10,10,11,11,11,11,8,8,8,8,6,6,5,4,3,3,3,3,2,2,2,2,1,1,0,1,1,1,1,1,2,2,2,2,4,5,5,7,7,7,7,8,8],[24,25,25,26,25,26,28,28,26,28,26,27,28,27,28,28,28,29,27,29,28,28,29,29,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,29,29,28,28,29,29,28,28,28,28,29,29,29,28,28,29,27,29,28,28,28,28,28,29,29,28,29,29,29,29,29,29,29,30,29,29,29,29,29,30,30,30,29,30,29,29,30,30,29,29,30,30,30,29,29,29,29,29,29,30,30,29,30,29,30,30,28,29,30,29,29,29,30,29,28,29,30,28,27,28,29,30,28,30,30,29,29,30,29,29,30,30,29,29,30,30,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,28,29,29,28,29,28,27,29,29,27,27,29,28,27,28,28,27,26,29,28,30,29,27,29,30,28,27,28,30,29,30,28,29,29,30,29,28,30,29,28,29,29,29,28,29,29,29,28,29,29,28,28,29,29,27,28,28,28,29,29,28,29,29,29,28,28,27,29,28,27,26,28,27,27,26,27,27,25,25,26,26,26,24,24,25,27,26,24,25,28,25,25,27,27,23,26,28,27,26,28,26,27,29,29,27,29,28,29,29,28,28,29,28,27,26,28,27,27,27,28,26,26,27,28,26,28,27,25,27,28,26,24,27,26,25,25,27,25,23,25,25,27,28,26,27,27,27,26,28,28,28,28,28,29,28,28,28,29,28,29,29,29,29,30,29,28,29,29,29,29,29,30,29,29,30,30,29,29,30,29,30,29,30,29,28,29,29,28,28,29,29,29,28,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,29,28,27,28,28,28,28,29,28,28,27,28,27,25,26,25,24,24,27,27,25,25,27,27,26,26,27,27,26,26,27,26,25,23,23,24,24,23,26,25,26,25,26,26,27,26,27,27,28,27,28,28,27,26,28,29,26,26,27,27,26,26,25,23,24,24,24,25,24,24,24,22,21,22,23,21,19,17,17,16,17,19,22,21,18,21,21,22,23,23,23,25,24,24,23,26,24,22,24,23,22,23,23,24,24,25,24,25,26,27,28,26,26,29,28,27,29,29,28,29,29,28,29,29,28,28,29,27,27,29,28,29,29,28,29,29,29,30,30,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,30,29,28,29,29,29,29,29,29,29,27,28,28,27,27,28,27,25,25,25,24,24,24,24,25,23,23,23,23,24,24,23,26,25,24,23,27,26,26,26,26,27,27,27,27,28,28,29,29,29,29,29,30,28,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,28,28,28,29,29,29,29,29,29,28,28,28,29,29,29,28,29,28,29,29,29,29,28,29,29,28,28,29,26,27,28,27,25,26,26,25,25,24,25,26,26,27,26,26,27,26,25,26,27,26,28,29,29,28,29,29,29,29,29,29,28,28,28,28,29,29,28,27,29,29,25,27,29,27,25,25,28,26,26,28,27,29,27,28,28,28,28,29,29,29,29,29,29,29,28,29,28,28,27,26,27,25,28,26,26,27,26,29,27,26,27,26,27,25,25,24,25,25,25,23,24,22,24,23,21,24,24,22,22,23,21,20,20,22,20,18,20,21,19,19,18,17,14,14,12,11,10,13,10,10,10,8,9,8,9,9,7,7,8,7,6,5,4,4,3,3,3,3,2,2,2,1,1,1,1,0,1,1,1,1,1,1,2,2,3,3,4,5,6,5,6,7,7],[24,24,25,25,25,26,26,27,27,27,27,27,28,27,28,28,28,28,28,29,28,28,29,29,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,29,29,28,27,28,28,28,27,27,29,28,28,29,28,28,28,28,28,28,28,28,29,29,29,29,30,29,28,29,29,29,29,28,28,29,29,28,29,29,28,28,29,29,28,29,29,28,29,29,29,28,28,28,28,28,29,28,28,28,29,29,29,29,29,29,29,29,29,29,30,29,28,29,29,29,27,28,29,29,28,29,29,29,29,28,29,29,29,29,29,29,29,29,29,29,28,28,28,28,28,27,28,28,28,28,29,28,29,28,28,28,29,29,29,28,29,29,29,29,29,29,28,29,28,27,29,30,27,28,29,28,26,28,29,28,26,28,28,29,28,27,29,29,28,27,28,29,28,29,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,27,28,28,28,28,28,28,28,28,29,28,28,28,29,28,28,27,29,27,27,27,27,27,26,26,25,25,25,25,25,25,27,26,25,25,28,27,26,28,28,26,26,29,27,27,28,27,27,29,28,28,29,28,29,29,28,28,29,29,27,27,29,28,27,27,28,28,26,28,29,27,28,28,28,28,28,26,26,27,26,25,27,27,25,25,26,26,26,27,26,27,28,28,27,28,28,28,28,28,28,28,27,28,28,28,28,28,28,28,29,29,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,30,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,29,29,29,28,28,28,28,28,28,28,28,28,28,27,28,25,27,27,26,25,27,27,25,26,27,27,26,27,27,26,26,27,27,27,26,25,24,25,23,23,26,25,25,27,25,27,27,26,28,27,29,27,28,28,29,27,27,29,27,26,27,28,25,26,26,26,25,26,26,25,26,26,24,23,24,23,24,24,20,19,18,17,17,21,22,22,20,23,23,24,24,24,24,26,25,25,24,25,25,23,24,24,24,23,24,25,25,24,26,27,26,27,28,28,26,29,28,28,29,29,28,28,28,28,27,28,26,27,28,27,28,28,29,28,29,28,29,28,28,29,28,27,28,28,28,26,26,27,28,27,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,28,29,28,28,27,28,27,26,27,26,26,27,26,25,25,25,24,25,24,26,26,24,26,27,26,26,27,27,27,27,27,28,28,28,29,28,28,28,29,28,29,29,28,29,28,28,29,29,29,29,28,29,28,28,29,28,29,29,29,28,28,28,28,28,28,26,26,27,27,28,26,26,27,26,27,27,26,26,27,26,28,27,28,29,28,29,29,29,29,29,29,28,28,29,29,27,28,28,28,27,28,28,26,26,26,27,27,28,28,27,28,27,27,27,29,27,28,28,28,29,28,28,28,29,28,28,29,28,28,28,28,29,28,28,28,29,29,27,28,29,27,26,28,28,26,28,28,28,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,26,27,26,27,26,27,26,27,27,26,26,26,26,26,27,27,25,26,24,26,27,25,22,25,26,21,22,25,26,19,24,24,21,18,23,22,18,20,21,21,19,16,17,14,14,13,12,12,14,12,12,11,10,10,10,9,10,9,8,8,8,6,6,4,4,3,3,3,3,2,2,2,1,1,1,1,1,0,1,1,1,1,1,2,2,3,4,5,5,7,7,7,7,8],[24,23,24,25,25,26,27,26,26,26,26,26,27,26,28,27,28,27,27,28,27,28,29,28,28,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,29,29,29,30,29,29,30,29,29,29,29,28,29,28,28,28,28,29,28,29,29,29,29,29,29,29,29,28,29,29,29,29,29,30,30,29,29,29,30,30,29,28,29,29,28,28,29,29,28,29,29,29,28,29,28,28,28,28,28,27,28,27,28,29,28,29,28,28,29,28,29,29,29,28,28,29,28,29,29,29,27,29,29,26,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,28,29,27,28,27,28,29,28,28,29,29,29,28,29,29,28,29,30,29,29,29,29,29,29,28,29,29,28,29,29,28,27,29,29,27,29,30,28,27,29,27,28,29,28,28,29,28,28,28,29,27,29,29,29,29,29,29,29,30,29,29,30,30,29,29,29,30,29,29,29,29,29,29,29,29,28,29,28,29,28,28,29,28,27,29,29,29,29,29,29,28,28,29,28,28,27,28,28,27,26,27,25,24,24,26,26,28,27,26,27,28,27,27,29,28,26,28,29,28,27,28,27,29,29,29,29,29,29,30,30,29,29,29,29,28,29,30,29,28,29,29,29,27,28,29,28,29,28,28,28,29,28,27,28,28,26,27,28,26,25,25,26,27,28,26,28,28,29,27,29,28,29,29,29,28,28,27,29,28,29,29,29,28,29,29,29,28,29,29,29,29,29,29,29,29,29,29,30,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,29,29,29,29,30,29,30,29,29,29,30,29,29,29,29,29,29,29,29,29,28,29,28,28,28,28,29,29,29,29,28,28,27,27,26,25,24,26,26,25,26,27,26,25,27,27,25,25,27,27,25,26,23,25,22,24,22,26,26,26,24,26,25,25,26,26,28,28,25,28,28,27,26,28,29,27,27,29,28,26,26,26,26,26,25,25,25,26,26,25,24,25,23,24,24,21,18,18,19,17,19,23,23,20,25,24,25,24,24,25,27,26,25,25,26,24,24,24,25,24,23,25,27,23,25,26,27,26,28,28,28,28,29,29,28,29,29,28,29,29,29,29,29,28,28,28,27,29,29,29,30,29,29,30,29,29,29,28,29,28,28,28,29,28,29,29,29,29,29,29,29,29,30,29,29,29,30,30,30,29,29,30,29,29,29,29,28,27,28,28,27,27,27,27,26,26,26,26,24,25,23,25,26,24,24,27,26,25,26,28,26,26,28,26,28,28,27,29,29,28,29,29,29,28,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,27,28,27,27,28,27,28,26,27,29,28,27,28,28,27,29,28,29,30,29,30,29,30,29,29,30,29,29,29,29,27,29,29,27,28,27,27,27,26,26,26,24,27,28,25,26,28,28,27,29,28,29,28,28,29,29,29,30,29,29,29,30,29,29,29,29,30,30,29,28,30,29,28,28,29,28,27,28,28,26,26,28,25,27,27,28,29,29,29,29,28,28,29,28,28,29,28,28,28,29,29,27,28,26,27,25,27,25,27,28,26,26,25,26,26,25,26,24,25,23,24,27,24,22,25,27,21,21,25,25,21,24,25,23,19,25,24,21,21,23,22,20,18,16,14,15,15,11,11,15,14,14,11,11,12,11,11,11,9,9,8,8,6,6,5,5,4,3,4,3,3,2,2,2,1,1,1,1,1,0,1,1,1,2,2,2,3,4,4,6,6,6,7,8,8],[25,24,25,26,25,27,28,27,27,28,26,26,28,27,28,28,28,28,28,29,28,28,29,29,28,29,29,29,29,30,29,30,29,30,29,30,29,30,29,29,30,29,29,30,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,28,29,29,28,29,28,29,29,28,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,30,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,30,28,29,29,29,29,29,29,28,30,29,28,29,29,29,29,29,30,29,29,29,30,29,29,29,29,29,29,30,29,29,29,29,29,29,28,28,28,29,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,28,27,29,29,27,27,29,28,27,28,29,28,26,29,28,29,29,27,29,29,28,28,29,30,30,30,28,29,29,30,29,28,30,29,28,29,29,29,28,29,30,29,28,29,30,28,29,29,29,28,29,28,29,29,29,29,29,28,28,29,29,28,29,28,29,28,29,28,28,28,27,27,26,24,27,26,25,22,25,25,27,26,24,27,28,25,26,28,27,24,26,28,27,26,28,27,28,29,29,28,29,28,29,30,28,28,29,28,27,28,29,28,26,28,28,28,26,28,29,28,28,28,26,28,28,27,26,27,27,25,26,27,25,23,24,24,27,27,27,27,28,28,27,28,28,28,28,28,28,27,28,28,28,29,29,29,29,29,29,29,28,29,29,29,29,30,30,29,29,29,29,30,29,29,29,29,29,30,29,29,29,29,28,29,29,29,29,29,29,29,29,30,30,29,30,30,30,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,29,30,30,29,30,30,29,29,29,29,29,28,28,28,29,28,28,28,27,28,27,28,27,26,26,24,24,23,26,26,23,24,27,25,24,26,26,25,25,27,27,26,26,24,24,25,23,21,24,25,26,25,26,26,27,25,27,27,28,25,27,28,28,25,27,29,25,26,28,27,26,26,24,24,26,23,23,25,25,22,23,23,22,22,22,22,19,19,18,17,17,19,22,22,18,22,21,23,24,23,25,26,24,23,25,25,22,22,25,25,22,22,24,25,24,25,24,25,25,28,28,26,27,29,28,27,29,29,28,29,29,28,30,29,29,29,29,28,28,29,28,29,29,29,29,29,29,30,30,29,28,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,27,28,29,28,26,28,28,25,24,27,26,24,24,25,25,22,23,20,24,25,21,22,25,25,24,24,26,25,26,27,25,27,25,26,27,28,27,28,29,28,29,29,29,29,29,29,28,28,30,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,28,28,28,28,29,29,29,28,28,29,28,28,28,28,29,29,29,28,29,29,29,29,29,29,29,29,29,28,28,28,27,27,27,27,26,24,26,27,24,23,25,24,25,27,24,24,27,27,26,28,28,27,28,29,28,27,29,29,28,28,29,29,28,28,28,28,29,28,28,27,29,28,27,26,28,27,24,26,28,25,25,27,27,28,27,27,27,28,28,28,29,28,28,27,28,28,27,27,28,28,27,27,27,25,27,26,26,27,26,27,27,25,26,24,27,27,25,26,24,25,25,25,24,23,25,24,22,22,24,24,21,21,23,21,20,22,22,20,21,21,20,18,18,16,14,14,13,11,11,14,13,13,11,11,13,12,11,13,10,9,8,10,8,7,6,6,4,4,4,3,3,2,3,2,2,2,1,1,1,1,0,1,1,2,2,2,3,4,4,6,6,5,6,7,8],[25,26,26,26,27,27,28,28,27,28,27,27,28,27,28,28,29,28,28,29,28,28,29,29,28,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,28,28,28,28,28,28,29,27,28,27,28,28,28,28,28,29,28,28,28,29,28,28,29,28,29,29,29,29,28,28,29,29,28,29,30,29,29,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,30,28,29,29,28,29,28,29,29,28,29,30,28,27,28,28,30,28,30,30,29,29,29,29,28,29,29,29,28,29,29,29,29,28,29,28,29,29,28,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,29,29,28,29,29,28,29,28,27,29,29,26,27,28,28,26,27,28,27,27,29,28,29,28,27,28,29,28,27,29,30,30,29,28,29,28,29,29,28,29,29,28,28,29,29,27,28,29,27,27,28,28,27,28,28,28,27,29,29,28,29,29,28,28,28,29,29,28,28,28,28,28,27,28,27,27,26,27,26,25,25,25,26,25,23,25,25,26,24,24,24,27,24,25,26,26,25,25,27,26,26,27,27,28,28,28,27,28,26,29,29,27,27,28,27,26,27,28,26,25,27,27,26,24,27,28,27,28,28,26,27,27,25,25,26,26,25,26,26,24,21,23,23,25,27,26,27,27,27,26,28,27,27,27,27,28,27,27,28,28,28,28,28,29,29,29,29,29,29,30,29,29,29,30,29,29,30,30,30,30,30,30,30,29,30,29,28,29,29,28,28,29,28,29,28,29,29,29,29,29,29,29,29,30,29,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,29,29,30,29,30,30,30,30,30,29,29,29,29,29,29,29,29,29,29,29,28,27,28,28,27,27,28,26,28,26,27,27,25,25,25,22,23,26,25,24,23,25,25,24,25,24,24,24,25,25,24,24,23,23,23,24,21,24,24,24,24,24,25,25,25,26,25,27,26,26,26,27,25,26,28,25,24,26,26,25,25,23,24,23,24,23,23,24,23,22,22,21,21,21,21,18,17,16,15,17,18,21,19,18,21,21,23,24,22,23,25,23,23,22,24,23,22,23,22,22,22,22,22,25,23,24,23,25,26,26,25,26,28,27,26,29,28,27,28,28,28,29,29,29,28,28,27,27,28,28,28,29,28,28,28,29,29,29,28,29,29,29,29,28,28,28,28,29,28,29,29,28,29,29,28,28,29,29,28,28,28,28,29,26,27,28,26,25,27,26,24,24,24,25,23,24,23,24,22,22,21,24,24,22,22,23,24,24,24,25,24,25,26,24,25,23,26,26,27,27,28,28,28,28,28,29,28,28,29,28,28,28,29,28,29,28,28,28,28,29,29,28,28,28,29,28,29,28,28,28,28,29,28,28,28,29,28,28,29,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,26,28,28,26,25,26,25,23,24,24,24,25,23,23,25,25,25,24,24,26,26,25,26,27,25,28,28,28,27,28,29,28,27,28,28,28,27,27,27,28,28,27,26,28,27,26,25,28,26,24,26,26,24,25,26,26,27,26,27,26,28,27,28,27,28,28,26,27,28,26,27,27,27,26,26,26,26,26,25,25,25,26,26,27,25,26,25,25,25,24,26,25,24,25,25,23,24,25,23,21,23,24,23,21,21,22,20,19,21,21,18,19,21,21,18,18,17,15,15,13,11,11,14,12,12,10,11,10,11,10,12,10,8,8,10,8,8,5,6,4,4,5,4,3,3,3,2,2,2,2,1,1,1,1,0,1,2,2,2,3,4,5,6,8,6,6,7,8],[24,23,25,24,25,26,26,26,26,26,26,27,27,25,26,26,27,27,26,28,27,27,28,28,27,29,28,28,29,29,28,29,29,29,29,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,28,29,28,28,29,29,28,28,28,28,28,28,28,28,28,28,29,28,28,28,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,28,28,29,28,28,29,29,29,29,29,29,29,28,29,28,29,29,29,29,28,28,29,29,29,29,29,29,29,29,29,29,28,28,29,28,29,28,29,29,28,28,29,28,26,27,27,28,28,29,29,28,28,29,28,29,29,29,29,28,29,29,28,29,28,28,28,29,28,28,28,28,29,29,29,28,29,29,29,28,29,29,28,27,28,29,28,28,29,28,27,28,27,24,28,28,24,26,28,27,24,26,27,25,26,27,26,28,27,25,27,28,28,27,27,28,27,28,28,28,28,28,28,28,29,28,28,28,29,28,28,28,29,28,27,28,28,27,27,28,27,26,27,28,28,28,29,28,28,28,29,28,28,28,28,27,27,27,27,26,26,26,26,25,25,24,24,23,23,24,24,23,26,25,24,24,26,24,25,26,25,24,25,27,25,25,27,25,27,28,28,27,28,27,28,28,27,27,28,27,26,27,27,27,25,26,26,26,25,26,27,26,27,27,25,26,27,25,25,26,26,26,25,25,26,22,26,25,26,27,24,26,26,26,25,27,26,26,26,27,27,27,27,28,28,28,29,29,28,28,28,29,28,28,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,28,29,28,28,27,28,28,28,28,28,28,28,29,30,29,28,29,29,29,29,29,29,29,29,29,29,30,30,30,29,30,29,30,29,29,29,28,29,29,29,29,29,29,29,28,29,29,29,29,29,29,29,29,28,28,28,27,27,27,26,27,28,26,27,27,27,26,26,24,25,24,23,25,24,24,23,26,25,24,24,24,24,24,25,24,24,23,23,20,21,22,20,24,23,23,24,24,24,25,26,27,26,27,26,27,27,27,26,27,27,26,24,26,26,24,25,25,24,24,25,24,25,25,23,24,23,23,22,23,21,20,18,18,16,17,18,21,21,21,23,23,23,24,24,23,25,23,24,23,24,24,22,22,22,23,23,23,24,23,22,24,25,24,26,26,26,24,28,28,26,28,28,27,28,27,28,27,28,25,27,27,26,28,27,28,27,28,27,28,28,28,29,28,26,28,27,27,27,27,28,28,28,29,28,28,28,28,28,28,29,27,28,28,28,28,28,28,28,27,27,27,27,27,26,26,26,25,25,25,26,25,23,24,24,23,24,23,23,24,23,24,24,23,23,26,24,25,26,24,26,27,26,28,27,28,28,27,27,27,28,27,28,28,29,28,28,29,29,29,28,28,28,28,29,29,29,29,29,28,28,29,28,28,27,27,28,27,28,26,27,27,27,28,27,27,28,28,27,28,28,28,29,28,28,28,28,27,28,28,28,26,28,27,27,26,27,25,26,26,25,25,25,25,24,24,27,26,25,26,26,26,25,28,26,27,28,28,28,28,27,28,28,28,28,28,28,28,27,27,27,28,27,27,28,27,26,26,28,26,24,27,26,25,26,27,26,26,26,28,27,26,28,28,26,28,28,28,27,28,28,27,27,27,26,26,26,25,26,25,25,26,27,26,26,25,24,25,24,25,24,23,23,23,25,23,23,20,23,24,19,21,21,22,18,21,21,21,17,21,20,18,21,21,20,19,17,17,15,16,13,12,11,13,14,12,11,11,11,10,9,12,11,8,9,10,8,7,5,6,4,4,5,4,3,3,4,2,2,2,2,2,1,2,1,1,0,1,1,2,3,4,5,5,7,6,6,7,8],[24,24,25,25,25,26,27,27,26,27,26,26,27,26,28,27,28,28,28,29,28,28,30,29,28,29,29,29,29,29,29,30,29,30,30,30,29,30,30,30,30,29,29,29,30,30,30,30,29,30,29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,27,28,28,28,28,28,28,28,28,28,28,28,27,28,28,29,28,29,29,29,28,29,28,29,29,28,27,29,28,27,28,28,28,28,28,28,28,28,28,28,28,29,28,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,28,28,28,29,28,26,26,28,27,28,28,28,29,28,28,28,29,29,28,28,29,28,28,29,28,27,28,27,28,27,27,26,28,28,28,28,28,28,27,27,28,28,28,28,29,28,28,28,29,29,28,28,29,28,27,29,28,28,27,28,28,27,28,28,28,27,28,27,28,27,28,29,29,28,28,28,29,28,28,29,28,28,29,28,29,29,28,29,29,28,28,29,28,29,29,28,28,29,29,28,28,29,28,27,28,27,27,28,28,27,28,28,28,28,28,28,28,28,28,28,27,27,26,27,27,26,25,26,25,24,24,25,25,26,26,25,26,27,25,26,27,27,26,27,28,27,27,28,27,28,28,28,28,28,28,29,29,28,28,28,28,27,27,28,28,27,27,27,28,26,27,28,27,28,28,27,27,28,27,26,27,27,25,27,27,26,24,26,26,26,28,26,27,28,28,27,28,27,28,28,28,27,27,27,28,28,28,28,28,28,28,29,28,28,28,29,28,29,28,29,29,29,29,29,29,29,30,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,30,30,29,29,29,29,30,29,29,29,29,29,29,29,29,28,28,27,28,27,28,27,28,28,28,28,28,28,26,26,26,26,25,26,26,25,25,26,24,25,26,26,24,26,26,25,25,25,23,24,24,23,21,25,25,25,24,25,26,26,25,27,27,28,27,27,28,27,26,27,28,27,26,27,27,25,26,26,25,26,26,24,26,25,25,25,23,25,23,23,24,22,19,18,18,18,21,22,22,21,24,24,24,24,24,25,25,25,25,24,25,24,23,23,24,24,22,23,25,24,24,26,27,26,28,27,27,27,29,28,28,28,28,28,28,28,28,28,29,27,28,28,28,29,28,29,28,28,28,28,28,28,29,28,27,27,28,27,26,27,28,27,26,28,27,28,28,29,28,29,29,28,29,29,29,29,29,29,28,28,28,28,28,27,27,27,26,26,26,26,26,26,25,25,25,25,24,23,25,24,24,26,26,25,26,27,26,26,27,25,27,28,28,28,28,28,29,29,28,28,29,28,29,28,29,28,29,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,27,26,26,26,27,26,27,26,26,27,27,26,27,27,27,28,27,28,28,29,29,28,29,28,29,28,28,28,29,28,27,28,28,28,27,27,28,27,26,27,27,26,27,28,26,28,28,27,27,29,28,27,28,28,29,29,28,28,28,28,28,28,27,27,28,28,28,28,28,28,29,28,27,28,29,27,27,27,28,26,27,28,27,28,27,28,29,28,28,27,27,27,29,28,27,28,28,28,27,28,28,27,27,27,27,26,27,26,27,27,26,26,26,27,26,26,26,26,26,26,26,26,25,23,25,26,22,22,25,25,20,24,24,22,19,24,23,21,21,22,20,21,17,17,16,15,16,12,11,15,14,13,11,12,11,11,10,12,11,9,8,10,7,7,6,6,4,4,5,4,3,3,4,3,2,2,3,2,2,2,3,1,1,0,1,2,3,4,5,6,7,7,6,6,8],[25,25,25,26,26,27,28,27,27,27,27,26,28,27,28,28,29,28,28,29,29,28,29,29,29,29,29,29,29,29,29,30,29,30,29,29,29,29,30,30,29,29,29,29,29,30,30,29,30,29,29,29,29,30,29,29,29,30,29,29,29,28,29,28,29,29,29,29,28,29,30,29,29,29,30,29,30,29,29,29,29,29,30,30,30,30,30,30,30,30,29,29,30,30,29,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,30,29,29,28,29,30,29,29,30,29,28,30,29,27,28,29,29,29,29,29,30,30,29,29,30,30,29,30,30,30,30,30,30,29,29,29,30,29,29,28,29,29,29,29,29,29,29,29,29,29,30,29,30,30,29,30,29,29,29,28,30,29,28,29,30,28,28,29,29,28,29,29,29,28,29,28,29,29,28,29,30,29,29,29,30,29,29,30,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,29,29,29,29,29,29,29,28,28,30,29,29,29,29,29,29,29,28,28,28,28,28,27,26,27,27,26,25,26,26,28,28,26,28,29,27,28,29,28,27,28,30,28,27,29,28,30,29,30,30,30,29,30,30,30,30,30,29,29,29,30,29,28,29,29,29,28,29,29,29,29,29,28,29,29,28,28,28,28,26,28,28,26,25,26,26,27,28,27,28,29,29,28,29,29,29,29,29,29,29,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,28,28,28,28,28,28,29,29,29,29,29,29,27,27,26,25,23,26,26,24,24,27,24,25,26,26,24,26,27,28,25,26,23,24,23,24,23,25,26,26,25,26,25,26,25,27,28,29,25,27,28,28,25,28,29,26,26,28,28,26,27,24,26,26,25,24,25,26,24,23,25,23,22,22,23,23,22,20,20,19,21,23,23,21,24,24,24,24,25,26,27,26,24,25,27,25,24,25,26,24,23,25,26,24,26,27,27,26,29,29,28,29,30,29,28,29,29,29,30,29,29,29,29,28,29,29,29,29,30,30,30,30,30,30,30,30,30,29,30,29,30,29,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,27,29,29,27,27,28,28,27,25,26,26,25,24,23,25,27,23,24,27,27,24,26,28,26,27,28,27,29,27,27,29,29,29,30,30,30,29,30,29,30,30,30,29,30,30,29,29,30,29,29,29,29,30,29,30,30,29,29,30,29,29,28,29,28,28,29,28,29,28,28,30,29,28,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,29,29,30,29,28,28,28,28,27,28,28,26,24,26,25,27,28,26,25,29,28,27,29,29,29,29,29,29,29,30,30,30,29,29,30,29,29,29,29,30,29,30,28,30,29,29,28,29,28,26,27,28,25,25,28,26,28,28,29,29,29,29,29,29,29,30,29,29,29,29,28,29,29,29,28,28,27,28,26,27,26,27,29,27,26,27,26,28,28,25,27,25,25,25,26,25,24,25,25,24,23,25,25,23,22,24,22,21,23,23,22,23,23,22,22,19,18,16,17,16,14,14,18,16,17,14,14,15,14,14,14,13,12,10,11,10,9,9,8,6,7,7,6,5,5,6,5,4,4,4,4,3,4,4,4,3,1,0,1,3,4,5,6,7,7,7,8,8],[26,26,27,27,27,28,28,28,28,28,27,27,28,26,27,28,28,29,28,29,29,29,30,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,29,29,29,30,29,29,30,29,30,30,29,30,29,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,30,29,29,30,30,30,29,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,29,30,30,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,29,30,30,28,29,30,29,28,30,29,28,28,30,29,30,29,29,30,30,29,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,29,29,30,29,30,30,30,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,29,29,29,28,28,28,27,28,29,27,26,27,27,29,28,27,28,29,27,27,29,29,27,28,30,28,28,29,28,29,30,29,29,29,29,30,30,30,29,30,29,28,29,30,29,28,29,29,29,27,29,29,29,29,30,28,30,29,28,27,29,28,26,28,29,27,25,26,26,28,29,28,29,29,29,29,29,29,30,29,29,29,29,28,29,29,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,30,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,29,29,29,28,29,29,29,29,29,29,28,29,27,27,26,28,27,26,27,28,27,26,28,27,27,27,27,27,25,25,24,25,25,25,23,25,27,27,26,26,27,26,26,27,28,27,27,28,28,29,27,29,29,27,27,28,29,26,28,26,28,27,26,26,27,27,25,25,26,24,23,23,24,21,20,20,19,19,21,24,22,22,23,25,25,26,26,27,28,27,26,26,28,25,25,27,26,24,24,26,25,26,27,28,27,28,29,29,29,29,30,29,29,30,30,29,29,29,29,30,30,29,29,29,29,29,29,29,29,30,29,30,30,30,30,30,30,29,30,30,30,29,30,30,29,30,30,29,30,29,30,30,30,29,30,30,30,30,30,30,30,29,30,29,29,28,29,29,27,27,29,28,26,27,28,27,25,25,24,26,28,26,26,27,27,27,26,28,27,28,28,28,28,27,29,29,29,29,30,30,30,30,30,29,29,30,30,29,29,30,30,30,29,30,30,29,30,30,30,30,30,30,29,29,30,30,29,29,29,29,29,30,30,29,30,30,30,30,29,29,29,30,29,29,30,30,30,29,29,30,30,29,30,29,30,30,29,28,29,29,27,27,28,28,27,27,28,27,28,29,27,27,29,29,28,30,29,29,29,29,30,29,30,30,30,29,29,29,29,29,29,29,29,30,30,29,30,29,29,29,30,29,28,29,30,28,28,29,28,29,29,29,29,30,29,29,30,29,30,29,29,29,28,29,29,29,29,29,29,29,29,28,28,28,29,29,29,27,28,27,28,27,28,27,28,26,26,27,26,24,26,26,23,22,25,26,21,22,25,24,20,25,25,22,22,25,24,23,21,20,19,19,17,15,16,17,17,16,16,16,15,17,14,17,17,12,13,15,13,13,10,11,8,8,10,8,8,7,8,6,6,5,5,5,4,3,4,5,3,2,1,0,1,3,4,4,6,5,5,6,7],[25,25,25,26,26,27,28,27,26,27,27,27,28,27,28,28,29,28,28,29,28,29,30,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,28,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,29,30,29,30,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,26,28,28,27,26,28,28,29,29,27,29,29,29,29,30,29,28,29,30,30,28,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,29,30,30,30,28,30,30,30,30,30,29,30,30,29,28,29,29,27,28,28,27,25,26,26,27,29,28,29,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,28,28,27,27,25,24,28,26,24,26,28,25,25,27,27,26,26,27,28,26,26,23,24,23,24,22,24,26,25,24,26,27,27,25,27,28,29,25,27,29,27,25,28,29,27,27,29,29,26,28,25,27,27,26,25,26,27,25,24,26,25,24,23,24,25,22,21,22,20,21,22,24,24,25,26,26,25,26,27,28,27,26,27,28,26,26,27,27,25,24,27,27,26,27,28,28,27,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,28,28,29,28,27,27,27,27,25,25,24,26,27,25,25,28,27,27,26,28,27,27,29,28,29,28,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,30,29,30,29,29,30,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,28,26,26,27,27,28,29,28,29,29,29,28,30,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,27,29,29,26,28,29,28,29,29,30,29,30,30,30,30,30,30,29,30,30,29,29,30,30,29,29,29,27,28,27,27,28,28,30,28,26,28,27,28,28,26,27,27,26,26,26,26,24,25,27,26,25,25,26,25,22,25,24,22,24,24,24,23,24,24,23,22,20,19,18,19,16,16,18,18,17,16,17,16,18,16,18,17,14,14,16,14,13,14,12,12,11,12,11,9,11,12,8,10,7,5,7,6,5,4,4,4,4,2,1,0,1,3,3,5,5,4,5,6],[26,26,26,27,27,28,29,28,28,29,28,28,28,28,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,29,29,29,29,30,30,30,29,30,29,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,30,30,28,29,30,29,28,29,29,28,28,29,29,29,29,29,29,30,29,29,29,30,29,30,29,30,29,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,29,30,30,30,29,29,29,30,30,30,30,30,30,30,29,30,30,30,29,29,30,29,29,29,29,28,28,28,27,28,28,27,27,27,27,28,28,27,28,29,27,28,29,28,28,29,29,29,28,29,28,29,30,29,29,30,29,30,30,30,29,30,29,29,29,30,29,28,29,29,29,28,29,30,29,30,30,28,29,29,28,28,29,29,27,28,28,28,27,28,27,28,29,28,28,29,29,29,29,29,30,29,29,29,29,29,29,29,29,29,30,29,30,29,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,30,30,29,30,29,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,28,29,29,28,29,30,29,29,29,29,29,28,28,28,27,26,28,27,26,27,28,26,26,27,26,25,26,27,26,25,25,24,25,25,24,24,25,27,26,26,27,26,27,27,27,28,28,27,28,28,29,27,28,30,28,28,28,28,27,27,27,27,27,26,28,27,27,27,27,27,25,26,26,25,26,22,23,21,21,23,25,25,25,27,27,27,27,27,28,29,28,27,28,28,26,27,28,27,26,26,26,27,27,27,27,28,28,29,28,28,28,30,29,29,29,29,29,29,29,29,29,30,29,29,29,28,29,29,29,29,29,29,30,30,30,30,30,29,29,30,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,28,29,29,28,28,28,28,27,27,27,26,27,26,25,27,26,28,26,26,26,27,27,28,28,27,28,27,29,28,29,29,29,29,30,29,29,30,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,30,29,29,30,30,30,30,30,30,30,30,30,29,29,30,29,29,29,28,28,28,29,28,26,27,28,27,28,28,28,28,29,29,29,29,29,29,29,29,30,29,30,30,30,29,30,30,29,29,30,29,30,30,30,29,30,30,29,29,30,29,27,28,29,28,29,29,29,29,28,30,30,30,29,29,29,29,30,29,29,29,29,29,29,29,29,29,29,28,28,27,28,28,28,29,28,28,28,28,27,27,27,26,28,26,27,27,27,24,27,27,26,24,26,27,24,24,25,25,22,25,26,23,24,26,25,24,24,23,21,21,19,18,16,18,20,18,17,18,16,18,17,20,20,15,16,20,17,18,14,16,13,14,16,14,12,13,15,11,10,8,9,8,8,6,7,7,5,5,4,3,1,0,1,3,4,4,4,5,5],[26,26,27,28,27,28,29,28,28,28,28,27,28,27,28,28,28,28,28,29,28,29,30,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,31,30,30,30,30,30,30,30,29,30,30,30,30,30,30,31,31,30,31,30,31,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,30,31,30,31,30,30,30,30,30,30,29,30,31,30,29,30,30,29,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,31,30,30,31,31,30,30,31,30,31,31,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,29,30,30,28,28,28,29,29,28,27,28,28,30,29,28,29,30,28,29,30,30,28,29,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,28,30,30,30,30,30,28,30,30,28,28,29,29,27,28,29,27,26,26,27,28,29,28,29,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,28,29,28,27,27,29,28,26,27,29,27,27,28,29,27,28,29,29,26,28,25,26,25,26,26,26,28,27,26,28,27,28,27,29,29,30,28,28,30,29,27,29,30,29,27,29,29,27,28,26,29,28,27,27,26,27,26,26,26,26,26,25,24,26,23,22,23,21,22,23,25,23,24,25,25,27,27,28,28,28,26,27,28,26,27,28,27,26,27,28,26,26,27,28,28,28,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,28,28,28,29,28,27,28,27,26,26,26,27,28,26,26,28,28,27,28,29,28,28,29,29,29,28,29,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,30,30,30,30,30,29,30,29,28,29,30,29,27,28,29,28,29,29,28,29,30,30,29,30,30,30,30,30,30,30,31,30,31,31,30,30,30,30,30,30,31,31,30,30,31,31,29,30,31,30,28,30,30,28,29,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,29,30,28,29,28,28,29,29,30,30,28,29,28,29,29,28,28,28,27,27,28,28,25,28,28,27,25,27,28,25,24,27,25,24,24,25,23,24,24,24,23,21,21,20,18,19,18,17,19,18,17,19,18,17,18,17,19,18,17,17,18,18,18,15,17,14,14,15,14,13,12,15,12,11,10,8,8,8,7,6,6,6,5,5,3,2,1,0,1,3,6,3,3,4],[26,26,26,26,27,27,27,28,28,28,27,27,28,28,28,28,28,29,28,29,29,29,30,29,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,29,29,29,30,30,30,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,29,29,29,29,29,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,28,29,30,30,28,30,29,29,28,29,29,29,29,29,29,30,29,29,29,29,29,29,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,28,29,29,28,28,27,28,28,27,27,27,27,29,28,27,28,29,28,28,30,29,28,28,30,29,28,29,28,29,29,29,30,30,30,30,30,30,29,30,30,29,29,30,30,28,30,30,29,28,29,30,29,29,29,28,29,29,28,28,29,28,27,28,27,27,25,27,27,28,28,28,28,29,29,28,30,29,30,29,29,30,30,29,29,30,29,30,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,29,29,29,29,29,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,29,29,30,30,29,30,29,30,28,28,28,26,25,27,27,26,27,27,25,25,27,26,26,25,27,27,26,26,25,23,24,23,23,25,26,26,25,27,27,26,26,28,27,29,26,26,29,27,25,28,29,28,27,28,28,27,27,26,27,27,27,27,27,28,27,26,27,26,26,25,25,26,21,21,20,22,21,23,25,24,26,26,26,26,27,27,28,28,26,26,28,26,26,27,27,26,26,27,27,26,26,26,28,28,28,28,28,27,30,29,29,29,30,29,30,29,29,29,29,28,29,29,28,30,29,30,30,29,29,30,29,30,30,30,29,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,29,28,29,29,27,28,27,28,28,27,27,27,26,26,25,26,27,27,25,27,27,27,28,29,28,27,28,28,28,29,29,29,29,29,29,30,30,29,29,29,30,29,29,29,30,30,30,29,30,29,30,30,29,30,30,30,30,30,29,30,30,30,28,28,28,28,29,29,29,29,28,29,29,28,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,29,28,27,28,28,27,29,29,28,28,29,29,28,30,28,28,29,28,29,29,29,29,30,30,29,30,29,30,30,30,30,29,30,29,30,30,28,29,30,29,28,29,29,27,28,29,29,29,28,29,29,29,28,29,29,29,30,29,29,30,30,30,29,29,30,29,29,28,28,27,29,28,29,29,27,28,27,27,27,26,27,26,28,26,26,26,25,24,26,27,24,23,26,26,23,24,27,24,21,25,27,22,24,25,24,23,22,21,20,19,19,18,16,19,19,19,19,18,17,17,17,18,19,16,16,19,17,18,15,17,15,13,15,14,15,14,16,13,13,11,10,10,8,7,7,7,6,5,5,4,3,1,1,0,1,2,2,3,3],[26,26,26,27,27,28,28,28,28,28,27,28,28,28,28,28,29,28,28,29,28,28,30,29,28,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,28,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,28,30,30,29,30,30,29,28,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,28,27,28,28,26,25,27,28,29,29,28,28,30,28,28,30,29,27,28,30,29,28,30,28,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,29,29,30,30,29,30,30,29,30,30,29,28,29,28,28,29,29,28,26,27,27,28,29,28,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,29,29,30,29,30,29,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,29,28,28,28,27,25,28,27,26,26,28,26,25,27,26,26,27,29,28,27,27,25,26,25,25,24,26,26,26,27,27,27,28,25,29,29,29,26,28,29,28,27,29,29,28,27,29,29,27,29,27,28,27,27,27,27,28,26,26,26,25,26,25,25,26,21,20,23,20,21,24,24,24,26,26,27,27,27,27,28,27,28,27,28,27,27,28,27,26,25,26,28,25,26,27,27,27,28,29,29,28,30,30,29,30,30,30,30,30,30,30,30,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,28,29,29,27,27,29,28,27,28,28,27,27,27,25,27,28,27,26,28,27,27,26,28,27,26,28,27,29,28,28,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,30,29,30,29,29,30,30,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,28,29,29,29,28,28,29,27,28,28,26,29,29,28,28,29,29,28,29,30,28,29,30,30,30,30,30,30,30,30,31,30,30,30,30,30,31,30,29,30,30,29,29,30,29,27,29,29,27,28,29,29,30,29,30,30,30,30,30,30,30,30,29,30,30,29,30,30,30,29,29,29,28,29,27,28,29,28,29,29,28,28,27,27,27,27,28,27,27,26,26,26,26,26,27,25,25,25,26,26,24,26,24,24,25,25,24,25,25,25,24,24,22,20,20,19,17,16,19,19,19,17,19,18,19,16,20,19,15,16,18,17,17,14,17,14,15,15,15,14,12,13,13,13,11,12,10,9,8,7,7,7,7,6,5,4,3,2,1,0,1,2,3,3],[26,27,26,27,27,28,28,28,28,28,27,27,28,27,28,28,28,28,28,29,29,28,29,29,29,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,29,29,30,30,30,30,30,30,29,30,30,30,28,29,29,29,29,29,29,29,29,30,29,29,29,29,29,29,29,29,30,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,29,29,30,29,28,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,29,29,30,29,28,30,30,28,28,30,30,28,29,30,28,28,29,29,30,29,29,30,30,29,30,30,30,30,30,29,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,28,29,29,29,29,30,29,29,29,29,30,29,29,29,30,28,28,29,28,26,27,28,26,25,26,27,28,26,25,26,25,28,26,25,28,29,25,27,29,28,26,28,29,28,28,29,28,29,29,29,29,29,29,29,30,29,29,30,29,28,29,30,29,26,29,29,27,25,28,29,28,29,28,27,28,28,26,27,27,27,26,27,27,25,25,27,26,27,27,27,27,29,28,27,29,29,29,29,29,29,29,29,29,30,29,30,30,30,30,30,29,30,30,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,29,30,29,29,29,29,29,29,30,29,29,29,29,30,29,29,29,29,30,29,29,29,30,30,29,30,30,30,30,30,30,30,29,30,29,30,29,29,29,30,30,30,30,30,29,29,30,30,30,30,29,30,30,29,29,29,28,29,29,29,29,29,29,29,29,28,29,28,28,27,26,25,28,27,25,26,28,27,26,28,28,27,26,28,28,26,26,24,27,25,26,25,25,27,26,26,27,27,27,27,28,28,29,28,28,29,29,26,28,29,28,27,28,28,27,28,26,28,27,26,27,27,27,25,26,26,25,25,24,24,24,21,19,22,18,19,23,22,22,24,24,24,25,25,25,27,25,25,24,27,25,23,25,25,23,24,26,25,26,27,26,26,27,28,28,28,28,30,29,29,29,30,29,29,30,29,29,30,29,30,29,29,30,29,30,29,30,29,30,29,30,30,30,29,30,30,30,30,29,30,30,29,29,30,30,30,30,30,30,30,29,29,29,30,30,30,30,30,28,29,29,28,27,28,28,25,26,26,26,25,26,26,26,25,25,24,24,26,26,25,26,26,26,25,27,26,27,27,28,27,27,28,28,29,29,30,30,30,29,29,30,30,29,30,30,30,30,30,30,29,29,30,29,29,30,30,30,30,30,30,30,30,30,29,29,29,29,29,30,29,29,30,29,29,29,29,29,29,29,29,29,29,30,29,29,30,30,30,30,30,29,29,29,28,27,28,28,26,27,28,28,27,28,28,27,27,28,28,28,29,29,28,29,29,28,29,29,30,29,30,29,30,29,29,30,29,29,30,29,30,30,29,28,30,29,28,28,30,28,27,28,29,27,28,29,29,29,29,30,29,29,29,30,30,29,30,29,30,30,28,29,29,29,29,28,29,27,28,27,27,29,29,29,29,28,28,27,28,28,27,27,28,27,27,28,27,25,27,28,25,24,26,27,23,24,25,25,23,24,24,21,23,23,24,23,22,22,21,19,19,19,16,18,18,16,16,18,16,16,16,18,18,15,15,18,17,18,15,18,15,15,17,15,15,15,15,14,13,13,13,11,9,8,9,7,7,8,7,5,5,4,3,2,1,0,1,3,2],[26,26,27,27,27,28,29,28,28,28,27,28,28,28,29,28,28,29,28,29,29,29,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,29,29,29,29,30,30,29,30,29,29,28,29,29,29,29,30,30,30,30,29,30,30,30,30,29,29,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,29,29,30,30,28,29,30,29,28,29,29,28,28,29,29,30,29,28,30,30,29,29,30,30,29,29,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,30,28,29,29,29,30,30,30,30,30,30,29,29,29,30,29,29,28,29,28,28,28,28,27,28,27,26,27,26,27,26,26,28,28,26,27,29,26,27,29,28,26,27,29,28,27,29,27,29,29,29,29,29,29,29,30,29,29,30,29,28,28,29,29,27,29,29,28,27,29,29,28,29,28,28,28,28,27,27,28,28,27,28,28,27,26,28,27,27,28,28,29,29,28,28,29,29,29,29,29,29,29,29,29,30,29,29,30,29,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,31,31,31,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,30,30,30,30,28,30,29,29,29,30,29,28,28,28,28,26,28,27,27,26,28,27,26,27,27,26,25,27,26,26,26,27,26,26,25,23,26,25,24,23,26,26,26,27,25,26,27,27,27,27,28,28,27,27,28,26,28,29,28,27,27,28,27,27,27,28,27,27,27,27,27,27,26,26,26,26,26,26,26,20,20,23,21,22,24,24,25,26,27,27,28,27,27,27,27,27,26,28,26,26,27,26,26,26,26,27,27,26,26,27,27,27,28,27,27,29,29,29,29,29,29,28,29,29,28,29,28,29,29,28,29,29,30,29,30,29,30,29,29,30,30,29,29,30,29,29,29,29,29,29,29,29,30,30,29,30,29,30,29,29,30,30,30,29,29,30,28,29,29,28,28,28,28,27,27,26,27,27,26,26,26,27,27,25,26,26,27,26,26,27,27,26,28,27,26,26,26,27,28,28,28,29,29,29,29,29,29,29,29,30,30,29,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,30,29,29,29,29,30,30,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,28,28,27,28,28,27,27,27,28,27,28,28,28,28,28,28,28,29,27,28,29,29,29,29,29,29,30,30,29,30,29,29,29,29,30,30,29,28,30,29,28,28,30,28,27,28,28,28,29,28,29,29,28,29,29,29,29,29,29,29,30,30,29,29,29,29,29,29,28,28,29,27,28,27,27,28,28,28,28,28,28,27,27,26,27,26,27,27,26,27,26,24,26,27,26,24,26,27,25,24,26,26,23,26,26,23,26,26,26,26,24,24,22,20,20,20,16,19,19,19,16,18,16,17,18,21,19,16,17,21,17,20,15,19,16,16,19,17,15,16,17,15,16,15,14,12,11,10,9,8,7,8,8,6,6,4,3,3,2,1,0,1,2],[25,26,26,27,26,27,28,28,27,28,27,28,28,27,28,27,28,28,28,29,28,28,29,29,28,29,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,28,29,30,30,29,29,30,29,28,30,29,30,29,29,29,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,29,28,29,29,29,28,28,28,28,27,27,28,28,28,28,28,28,29,27,29,29,29,28,28,29,29,27,28,27,29,29,30,29,30,30,30,30,30,29,30,30,28,29,30,30,28,30,29,28,28,29,30,29,30,29,28,29,29,28,28,29,29,27,28,28,28,26,27,27,28,28,28,29,29,29,29,29,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,29,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,30,29,29,29,29,29,28,27,28,27,26,28,27,27,27,27,25,27,28,26,27,28,28,27,28,27,27,26,26,25,23,27,27,27,28,26,28,28,26,28,28,29,27,27,28,28,26,28,29,27,27,28,29,27,28,27,28,27,27,27,27,28,27,27,27,26,27,26,27,26,21,22,24,22,22,24,25,25,27,27,26,28,27,28,28,27,27,27,28,27,27,28,27,26,26,26,28,26,26,27,28,27,28,28,28,27,30,29,29,29,29,29,30,29,30,29,29,28,29,29,28,29,29,30,30,30,30,30,29,30,30,30,29,30,29,30,30,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,29,29,28,28,28,28,27,27,28,27,27,27,26,27,27,28,26,27,27,27,27,28,27,26,28,26,28,28,28,28,29,29,28,29,30,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,29,29,29,29,29,30,30,30,29,29,30,30,30,30,30,30,30,30,30,29,29,30,29,28,29,29,28,28,28,28,28,28,28,27,28,29,27,28,28,28,28,29,28,29,29,29,30,29,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,29,28,29,30,28,27,28,28,27,28,28,28,29,29,29,29,30,29,29,30,30,30,29,30,30,29,30,30,29,29,29,29,27,28,27,28,28,28,29,28,28,28,28,28,28,27,27,27,26,27,27,26,26,27,27,26,25,27,27,26,27,27,26,25,26,26,25,26,26,26,25,23,23,22,20,22,20,19,20,19,20,18,19,18,19,19,20,20,17,16,20,19,19,16,19,16,18,19,17,16,16,16,14,16,14,14,13,11,12,11,9,9,9,9,7,7,6,4,4,4,2,1,0,1],[26,27,27,28,28,28,29,28,28,28,28,28,28,28,29,28,29,28,28,29,28,28,29,29,29,29,29,29,30,29,29,30,29,30,30,29,29,29,30,29,30,30,29,29,29,30,29,29,29,30,29,30,30,30,30,29,30,30,30,30,29,29,30,30,30,30,30,30,30,30,31,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,31,30,31,31,30,30,30,30,30,30,30,30,30,30,30,30,30,31,30,31,30,30,30,30,30,30,31,31,31,31,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,31,29,30,30,29,29,29,29,28,28,28,29,29,28,28,28,27,29,28,27,29,30,27,29,30,29,28,29,30,29,29,30,29,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,27,30,30,29,27,29,30,29,30,30,29,29,30,29,28,29,29,27,28,29,28,26,27,27,28,29,28,29,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,29,29,29,29,29,29,29,29,30,29,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,30,30,29,29,29,29,30,30,30,29,30,28,29,29,28,28,28,27,27,29,27,27,27,28,26,27,28,28,27,28,29,28,27,28,26,27,25,26,24,26,27,27,27,27,27,28,26,29,28,29,27,28,29,29,26,29,29,27,26,29,29,27,29,26,29,28,28,27,26,28,27,26,27,27,27,24,27,27,20,20,26,20,23,25,26,26,27,27,26,27,26,28,28,27,25,27,28,27,26,28,28,27,27,28,27,27,28,28,28,28,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,30,28,27,29,29,28,28,28,28,27,27,28,28,28,28,27,28,28,28,28,29,28,28,29,29,28,28,29,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29,29,29,29,28,28,29,29,28,29,28,28,29,29,28,29,29,29,29,30,30,29,29,30,30,29,30,30,30,30,30,30,30,30,30,30,30,30,30,29,30,30,29,29,30,29,27,29,29,27,28,29,30,29,30,30,29,30,30,30,31,30,30,29,30,30,29,29,30,30,29,28,29,27,28,27,27,29,29,29,29,27,29,28,30,28,27,29,28,28,28,28,29,27,29,29,27,26,28,28,26,28,27,27,26,26,27,27,28,26,26,26,25,25,23,21,23,23,20,21,21,21,19,19,19,19,19,21,21,18,18,20,21,21,18,23,19,23,22,22,20,18,19,18,17,15,16,17,13,14,16,13,11,11,12,10,9,7,6,6,4,4,3,1,0]],"max_predicted_aligned_error":31.75}]
\ No newline at end of file
diff --git a/examples/argfiles/test_fab41-B.txt b/examples/argfiles/test_fab41-B.txt
new file mode 100644 (file)
index 0000000..4bf0b31
--- /dev/null
@@ -0,0 +1,4 @@
+--open[B]=./examples/uniref50.fa
+--colour[B]=clustal
+--image[B]=outputB.html
+--close[B]
diff --git a/examples/argfiles/test_fab41-autocounter.txt b/examples/argfiles/test_fab41-autocounter.txt
new file mode 100644 (file)
index 0000000..9981286
--- /dev/null
@@ -0,0 +1,14 @@
+--open[{++n}]=./examples/test_fab41.result/sample.a2m
+--colour[{n}]=clustal
+--structure[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb
+--paematrix[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json
+--structure[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb
+--paematrix[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4_scores.json
+--structure[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb
+--paematrix[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2_scores.json
+--structure[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5.pdb
+--paematrix[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5_scores.json
+--structure[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1.pdb
+--paematrix[{n}]=./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1_scores.json
+--image[{n}]=output1.html
+--close
diff --git a/examples/argfiles/test_fab41.txt b/examples/argfiles/test_fab41.txt
new file mode 100644 (file)
index 0000000..b7f0d45
--- /dev/null
@@ -0,0 +1,13 @@
+--open=./examples/test_fab41.result/sample.a2m
+--colour=gecos:flower
+--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb
+--paematrix=[label=pAE R1-M3]./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json
+--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb
+--paematrix=[label=pAE R2-M4]./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4_scores.json
+--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb
+--paematrix=[label=pAE R3-M2]./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2_scores.json
+--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5.pdb
+--paematrix=[label=pAE R4-M5]./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5_scores.json
+--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1.pdb
+--paematrix=[label=pAE R5-M1]./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1_scores.json
+--image=[textrenderer=text]output1.html
diff --git a/examples/argfiles/test_fab41_nostructureviewers.txt b/examples/argfiles/test_fab41_nostructureviewers.txt
new file mode 100644 (file)
index 0000000..ab52cdf
--- /dev/null
@@ -0,0 +1,14 @@
+--open=./examples/test_fab41.result/sample.a2m
+--colour=gecos:flower
+--gui
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb
+--paematrix=[label=pAE R1-M3]./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb
+--paematrix=[label=pAE R2-M4]./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4_scores.json
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb
+--paematrix=[label=pAE R3-M2]./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2_scores.json
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5.pdb
+--paematrix=[label=pAE R4-M5]./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5_scores.json
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1.pdb
+--paematrix=[label=pAE R5-M1]./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1_scores.json
+--image=[textrenderer=text]output1.html
diff --git a/examples/test_fab41.result/argfile.txt b/examples/test_fab41.result/argfile.txt
new file mode 100644 (file)
index 0000000..52d68ee
--- /dev/null
@@ -0,0 +1,24 @@
+--debug
+--nonews
+--nosplash
+--noannotation
+--substitutions
+--open={argfiledirname}/sample.a2m
+--colour=gecos:flower
+--structure={dirname}/test_fab41_unrelaxed_rank_1_model_3.pdb
+--paematrix={dirname}/test_fab41_unrelaxed_rank_1_model_3_scores.json
+--tempfac=plddt
+--structure={dirname}/test_fab41_unrelaxed_rank_2_model_4.pdb
+--paematrix={dirname}/test_fab41_unrelaxed_rank_2_model_4_scores.json
+--tempfac=plddt
+--structure={dirname}/test_fab41_unrelaxed_rank_3_model_2.pdb
+--paematrix={dirname}/test_fab41_unrelaxed_rank_3_model_2_scores.json
+--tempfac=plddt
+--structure={dirname}/test_fab41_unrelaxed_rank_4_model_5.pdb
+--paematrix={dirname}/test_fab41_unrelaxed_rank_4_model_5_scores.json
+--tempfac=plddt
+--structure={dirname}/test_fab41_unrelaxed_rank_5_model_1.pdb
+--tempfac=plddt
+--paematrix={dirname}/test_fab41_unrelaxed_rank_5_model_1_scores.json
+--image={dirname}/{basename}.html
+#--headless
diff --git a/examples/testdata/7WKP-rna1.xml b/examples/testdata/7WKP-rna1.xml
new file mode 100644 (file)
index 0000000..2703212
--- /dev/null
@@ -0,0 +1,491 @@
+<?xml version="1.0"?>
+<!DOCTYPE rnaml SYSTEM "rnaml.dtd">
+
+<rnaml version="1.0">
+
+   <molecule id="1">
+      <sequence>
+         <numbering-system id="1" used-in-file="false">
+            <numbering-range>
+               <start>1</start>
+               <end>20</end>
+            </numbering-range>
+         </numbering-system>
+         <numbering-table length="20" comment="sequence number in pdb file">
+            1    2    3    4    5    6    7    8    9   10 
+           11   12   13   14   15   16   17   18   19   20 
+         
+         </numbering-table>
+         <seq-data>
+            GUUAGCAGCC GCAUAGGCUG 
+         </seq-data>
+         <seq-annotation comment="?">
+            <segment>
+               <seg-name>LOOP1</seg-name>
+               <base-id-5p><base-id><position>12</position></base-id></base-id-5p>
+               <base-id-3p><base-id><position>14</position></base-id></base-id-3p>
+            </segment>
+         </seq-annotation>
+      </sequence>
+      <structure>
+         <model id="?">
+            <model-info>
+               <method>Crystallography ?</method>
+               <resolution>? Angstroms</resolution>
+            </model-info>
+            <base>
+               <position>1</position>
+               <base-type>G</base-type>
+               <atom serial="1">
+                  <atom-type> P  </atom-type>
+                     <coordinates>7.232 28.529 -12.305</coordinates>
+               </atom>
+               <atom serial="9">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>4.752 23.963 -11.820</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>2</position>
+               <base-type>U</base-type>
+               <atom serial="24">
+                  <atom-type> P  </atom-type>
+                     <coordinates>3.868 23.252 -12.962</coordinates>
+               </atom>
+               <atom serial="32">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>0.983 18.432 -13.409</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>3</position>
+               <base-type>U</base-type>
+               <atom serial="44">
+                  <atom-type> P  </atom-type>
+                     <coordinates>1.438 17.540 -14.670</coordinates>
+               </atom>
+               <atom serial="52">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-1.417 16.962 -19.633</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>4</position>
+               <base-type>A</base-type>
+               <atom serial="64">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-2.710 16.020 -19.430</coordinates>
+               </atom>
+               <atom serial="72">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-7.138 19.555 -19.112</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>5</position>
+               <base-type>G</base-type>
+               <atom serial="86">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-7.829 20.393 -20.298</coordinates>
+               </atom>
+               <atom serial="94">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-11.316 24.166 -18.659</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>6</position>
+               <base-type>C</base-type>
+               <atom serial="109">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-12.021 24.790 -19.958</coordinates>
+               </atom>
+               <atom serial="117">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-14.686 21.023 -22.223</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>7</position>
+               <base-type>A</base-type>
+               <atom serial="129">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-16.102 21.690 -22.577</coordinates>
+               </atom>
+               <atom serial="137">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-20.284 18.901 -22.582</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>8</position>
+               <base-type>G</base-type>
+               <atom serial="151">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-21.555 19.844 -22.854</coordinates>
+               </atom>
+               <atom serial="159">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-26.285 20.028 -19.599</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>9</position>
+               <base-type>C</base-type>
+               <atom serial="174">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-27.355 21.190 -19.880</coordinates>
+               </atom>
+               <atom serial="182">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-30.900 21.877 -16.104</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>10</position>
+               <base-type>C</base-type>
+               <atom serial="194">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-31.737 23.147 -16.621</coordinates>
+               </atom>
+               <atom serial="202">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-33.685 26.755 -13.690</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>11</position>
+               <base-type>G</base-type>
+               <atom serial="214">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-34.360 27.602 -14.877</coordinates>
+               </atom>
+               <atom serial="222">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-34.025 32.801 -15.050</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>12</position>
+               <base-type>C</base-type>
+               <atom serial="237">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-35.037 32.875 -16.296</coordinates>
+               </atom>
+               <atom serial="245">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-31.850 33.486 -20.341</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>13</position>
+               <base-type>A</base-type>
+               <atom serial="257">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-30.767 32.411 -19.837</coordinates>
+               </atom>
+               <atom serial="265">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-25.756 33.919 -20.714</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>14</position>
+               <base-type>U</base-type>
+               <atom serial="279">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-24.465 33.135 -20.171</coordinates>
+               </atom>
+               <atom serial="287">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-21.219 37.107 -19.013</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>15</position>
+               <base-type>A</base-type>
+               <atom serial="299">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-22.129 38.268 -18.376</coordinates>
+               </atom>
+               <atom serial="307">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-20.542 37.656 -12.798</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>16</position>
+               <base-type>G</base-type>
+               <atom serial="321">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-19.666 36.373 -12.391</coordinates>
+               </atom>
+               <atom serial="329">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-21.101 34.091 -7.803</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>17</position>
+               <base-type>G</base-type>
+               <atom serial="344">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-20.251 32.728 -7.687</coordinates>
+               </atom>
+               <atom serial="352">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-22.951 28.722 -5.266</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>18</position>
+               <base-type>C</base-type>
+               <atom serial="367">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-21.797 27.634 -5.014</coordinates>
+               </atom>
+               <atom serial="375">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-23.692 22.611 -5.084</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>19</position>
+               <base-type>U</base-type>
+               <atom serial="387">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-22.583 21.449 -4.989</coordinates>
+               </atom>
+               <atom serial="395">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-22.919 16.822 -7.040</coordinates>
+               </atom>
+            </base>
+            <base>
+               <position>20</position>
+               <base-type>G</base-type>
+               <atom serial="407">
+                  <atom-type> P  </atom-type>
+                     <coordinates>-21.585 16.199 -6.397</coordinates>
+               </atom>
+               <atom serial="415">
+                  <atom-type> O3'</atom-type>
+                     <coordinates>-18.522 13.024 -10.277</coordinates>
+               </atom>
+            </base>
+            <str-annotation>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>1</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>2</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>S</edge-5p>
+                  <edge-3p>H</edge-3p>
+                  <bond-orientation>c</bond-orientation>
+               </base-pair>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>6</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>20</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>+</edge-5p>
+                  <edge-3p>+</edge-3p>
+                  <bond-orientation>c</bond-orientation>
+               </base-pair>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>7</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>19</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>-</edge-5p>
+                  <edge-3p>-</edge-3p>
+                  <bond-orientation>c</bond-orientation>
+               </base-pair>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>8</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>18</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>+</edge-5p>
+                  <edge-3p>+</edge-3p>
+                  <bond-orientation>c</bond-orientation>
+               </base-pair>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>9</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>17</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>+</edge-5p>
+                  <edge-3p>+</edge-3p>
+                  <bond-orientation>c</bond-orientation>
+               </base-pair>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>10</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>16</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>+</edge-5p>
+                  <edge-3p>+</edge-3p>
+                  <bond-orientation>c</bond-orientation>
+               </base-pair>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>11</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>15</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>S</edge-5p>
+                  <edge-3p>H</edge-3p>
+                  <bond-orientation>t</bond-orientation>
+               </base-pair>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>3</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>4</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>!</edge-5p>
+                  <edge-3p>!</edge-3p>
+                  <bond-orientation>!</bond-orientation>
+               </base-pair>
+               <base-pair comment="?">
+                  <base-id-5p>
+                     <base-id><position>14</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>15</position></base-id>
+                  </base-id-3p>
+                  <edge-5p>!</edge-5p>
+                  <edge-3p>!</edge-3p>
+                  <bond-orientation>!</bond-orientation>
+               </base-pair>
+               <helix id="H1">
+                  <base-id-5p>
+                     <base-id><position>6</position></base-id>
+                  </base-id-5p>
+                  <base-id-3p>
+                     <base-id><position>20</position></base-id>
+                  </base-id-3p>
+                  <length>6</length>
+               </helix>
+               <single-strand>
+                  <segment>
+                     <seg-name>SG1</seg-name>
+                     <base-id-5p><base-id><position>1</position></base-id></base-id-5p>
+                     <base-id-3p><base-id><position>5</position></base-id></base-id-3p>
+                  </segment>
+               </single-strand>
+               <single-strand>
+                  <segment>
+                     <seg-name>SG2</seg-name>
+                     <base-id-5p><base-id><position>12</position></base-id></base-id-5p>
+                     <base-id-3p><base-id><position>14</position></base-id></base-id-3p>
+                  </segment>
+               </single-strand>
+            </str-annotation>
+            <secondary-structure-display comment="x,y coodinates">
+               <ss-base-coord>
+                  <base-id><position>1</position></base-id>
+                  <coordinates>133.930 0.000</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>2</position></base-id>
+                  <coordinates>133.930 33.482</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>3</position></base-id>
+                  <coordinates>133.930 66.965</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>4</position></base-id>
+                  <coordinates>133.930 100.447</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>5</position></base-id>
+                  <coordinates>133.930 133.930</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>6</position></base-id>
+                  <coordinates>133.930 167.412</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>7</position></base-id>
+                  <coordinates>133.930 223.216</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>8</position></base-id>
+                  <coordinates>133.930 279.021</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>9</position></base-id>
+                  <coordinates>133.930 334.825</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>10</position></base-id>
+                  <coordinates>133.930 390.629</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>11</position></base-id>
+                  <coordinates>133.930 446.433</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>12</position></base-id>
+                  <coordinates>128.630 516.439</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>13</position></base-id>
+                  <coordinates>66.965 550.000</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>14</position></base-id>
+                  <coordinates>5.300 516.439</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>15</position></base-id>
+                  <coordinates>0.000 446.433</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>16</position></base-id>
+                  <coordinates>0.000 390.629</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>17</position></base-id>
+                  <coordinates>0.000 334.825</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>18</position></base-id>
+                  <coordinates>0.000 279.021</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>19</position></base-id>
+                  <coordinates>0.000 223.216</coordinates>
+               </ss-base-coord>
+               <ss-base-coord>
+                  <base-id><position>20</position></base-id>
+                  <coordinates>0.000 167.412</coordinates>
+               </ss-base-coord>
+            </secondary-structure-display>
+         </model>
+      </structure>
+   </molecule>
+
+
+   <interactions>
+            <str-annotation>
+            </str-annotation>
+   </interactions>
+</rnaml>
index 1a5992a..25d39f4 100644 (file)
@@ -1 +1 @@
-1.8.3-1.2.13_FJVL
+1.8.3-1.3.0_FJVL
index 60daf6c..12110b2 100644 (file)
@@ -1 +1 @@
-1.8.3-1.2.13_JVL
+1.8.3-1.3.0_JVL
index 5c98d23..fb8f1bc 100644 (file)
Binary files a/getdown/lib/getdown-core.jar and b/getdown/lib/getdown-core.jar differ
index b022d9f..c74dcc5 100644 (file)
Binary files a/getdown/lib/getdown-launcher-local.jar and b/getdown/lib/getdown-launcher-local.jar differ
index b9e3c6b..e1f1726 100644 (file)
Binary files a/getdown/lib/getdown-launcher.jar and b/getdown/lib/getdown-launcher.jar differ
index ed0f34a..d8bb7e9 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.threerings.getdown</groupId>
     <artifactId>getdown</artifactId>
-    <version>1.8.3-1.2.13_FJVL</version>
+    <version>1.8.3-1.3.0_FJVL</version>
   </parent>
 
   <artifactId>getdown-ant</artifactId>
index a7dfa07..6126686 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.threerings.getdown</groupId>
     <artifactId>getdown</artifactId>
-    <version>1.8.3-1.2.13_FJVL</version>
+    <version>1.8.3-1.3.0_FJVL</version>
   </parent>
 
   <artifactId>getdown-core</artifactId>
index 31a69c3..1faaa28 100644 (file)
@@ -17,6 +17,8 @@ import javax.xml.bind.DatatypeConverter;
 
 import java.security.MessageDigest;
 
+import jalview.util.LaunchUtils;
+
 import static com.threerings.getdown.Log.log;
 
 /**
@@ -88,6 +90,7 @@ public class LaunchUtil
         return getJVMPath(appdir, false);
     }
 
+    private static String jvmPath = null;
     /**
      * Reconstructs the path to the JVM used to launch this process.
      *
@@ -95,22 +98,27 @@ public class LaunchUtil
      */
     public static String getJVMPath (File appdir, boolean windebug)
     {
-        // first look in our application directory for an installed VM
-        String vmpath = checkJVMPath(new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath(), windebug);
-        if (vmpath == null && isMacOS()) {
-                       vmpath = checkJVMPath(new File(appdir, LOCAL_JAVA_DIR + "/Contents/Home").getAbsolutePath(), windebug);
+        if (jvmPath != null) {
+          return jvmPath;
         }
+        
+        // first look in our application directory for an installed VM
+        final String appDir = isMacOS() ?
+                        (new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath()) + "/Contents/Home"
+                        : new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath();
+
+        String javaBin = LaunchUtils.findJavaBin(appDir, windebug, false);
 
         // then fall back to the VM in which we're already running
-        if (vmpath == null) {
-            vmpath = checkJVMPath(System.getProperty("java.home"), windebug);
+        if (javaBin == null) {
+            javaBin = LaunchUtils.findJavaBin(System.getProperty("java.home"), windebug, false);
         }
 
         // then throw up our hands and hope for the best
-        if (vmpath == null) {
+        if (javaBin == null) {
+            javaBin = LaunchUtils.findJavaBin(null, windebug, true);
             log.warning("Unable to find java [appdir=" + appdir +
                         ", java.home=" + System.getProperty("java.home") + "]!");
-            vmpath = "java";
         }
 
         // Oddly, the Mac OS X specific java flag -Xdock:name will only work if java is launched
@@ -120,15 +128,16 @@ public class LaunchUtil
         if (isMacOS()) {
             try {
                 File localVM = new File("/usr/bin/java").getCanonicalFile();
-                if (localVM.equals(new File(vmpath).getCanonicalFile())) {
-                    vmpath = "/usr/bin/java";
+                if (localVM.equals(new File(javaBin).getCanonicalFile())) {
+                    javaBin = "/usr/bin/java";
                 }
             } catch (IOException ioe) {
                 log.warning("Failed to check Mac OS canonical VM path.", ioe);
             }
         }
 
-        return vmpath;
+        jvmPath = javaBin;
+        return jvmPath;
     }
 
     private static String _getMD5FileChecksum (File file) {
@@ -233,12 +242,47 @@ public class LaunchUtil
     public static final boolean isLinux () { return _isLinux; }
 
     /**
+     * Check if a symlink (or file) points to a JVM
+     */
+    private static boolean checkJVMSymlink(String testBin)
+    {
+      File testBinFile = new File(testBin);
+      if (!testBinFile.exists())
+      {
+        return false;
+      }
+      File targetFile = null;
+      try
+      {
+        targetFile = testBinFile.getCanonicalFile();
+      } catch (IOException e)
+      {
+        return false;
+      }
+      if (targetFile != null && ("java".equals(targetFile.getName())
+            || "java.exe".equals(targetFile.getName())))
+      {
+        return true;
+      }
+      return false;
+    }
+
+    /**
      * Checks whether a Java Virtual Machine can be located in the supplied path.
      */
     protected static String checkJVMPath (String vmhome, boolean windebug)
     {
         String vmbase = vmhome + File.separator + "bin" + File.separator;
-        String vmpath = vmbase + "java";
+        String appName = System.getProperty("channel.app_name", "Jalview");
+        String vmpath = vmbase + appName;
+        if (checkJVMSymlink(vmpath)) {
+          return vmpath;
+        }
+        vmpath = vmbase + "Jalview";
+        if (checkJVMSymlink(vmpath)) {
+          return vmpath;
+        }
+        vmpath = vmbase + "java";
         if (new File(vmpath).exists()) {
             return vmpath;
         }
index 75106cc..2bce673 100644 (file)
@@ -1,8 +1,28 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.bin;
 
-import java.awt.HeadlessException;
 import java.util.Locale;
 
+import java.awt.HeadlessException;
 
 public class HiDPISetting
 {
@@ -36,6 +56,8 @@ public class HiDPISetting
 
   public static int scale = 0;
 
+  public final static int MAX_SCALE = 8;
+
   private static boolean doneInit = false;
 
   private static boolean allowScalePropertyArg = false;
@@ -68,8 +90,17 @@ public class HiDPISetting
 
     // get and use command line property values first
     String setHiDPIProperty = System.getProperty(setHiDPIPropertyName);
-    setHiDPI = setHiDPIProperty != null
-            && setHiDPIProperty.equalsIgnoreCase("true");
+    boolean setHiDPIPropertyBool = Boolean.parseBoolean(setHiDPIProperty);
+
+    // allow -DsetHiDPI=false to turn off HiDPI scaling
+    if (setHiDPIProperty != null && !setHiDPIPropertyBool)
+    {
+      clear();
+      doneInit = true;
+      return;
+    }
+
+    setHiDPI = setHiDPIProperty != null && setHiDPIPropertyBool;
 
     String setHiDPIScaleProperty = System
             .getProperty(setHiDPIScalePropertyName);
@@ -78,6 +109,12 @@ public class HiDPISetting
       try
       {
         setHiDPIScale = Integer.parseInt(setHiDPIScaleProperty);
+        // if setHiDPIScale property is validly set and setHiDPI property wasn't
+        // attempted to be set we assume setHiDPIScale to be true
+        if (setHiDPIProperty == null)
+        {
+          setHiDPI = true;
+        }
       } catch (NumberFormatException e)
       {
         System.err.println(setHiDPIScalePropertyName + " property give ("
@@ -151,6 +188,16 @@ public class HiDPISetting
 
     int dimensionScale = 1 + (mindimension / bigScreenThreshold);
 
+    // reject outrageous values -- dpiScale in particular could be mistaken
+    if (dpiScale > MAX_SCALE)
+    {
+      dpiScale = 1;
+    }
+    if (dimensionScale > MAX_SCALE)
+    {
+      dimensionScale = 1;
+    }
+
     // choose larger of dimensionScale or dpiScale (most likely dimensionScale
     // as dpiScale often misreported)
     int autoScale = Math.max(dpiScale, dimensionScale);
index f5f0196..bb545cb 100644 (file)
@@ -22,6 +22,8 @@
  */
 package jalview.bin;
 
+import java.util.Locale;
+
 /**
  * Methods to decide on appropriate memory setting for Jalview based on two
  * optionally provided values: jvmmempc - the maximum percentage of total
@@ -33,8 +35,6 @@ package jalview.bin;
  * @author bsoares
  *
  */
-import java.util.Locale;
-
 public class MemorySetting
 {
   public static final String MAX_HEAPSIZE_PERCENT_PROPERTY_NAME = "jvmmempc";
@@ -363,7 +363,7 @@ public class MemorySetting
 
   public static String memoryLongToString(long mem)
   {
-    return memoryLongToString(mem, "%.1f");
+    return memoryLongToString(mem, "%.3f");
   }
 
   public static String memoryLongToString(long mem, String format)
@@ -409,4 +409,4 @@ public class MemorySetting
     return ADJUSTMENT_MESSAGE;
   }
 
-}
\ No newline at end of file
+}
index 899bf94..18ef79e 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.bin;
 
 import java.awt.Toolkit;
index 40f6110..4832588 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.util;
 
 import java.awt.Image;
@@ -57,6 +77,7 @@ public class ChannelProperties
     defaultProps.put("default_appbase",
             "https://www.jalview.org/getdown/release/1.8");
     defaultProps.put("preferences.filename", ".jalview_properties");
+    defaultProps.put("channel", "none");
 
     // load channel_properties
     Properties tryChannelProps = new Properties();
index 3302dba..784eb5a 100644 (file)
@@ -1,14 +1,47 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.util;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.Properties;
 
 public class LaunchUtils
 {
 
+  // setting these is LaunchUtils so don't need to import Platform
+  public final static boolean isMac = System.getProperty("os.name")
+          .indexOf("Mac") > -1;
+
+  public final static boolean isWindows = System.getProperty("os.name")
+          .indexOf("Win") > -1;
+
+  private static boolean isJS = /** @j2sNative true || */
+          false;
+
   public static void loadChannelProps(File dir)
   {
     ChannelProperties.loadProps(dir);
@@ -53,4 +86,198 @@ public class LaunchUtils
   {
     return Boolean.parseBoolean(getUserPreference(key));
   }
+
+  public static int JAVA_COMPILE_VERSION = 0;
+
+  public static int getJavaCompileVersion()
+  {
+    if (LaunchUtils.isJS)
+    {
+      return -1;
+    }
+    else if (JAVA_COMPILE_VERSION > 0)
+    {
+      return JAVA_COMPILE_VERSION;
+    }
+    String buildDetails = "jar:".concat(LaunchUtils.class
+            .getProtectionDomain().getCodeSource().getLocation().toString()
+            .concat("!" + "/.build_properties"));
+    try
+    {
+      URL localFileURL = new URL(buildDetails);
+      InputStream in = localFileURL.openStream();
+      Properties buildProperties = new Properties();
+      buildProperties.load(in);
+      in.close();
+      String JCV = buildProperties.getProperty("JAVA_COMPILE_VERSION",
+              null);
+      if (JCV == null)
+      {
+        System.out.println(
+                "Could not obtain JAVA_COMPILE_VERSION for comparison");
+        return -2;
+      }
+      JAVA_COMPILE_VERSION = Integer.parseInt(JCV);
+    } catch (MalformedURLException e)
+    {
+      System.err.println("Could not find " + buildDetails);
+      return -3;
+    } catch (IOException e)
+    {
+      System.err.println("Could not load " + buildDetails);
+      return -4;
+    } catch (NumberFormatException e)
+    {
+      System.err.println("Could not parse JAVA_COMPILE_VERSION");
+      return -5;
+    }
+
+    return JAVA_COMPILE_VERSION;
+  }
+
+  public static int JAVA_VERSION = 0;
+
+  public static int getJavaVersion()
+  {
+    if (LaunchUtils.isJS)
+    {
+      return -1;
+    }
+    else if (JAVA_VERSION > 0)
+    {
+      return JAVA_VERSION;
+    }
+    try
+    {
+      String JV = System.getProperty("java.version");
+      if (JV == null)
+      {
+        System.out.println("Could not obtain java.version for comparison");
+        return -2;
+      }
+      if (JV.startsWith("1."))
+      {
+        JV = JV.substring(2);
+      }
+      JAVA_VERSION = JV.indexOf(".") == -1 ? Integer.parseInt(JV)
+              : Integer.parseInt(JV.substring(0, JV.indexOf(".")));
+    } catch (NumberFormatException e)
+    {
+      System.err.println("Could not parse java.version");
+      return -3;
+    }
+    return JAVA_VERSION;
+  }
+
+  public static boolean checkJavaVersion()
+  {
+    if (LaunchUtils.isJS)
+    {
+      return true;
+    }
+    String buildDetails = "jar:".concat(LaunchUtils.class
+            .getProtectionDomain().getCodeSource().getLocation().toString()
+            .concat("!" + "/.build_properties"));
+
+    int java_compile_version = getJavaCompileVersion();
+    int java_version = getJavaVersion();
+
+    if (java_compile_version <= 0 || java_version <= 0)
+    {
+      System.out.println("Could not make Java version check");
+      return true;
+    }
+    // Warn if these java.version and JAVA_COMPILE_VERSION conditions exist
+    // Usually this means a Java 11 compiled JAR being run by a Java 11 JVM
+    if (java_version >= 11 && java_compile_version < 11)
+    {
+      return false;
+    }
+
+    return true;
+  }
+
+  public static String findJavaBin(boolean winConsole)
+  {
+    return findJavaBin(System.getProperty("java.home"), winConsole, true);
+  }
+
+  /*
+   * Returns a string path to the most likely java binary wanted to run this
+   * installation of Jalview.
+   * 
+   * @param  winConsole  whether to use java.exe (console) in preference to javaw.exe
+   *                     (only affects Windows).
+   * @param  javaHome    Try this javaHome dir (defaults to the running java.home).
+   * @param  generic     Return a generic java command if not found.
+   */
+  public static String findJavaBin(String javaHome, boolean winConsole,
+          boolean generic)
+  {
+    String javaBin = null;
+    final String javaExe = winConsole ? "java.exe" : "javaw.exe";
+    final String java = "java";
+
+    if (javaHome != null)
+    {
+      // property "channel.app_name" is set by install4j when launching getdown
+      String propertyAppName = System.getProperty("channel.app_name");
+      final String appName = (propertyAppName != null
+              && propertyAppName.length() > 0) ? propertyAppName
+                      : ChannelProperties.getProperty("app_name");
+
+      final String javaBinDir = javaHome + File.separator + "bin"
+              + File.separator;
+
+      // appName and "Jalview" will not point to javaw.exe or java.exe but in
+      // this case that's okay because the taskbar display name problem doesn't
+      // manifest in Windows. See JAL-3820, JAL-4189.
+      for (String name : new String[] { appName, "Jalview", java, javaExe })
+      {
+        if (LaunchUtils.checkJVMSymlink(javaBinDir + name, winConsole))
+        {
+          javaBin = javaBinDir + name;
+          break;
+        }
+      }
+    }
+
+    if (javaBin == null && generic)
+    {
+      javaBin = LaunchUtils.isWindows ? javaExe : java;
+    }
+
+    return javaBin;
+  }
+
+  /*
+   * checkJVMSymlink returns true if the path in testBin *is* a java binary, or
+   * points to a java binary.
+   * @param  testBin     The binary or symbolic link to check
+   * @param  winConsole  whether we are in/want a Windows console (only relevant for Windows,
+   *                     determines whether we use java.exe or javaw.exe)
+   */
+  private static boolean checkJVMSymlink(String testBin, boolean winConsole)
+  {
+    File testBinFile = new File(testBin);
+    if (!testBinFile.exists())
+    {
+      return false;
+    }
+    File targetFile = null;
+    try
+    {
+      targetFile = testBinFile.getCanonicalFile();
+    } catch (IOException e)
+    {
+      return false;
+    }
+    final String javaExe = winConsole ? "java.exe" : "javaw.exe";
+    if (targetFile != null && ("java".equals(targetFile.getName())
+            || javaExe.equals(targetFile.getName())))
+    {
+      return true;
+    }
+    return false;
+  }
 }
index afb9c89..1c67c92 100644 (file)
@@ -25,6 +25,7 @@ import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 public class StringUtils
@@ -412,7 +413,8 @@ public class StringUtils
     {
       return s.toUpperCase(Locale.ROOT);
     }
-    return s.substring(0, 1).toUpperCase(Locale.ROOT) + s.substring(1).toLowerCase(Locale.ROOT);
+    return s.substring(0, 1).toUpperCase(Locale.ROOT)
+            + s.substring(1).toLowerCase(Locale.ROOT);
   }
 
   /**
@@ -583,4 +585,54 @@ public class StringUtils
     }
     return min < text.length() + 1 ? min : -1;
   }
+
+  public static int indexOfFirstWhitespace(String text)
+  {
+    int index = -1;
+    Pattern pat = Pattern.compile("\\s");
+    Matcher m = pat.matcher(text);
+    if (m.find())
+    {
+      index = m.start();
+    }
+    return index;
+  }
+
+  /*
+   * implementation of String.replaceLast.
+   * Replaces only the last occurrence of toReplace in string with replacement.
+   */
+  public static String replaceLast(String string, String toReplace,
+          String replacement)
+  {
+    int pos = string.lastIndexOf(toReplace);
+    if (pos > -1)
+    {
+      return new StringBuilder().append(string.substring(0, pos))
+              .append(replacement)
+              .append(string.substring(pos + toReplace.length()))
+              .toString();
+    }
+    else
+    {
+      return string;
+    }
+
+  }
+
+  /* 
+   * return the maximum length of a List of Strings
+   */
+  public static int maxLength(List<String> l)
+  {
+    int max = 0;
+    for (String s : l)
+    {
+      if (s == null)
+        continue;
+      if (s.length() > max)
+        max = s.length();
+    }
+    return max;
+  }
 }
index 6cf40a8..4374899 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.threerings.getdown</groupId>
     <artifactId>getdown</artifactId>
-    <version>1.8.3-1.2.13_FJVL</version>
+    <version>1.8.3-1.3.0_FJVL</version>
   </parent>
 
   <artifactId>getdown-launcher</artifactId>
index 36bc298..ba092a7 100755 (executable)
@@ -3,7 +3,7 @@
 if [ x$JVLVERSION != x ]; then
   export VERSION=$JVLVERSION
 else
-  export VERSION=1.8.3-1.2.13_JVL
+  export VERSION=1.8.3-1.3.0_JVL
 fi
 
 if [ x${VERSION%_JVL} = x$VERSION ]; then
index dc12610..51e9514 100644 (file)
@@ -10,7 +10,7 @@
   <groupId>com.threerings.getdown</groupId>
   <artifactId>getdown</artifactId>
   <packaging>pom</packaging>
-  <version>1.8.3-1.2.13_FJVL</version>
+  <version>1.8.3-1.3.0_FJVL</version>
 
   <name>getdown</name>
   <description>An application installer and updater.</description>
index 7b3a031..547304f 100644 (file)
@@ -201,7 +201,7 @@ jalviewjs_j2s_alt_file_property_config = j2s.config.altfileproperty
 # for developing in Eclipse as IDE, set this to automatically copy current swingjs/net.sf.j2s.core.jar to your dropins dir
 jalviewjs_eclipseIDE_auto_copy_j2s_plugin = false
 # Override this in a local.properties file
-jalviewjs_eclipse_root = ~/buildtools/eclipse/jee-2019-09
+jalviewjs_eclipse_root = ~/buildtools/eclipse/latest
 
 jalviewjs_eclipse_dropins_dir = utils/jalviewjs/eclipse/dropins
 jalviewjs_swingjs_zip = swingjs/SwingJS-site.zip
@@ -260,5 +260,14 @@ jalviewjs_j2s_to_console = true
 jalviewjs_closure_compiler = tools/closure_compiler.jar
 jalviewjs_j2s_closure_stdout = j2s-closure.out
 
+# for checking jalviewjs launches okay
+jalviewjs_chromium_binary = ~/buildtools/chromium/chrome
+jalviewjs_macos_chromium_binary = /Applications/Chromium.app/Contents/MacOS/Chromium
+jalviewjs_chromium_user_dir = chromium
+jalviewjs_chromium_idle_timeout = 10
+jalviewjs_chromium_overall_timeout = 40
+jalviewjs_chromium_profile_name = BUILD
+jalviewjs_stderr_launch = utils/jalviewjs/chromium_test/jalview_bin_Jalview-stderr.html
+jalviewjs_desktop_init_string = JALVIEWJS: CREATED DESKTOP
 
 testp=gradle.properties
index cd415ea..a2094f7 100755 (executable)
    <mapID target="commandline" url="html/features/commandline.html"/>
    <mapID target="jalviewcltool" url="html/features/commandline.html#script"/>
    <mapID target="clarguments" url="html/features/clarguments.html"/>
+   <mapID target="clarguments-basic" url="html/features/clarguments-basic.html"/>
+   <mapID target="clarguments-advanced" url="html/features/clarguments-advanced.html"/>
+   <mapID target="clarguments-argfiles" url="html/features/clarguments-argfiles.html"/>
+   <mapID target="clarguments-reference" url="html/features/clarguments-reference.html"/>
+   <mapID target="clarguments-old" url="html/features/clarguments-old.html"/>
    <mapID target="jvlfiles" url="html/features/jvlfiles.html"/>
    <mapID target="io" url="html/io/index.html"/>
    <mapID target="io.modellerpir" url="html/io/modellerpir.html"/>
index 877c758..d7ff3d4 100755 (executable)
@@ -29,7 +29,7 @@
                                <tocitem text="Structures via 3D Beacons" target="structuresvia3dbeacons" />
                                <tocitem text="Startup Memory Settings" target="startupprefs" />
                        <tocitem text="The Java Console, Logging and Reporting Bugs" target="logging" />
-                       <tocitem text="Command line launch scripts" target="jalviewcltool"/>
+                       <tocitem text="Command line launch" target="jalviewcltool"/>
                </tocitem>
                
                <tocitem text="Editing Alignments" target="edit" />
                        <tocitem text="Groovy Features Counter example" target="groovy.featurescounter"/>
                </tocitem>
                <tocitem text="Command Line" target="commandline" expand="false">
-                       <tocitem text="Command Line Arguments" target="clarguments" />
-    <tocitem text="Memory Settings" target="memory" expand="false"/>
-    <tocitem text="Jalview Launch Files" target="jvlfiles" expand="false"/>
-    </tocitem>
+                       <tocitem text="Command Line: introduction and reference" target="clarguments" />
+                       <tocitem text="Command Line: basic usage" target="clarguments-basic" />
+                       <tocitem text="Command Line: advanced usage" target="clarguments-advanced" />
+                       <tocitem text="Command Line: argument files" target="clarguments-argfiles" />
+                       <tocitem text="Command Line: reference" target="clarguments-reference" />
+                       <tocitem text="Command Line: old command line arguments" target="clarguments-old" />
+               </tocitem>
+               <tocitem text="Memory Settings" target="memory" expand="false"/>
+               <tocitem text="Jalview Launch Files" target="jvlfiles" expand="false"/>
                <tocitem text="Privacy" target="privacy" />
-       </tocitem>
+    </tocitem>
        <tocitem text="Useful information" expand="true">
                <tocitem text="Amino Acid Table" target="aminoAcids" />
                <tocitem text="Amino Acid Properties" target="aaProperties" />
index 9ba0578..6b77d91 100755 (executable)
@@ -94,7 +94,8 @@ td {
                                <td>
                                        <table border="1">
                                                <tr>
-                                                       <td nowrap></td>
+                                                       <td nowrap>Name</td>
+                                                       <td nowrap>CLI name</td>
                                                        <td>A</td>
                                                        <td>R</td>
                                                        <td>N</td>
@@ -121,6 +122,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td height="24">Clustal</td>
+                                                       <td>clustal</td>
                                                        <td bgcolor="#80a0f0"></td>
                                                        <td bgcolor="#f01505"></td>
                                                        <td bgcolor="#00ff00"></td>
@@ -147,6 +149,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td height="24">Zappo</td>
+                                                       <td>zappo</td>
                                                        <td bgcolor="#ffafaf"></td>
                                                        <td bgcolor="#6464ff"></td>
                                                        <td bgcolor="#00ff00"></td>
@@ -173,6 +176,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>Taylor</td>
+                                                       <td>taylor</td>
                                                        <td bgcolor="#ccff00"></td>
                                                        <td bgcolor="#0000ff"></td>
                                                        <td bgcolor="#cc00ff"></td>
@@ -199,7 +203,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>gecos Flower</td>
-
+                                                       <td>gecos-flower</td>
                                                        <td bgcolor="#b18a51"></td>
                                                        <td bgcolor="#83bff1"></td>
                                                        <td bgcolor="#0bcec6"></td>
@@ -226,6 +230,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>gecos Blossom</td>
+                                                       <td>gecos-blossom</td>
                                                        <td bgcolor="#8bc4b4"></td>
                                                        <td bgcolor="#fc9502"></td>
                                                        <td bgcolor="#b5c206"></td>
@@ -252,6 +257,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>gecos Sunset</td>
+                                                       <td>gecos-sunset</td>
                                                        <td bgcolor="#fea0fd"></td>
                                                        <td bgcolor="#85746a"></td>
                                                        <td bgcolor="#abc8f5"></td>
@@ -278,6 +284,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>gecos Ocean</td>
+                                                       <td>gecos-ocean</td>
                                                        <td bgcolor="#c6ca9b"></td>
                                                        <td bgcolor="#0ca0a8"></td>
                                                        <td bgcolor="#0adfc3"></td>
@@ -304,6 +311,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>Hydrophobicity</td>
+                                                       <td>hydrophobicity</td>
                                                        <td bgcolor="#ad0052"></td>
                                                        <td bgcolor="#0000ff"></td>
                                                        <td bgcolor="#0c00f3"></td>
@@ -330,6 +338,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>Helix Propensity</td>
+                                                       <td>helix-propensity</td>
                                                        <td bgcolor="#e718e7"></td>
                                                        <td bgcolor="#6f906f"></td>
                                                        <td bgcolor="#1be41b"></td>
@@ -356,6 +365,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td nowrap>Strand Propensity</td>
+                                                       <td>strand-propensity</td>
                                                        <td bgcolor="#5858a7"></td>
                                                        <td bgcolor="#6b6b94"></td>
                                                        <td bgcolor="#64649b"></td>
@@ -382,6 +392,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>Turn Propensity</td>
+                                                       <td>turn-propensity</td>
                                                        <td bgcolor="#2cd3d3"></td>
                                                        <td bgcolor="#708f8f"></td>
                                                        <td bgcolor="#ff0000"></td>
@@ -408,6 +419,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td>Buried Index</td>
+                                                       <td>buried-index</td>
                                                        <td bgcolor="#00a35c"></td>
                                                        <td bgcolor="#00fc03"></td>
                                                        <td bgcolor="#00eb14"></td>
@@ -445,7 +457,8 @@ td {
                                <td>
                                        <table border="1">
                                                <tr>
-                                                       <td nowrap></td>
+                                                       <td nowrap>Name</td>
+                                                       <td nowrap>CLI name</td>
                                                        <td>A</td>
                                                        <!--Adenine-->
                                                        <td>C</td>
@@ -485,6 +498,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td height="24">Nucleotide</td>
+                                                       <td>nucleotide</td>
                                                        <td bgcolor="#64F73F"></td>
                                                        <td bgcolor="#FFB340"></td>
                                                        <td bgcolor="#EB413C"></td>
@@ -506,6 +520,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td height="24">Nucleotide Ambiguity</td>
+                                                       <td>nucleotide-ambiguity</td>
                                                        <td bgcolor="#f0fff0"></td>
                                                        <td bgcolor="#f0fff0"></td>
                                                        <td bgcolor="#f0fff0"></td>
@@ -527,6 +542,7 @@ td {
                                                </tr>
                                                <tr>
                                                        <td height="24">Purine/Pyrimidine</td>
+                                                       <td>purine-pyrimidine</td>
                                                        <td bgcolor="#FF83FA"></td>
                                                        <td bgcolor="#40E0D0"></td>
                                                        <td bgcolor="#FF83FA"></td>
index 3517929..71f3046 100755 (executable)
@@ -40,7 +40,7 @@
     annotations files are imported into Jalview in the following ways:<br />
   <ul>
     <li>from the command line<strong><pre>
- -annotations &lt;<em>Annotations filename</em>&gt;</pre></strong></li>
+ --annotations &lt;<em>Annotations filename</em>&gt;</pre></strong></li>
     <li>Dragging an annotations file onto an alignment window</li>
     <li>Via the &quot;Load Features / Annotations&quot; entry in
       the <strong>File</strong> menu of an alignment window.
index f3b6816..fb8d624 100644 (file)
@@ -50,7 +50,7 @@
     templates for HTML export from our public GitHub Repository.
     Normally, this should happen without you needing to do anything, but
     if you do encounter problems, then please get in contact via the
-    jalview-discuss mailing list, or file a bug report.</p>
+    Jalview Discussion Forum, or file a bug report.</p>
   <p>Templates are downloaded to a directory called
     '.biojs_templates' in your user's home storage space (e.g.
     ~/.biojs_templates).</p>
diff --git a/help/help/html/features/clarguments-advanced.html b/help/help/html/features/clarguments-advanced.html
new file mode 100644 (file)
index 0000000..a235727
--- /dev/null
@@ -0,0 +1,182 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+<title>Command Line: advanced usage</title>
+<body>
+
+  <h1>Command Line: advanced usage</h1>
+
+  <p>
+  <a href="clarguments.html">Command Line: introduction</a>
+  <br/>
+  <a href="clarguments-basic.html">Command Line: basic usage</a>
+  <br/>
+  Command Line: advanced usage
+  <br/>
+  <a href="clarguments-argfiles.html">Command Line: argument files</a>
+  <br/>
+  <a href="clarguments-reference.html">Command Line: reference</a>
+  </p>
+
+  <hr/>
+
+  <ul>
+  <li><a href="#alignmentlinkedids">Alignment linked IDs</a></li>
+  <li><a href="#moresubstitutions">More substitutions</a></li>
+  <li><a href="#equalsseparatorandfileglobs">Equals separator and file globs</a></li>
+  <li><a href="#subvaluemodifiers">Sub-value modifiers</a></li>
+  </ul>
+
+
+  <h2><a name="alignmentlinkedids"></a>Alignment linked IDs</h2>
+
+  <p>
+  Jalview's alignment related arguments are linked together using a <em>linked ID</em>.  In all of the basic usage examples this linked ID is assigned using a default formula of <code>JALVIEW:<em>n</em></code> where <em>n</em> starts at 0 and increments every time there is an <code>--open</code>ed file (or a first use of <code>--append</code>) or the <code>--new</code> argument is used.
+  </p>
+
+  <p>
+  When another alignment related argument is used (without a specified linked ID), it is assigned this default linked ID.  When the <code>--all</code> argument is used, following alignment related arguments are applied to all of the linked IDs (made so far).
+  </p>
+
+  <p>
+  You can assign your own linked IDs to alignments that are opened from the command-line.  To do this put the linked ID in square brackets ('[', ']') <em>immediately following the argument</em> (i.e. before any space or equals sign) like this:
+  <pre>
+  jalview --open[myId1] file1.fa --open[myId2] file2.fa --open[myId3] file3.fa --colour[myId1] gecos-flower --colour[myId2] gecos-blossom --colour[myId3] zappo --image "*.png" --headless
+  </pre>
+
+  <p>
+  As you can see, if you specify your own linked IDs, the arguments for one alignment do not need to be adjacent as they are when using the default assigned linked ID.
+  </p>
+
+  <p>
+  A specified linked ID will also take precedence over a wildcard or <code>--all</code> set linked ID. e.g.
+  <pre>
+  jalview --open[myID] examples/uniref50.fa --all --colour taylor --colour[myID] gecos-blossom
+  </pre>
+  will open the alignment using the <code>gecos-blossom</code> colour scheme (thank goodness).
+  </p>
+
+
+  <h2><a name="moresubstitutions"></a>More substitutions (<code>{n}</code>, <code>{++n}</code>, <code>[*]</code>)</h2>
+
+  <p>
+  In the <a href="clarguments-basic.html#substitutions">basic usage document</a> we have a list of special strings that get replaced in output filename values with parts of input filename values.
+  </p>
+
+  <p>
+  There is also an incrementor integer value <code>{n}</code> that can be put into both linked IDs and filenames and works across different linked IDs.  Whenever you use <code>{n}</code> in a linked ID or filename value it is replaced with the current value of <em>n</em>.  The initial value is 0, and it can be incremented by using the argument <code>--npp</code> or <code>--n++</code>, or using a another special substitution <code>{++n}</code> in either a linked ID or filename value which increments the value and is replaced with the new incremented value of <em>n</em>.
+  </p>
+
+  <p>
+  In the same way that the <code>--all</code> argument enables (some) following arguments to apply to all opened alignments so far, the special linked ID <code>*</code> will also apply an individual argument to all opened linked IDs (in fact when you use the <code>--all</code> argument it simply changes the default linked ID to <code>*</code>).
+  <pre>
+  jalview --open[myId1] fileA.fa --open[myId2] fileB.fa --open[myId3] fileC.fa --colour[*] taylor --all --image tmp/image-{++n}.png --headless
+  </pre>
+  The above will produce an image <code>image-0.png</code> for the alignment in <code>fileA.fa</code>,  an image <code>image-1.png</code> for the alignment in <code>fileB.fa</code>, etc.
+  If you suddenly decide to colour the last alignment differently you could add to the command:
+  <pre>
+  jalview --open[myId1] fileA.fa --open[myId2] fileB.fa --open[myId3] fileC.fa --colour[*] taylor --all --image tmp/image-{++n}.png --headless --colour[myId3] gecos-blossom
+  </pre>
+  because all of the command line arguments are read and sorted into their linked IDs before starting to be processed, and the <code>[myId3]</code> specified linked ID takes precedence over the <code>[*]</code> wildcard linked ID.
+  </p>
+  </p>
+
+
+  <h2><a name="equalsseparatorandfileglobs"></a>Equals separator and Java file globs</h2>
+
+  <p>
+  When a Command-line argument requires one (or more) values, you can use the usual space separation, which allows the shell to expand any file "globs" (that is, filenames with wildcard characters allowing it to represent multiple files).  The shell "expands" this file glob and to Jalview it appears like a list of filenames supplied to the argument.
+  </p>
+
+  <p>
+  There is a limitation to shell expansion of file globs, as the length of a single command, or number of files the shell is willing to expand a file glob to, is limited (to different amounts depending on your shell and its configuration).
+  </p>
+
+  <p>
+  Jalview will also recognise values supplied to arguments (that expect one or more value) that are separated by an equals sign ("=").  There should be no spaces around the equals sign, e.g.
+  <pre>
+  jalview --open=examples/uniref50*.fa --colour=clustal --all --image=*.png --scale=2.5 --headless
+  </pre>
+  </p>
+
+  <p>
+  One benefit of this is seen above in the <code>--image</code> argument, the special "alloutput" wildcard filename <code>*.png</code> will not be expanded by the shell, so does not need to be escaped or surrounded with quotation marks.
+  </p>
+
+  <p>
+  A bigger benefit is that the <em>input</em> filename is not expanded by the shell but can instead be expanded by Jalview.  There is no limit to the number of files that this kind of file glob can match since it is expanded by Jalview, not the shell.
+  </p>
+
+  <p>
+  Jalview uses the Java PathMatcher "glob" scheme to match filenames, which is quite similar, though in some ways more powerful, to most shell glob rules.  The usual '<code>*</code>' and '<code>?</code>' characters act the same, but other combinations can be used too.  For the full rules see <a href="https://devdocs.io/openjdk~11/java.base/java/nio/file/filesystem#getPathMatcher(java.lang.String)">java.nio.file.PathMatcher.getPathMatcher</a> javadocs at https://devdocs.io/openjdk~11/java.base/java/nio/file/filesystem#getPathMatcher(java.lang.String).
+  </p>
+
+  <p>
+  One such PathMatcher addition to shell file globs is the use of <code>**</code> to match any number of directories and sub-directories (matching across file separator).  So to convert every Fasta file under the current working directory to BLC format you can do:
+  <pre>
+  jalview --open=./**/*.fa --output=*.blc --close --headless
+  </pre>
+  or to find every Stockholm and Pfam file under </code>/tmp</code> and convert to Fasta and save in your own folder, do
+  <pre>
+  jalview --open=/tmp/**/*.{stk,pfam} --all --output=~/rescued/{basenamedir}.fa --close --headless
+  </pre>
+  </p>
+
+  <h2><a name="subvaluemodifiers"></a>Sub-value modifiers</h2>
+
+  <p>
+  Sub-value modifiers are given in square brackets ('[', ']') <em>immediately before the value</em> (i.e. after any space or equals sign, and with no space between it and the value) like this:
+  <pre>
+  jalview --open=examples/uniref50.fa --image=[scale=1.414]picture.png
+  </pre>
+  </p>
+
+  <p>
+  Some arguments (such as <code>--scale=<em>n</em></code>) are used to modify the behaviour of other "primary" arguments (such as <code>--image=filename</code>).  These arguments can alternatively be specifed as <em>sub-value modifiers</em> of the values given to the primary argument.  If specified as a sub-value modifier, this modifier takes precedence over any following linked argument if given. e.g
+  <pre>
+  jalview --open=[colour=zappo]examples/*.fa
+  </pre>
+  Notice also that if a sub-value modifier is used for a value that is expanded by the application (i.e. using an equals sign ('=') to separate argument and value) then that modifier is applied to all of the values.
+  </p>
+
+  <p>
+  For shell expanded globs this is more problematic since the presence of a sub-value modifier will almost certainly prevent the shell from recognising the file glob, so
+  <pre>
+  jalview --open [colour=zappo]examples/*.fa
+  </pre>
+  will <em>NOT</em> work the same as above.  If you need to use sub-value modifiers on a file glob you should use an equals sign ('=') to separate it from the argument.
+  </p>
+
+  <p>
+  You can specify multiple sub-value modifiers separating them with a comma (',').  If you wish to specify a "boolean" argument, such as <code>--wrap</code> or <code>--nowrap</code> then simply use the argument name without a value, like this:
+  <pre>
+  jalview --open=[colour=gecos-flower,wrap,noannotations,features=examples/plantfdx.features]examples/plantfdx.fa
+  </pre>
+  </p>
+
+
+  <hr/>
+  Continue to <a href="clarguments-argfiles.html">Command Line: argument files</a>.
+  <br/>
+  <a href="clarguments-reference.html">Command Line: reference</a>
+
+</body>
+</html>
diff --git a/help/help/html/features/clarguments-argfiles.html b/help/help/html/features/clarguments-argfiles.html
new file mode 100644 (file)
index 0000000..5c71d16
--- /dev/null
@@ -0,0 +1,168 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+<title>Command Line: argument files</title>
+<body>
+
+  <h1>Command Line: argument files</h1>
+
+  <p>
+  <a href="clarguments.html">Command Line: introduction</a>
+  <br/>
+  <a href="clarguments-basic.html">Command Line: basic usage</a>
+  <br/>
+  <a href="clarguments-advanced.html">Command Line: advanced usage</a>
+  <br/>
+  <a href="clarguments-argfiles.html">Command Line: argument files</a>
+  <br/>
+  <a href="clarguments-reference.html">Command Line: reference</a>
+  </p>
+
+  <hr/>
+
+  <ul>
+  <li><a href="#argumentfiles">Argument files</a></li>
+  <li><a href="#onlyargumentfiles">Only argument files</a></li>
+  <li><a href="#evenmoresubstitutions">Even more substitutions</a></li>
+  </ul>
+
+  <h2><a name="argumentfiles"></a>Argument files</h2>
+
+  <p>
+  If you want to save a set of arguments to reuse, you can save them in a text file, say <code>argfile.txt</code>, and read them into Jalview with
+  <pre>
+  jalview --argfile=argfile.txt
+  </pre>
+  </p>
+
+  <p>
+  The argument file has one argument and value per line, still using the double-dash ('--') before the argument name, and separating the argument and value with an equals sign ('=').
+  <br/>
+  Because the argument file is read by the application and not read by the shell, you do not need to escape any values -- all spaces will be read as part of the value until the end of the line.
+  <br/>
+  You can add comments to a line by starting the line with an hash (octothorpe, pound-sign '#').
+  <br/>
+  e.g.
+  <table border="1">
+  <tr>
+  <td>
+  File <code>argfile.txt</code>
+  </td>
+  </tr>
+  <tr>
+  <td>
+  <pre>
+--nonews
+--nosplash
+--open=[nowrap,colour=gecos-flower,showannotations]examples/plantfdx.fa
+--features=examples/plantfdx.features
+--annotations=examples/plantfdx.annotations
+--image=images/alignment.png
+--scale=2.5
+#--scale=10
+# let's see what's happening
+#--headless</pre>
+  </td>
+  </tr>
+  </table>
+  </p>
+
+  <p>
+  Because <code>--argfiles</code> takes a filename argument, and multiple <code>--argfiles</code> can be read on the command line, you can also use file globs to specify multiple <code>--argfile</code> values.  If you produce an argument file for each set of alignment files that you wish to associate then you can act on all of them with, e.g.
+  <pre>
+  jalview --argfile=*/argfile.txt --headless
+  </pre>
+  </p>
+
+  <p>
+  You can even read argument files from within argument files, e.g.
+  <pre>
+  jalview --argfile=argfile*.txt --headless
+  </pre>
+  <table border="1">
+  <tr><td>File <code>argfile1.txt</code></td></tr>
+  <tr><td><pre>
+--open=file1.fa
+--argfile=myfavouriteformattingargfile.txt
+--argfile=mysecondfavouriteimageargfile.txt</pre></td></tr>
+  <tr><td>File <code>myfavouriteformattingargfile.txt</code></td></tr>
+  <tr><td><pre>
+--wrap
+--showannotations
+--annotations={dirname}/{basename}.annots</pre></td></tr>
+  <tr><td>File <code>mysecondfavouriteimageargfile.txt</code></td></tr>
+  <tr><td><pre>
+--image=images/{basename}.png
+--width=1920
+--height=1080</pre></td></tr>
+  </table>
+  </p>
+
+  <p>
+  If an argument file that has already been read is found in a firther argument file, then Jalview will exit with a warning.  This is to avoid loops of argument files.
+  </p>
+
+
+  <h2><a name="onlyargumentfiles"></a>Only argument files</h2>
+
+  <p>
+  When you use an <code>--argfile</code> argument, all other non-initialising arguments on the command line <em>will be ignored</em>.  Only the initialising arguments and any and all <code>--argfiles</code> arguments on the command line will be used.  You can also set initialising arguments in argument files.
+  </p>
+
+
+  <h2><a name="evenmoresubstitutions"></a>Even more substitutions</h2>
+
+  <p>
+  When adding values that can use substitutions within argument files, there are two additional substitutions that can be made:
+  <br/>
+  <code>{argfilebasename}</code> - replaced with the base of the filename of the argument file (i.e. without directory path or file extension).
+  <br/>
+  <code>{argfiledirname}</code> - replaced with the path to the filename of the argument file.
+  </p>
+
+  <p>
+  Another substitution you can make in argument files is the <code>{n}</code> substitution.  Combined with an <code>-npp</code> increment at the start (or end) of the argument file gives the potential to reuse an argument files in the same command but referring to different files, e.g.
+
+  <table border="1">
+  <tr><td>File <code>alignment.argfile</code></td></tr>
+  <tr><td><pre>
+--open={argfilebasename}-{n}.fa
+--wrap
+--output={basename}.stk
+--close
+--npp</pre></td></tr>
+  </table>
+  <pre>
+  jalview --argfile alignment.argfile --argfile alignment.argfile --headless
+  </pre>
+  would be processed the same as
+  <pre>
+  jalview --open=alignment-0.fa --wrap --output=alignment-0.stk --close --open=alignment-1.fa --wrap --output=alignment-1.stk --close --headless
+  </pre>
+  </p>
+
+
+  <hr/>
+  <a href="clarguments-reference.html">Command Line: reference</a>
+
+
+</body>
+</html>
diff --git a/help/help/html/features/clarguments-basic.html b/help/help/html/features/clarguments-basic.html
new file mode 100644 (file)
index 0000000..7eb2294
--- /dev/null
@@ -0,0 +1,680 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+<title>Command Line: basic usage</title>
+<body>
+
+  <h1>Command Line: basic usage</h1>
+
+  <p>
+  <a href="clarguments.html">Command Line: introduction</a>
+  <br/>
+  Command Line: basic usage
+  <br/>
+  <a href="clarguments-advanced.html">Command Line: advanced usage</a>
+  <br/>
+  <a href="clarguments-argfiles.html">Command Line: argument files</a>
+  <br/>
+  <a href="clarguments-reference.html">Command Line: reference</a>
+  </p>
+
+  <hr/>
+
+  <ul>
+  <li><a href="#openingalignments">Opening alignments</a></li>
+  <li><a href="#alignmentoptions">Alignment options</a></li>
+  <li><a href="#adding3dstructures">Adding 3D structures</a></li>
+  <li><a href="#outputtingalignmentfiles">Outputting/converting alignment files and images</a></li>
+  <li><a href="#filenamesubstitutionsandbatchprocessing">Filename substitutions and batch processing</a></li>
+  <li><a href="#alloutputwildcard">The all output wildcard</a></li>
+  </ul>
+
+  <h2><a name="openingalignments"></a>Opening alignments (<code>--open</code>, <code>--append</code>, <code>--new</code>)</h2>
+
+  <p>
+  To simply open one or more alignment files in different windows just put the filenames as the first arguments:
+  <pre>
+  jalview filename1 filename2 ...
+  </pre>
+  </p>
+
+  <p>
+  You can use shell-expanded wildcards:
+  <pre>
+  jalview this/filename* that/filename* other/filename*
+  </pre>
+  and URLs:
+  <pre>
+  jalview https://rest.uniprot.org/uniprotkb/P00221.fasta
+  </pre>
+  </p>
+
+  <p>
+  (Using initial filenames is the same as using the <code>--open</code> argument, and further arguments can be used
+  after the initial filenames.)
+  </p>
+
+  <h3><a name="open"></a><code>--open</code></h3>
+
+  <p>
+  Use the <code>--open</code> argument to open alignment files each in their own window.
+  </p>
+
+  <p>
+  The following are equivalent:
+  <pre>
+  jalview --open filename1 filename2 ...
+
+  jalview --open filename*
+
+  jalview --open filename1 --open filename2 --open ...
+
+  jalview filename1 filename2 ...
+  </pre>
+  </p>
+
+  <p>
+  Similarly you can open URLs:
+  <pre>
+  jalview --open https://rest.uniprot.org/uniprotkb/P00221.fasta
+  </pre>
+  </p>
+
+  <h3><a name="append"></a><code>--append</code></h3>
+
+  <p>
+  To append several alignment files together use:
+  <pre>
+  jalview --open filename1.fa --append filename2.fa filename3.fa
+  </pre>
+  or, if you haven't previously used <code>--open</code> then you can use --append to open one new window and keep appending each set of alignments:
+  <pre>
+  jalview --append these/filename*.fa --append more/filename*.fa
+
+  jalview --append https://rest.uniprot.org/uniprotkb/P00221.fasta https://www.uniprot.org/uniprotkb/A0A0K9QVB3/entry
+  </pre>
+  </p>
+
+  <p>
+  <strong>Note</strong> that whilst you can include a Jalview Project File (<code>.jvp</code>) as an <code>--append</code> value, the items in the file will always open in their original windows and not append to another.
+  </p>
+
+  <h3><a name="new"></a><code>--new</code></h3>
+
+  <p>
+  To append different sets of alignment files in different windows, use <code>--new</code> to move on to a new alignment window:
+  <pre>
+  jalview --append these/filename*.fa --new --append other/filename*.fa
+  </pre>
+  </p>
+
+  <p>
+  <code>--open</code> is like using <code>--new --append</code> applied to every filename/URL given to <code>--open</code>
+  </p>
+
+
+  <h2><a name="alignmentoptions"></a>Alignment options (<code>--colour</code>, <code>--wrap</code>, <code>--showannotations</code>, <code>--title</code>)</h2>
+
+  <h3><a name="colour"></a><code>--colour</code></h3>
+
+  <p>
+  You can specify a residue/base colouring for the alignment using the <code>--colour</code> option (note spelling -- Jalview is made in Scotland!):
+  <pre>
+  jalview --open examples/uniref50.fa --colour gecos-flower
+  </pre>
+  There are several colour schemes that you can use.  See the <a href="../colourSchemes/index.html">page on Colour Schemes</a> for details.
+  The names to use on the command line for colour schemes are:
+  </p>
+  <p>
+  <code>clustal</code>,
+  <br/>
+  <code>blosum62</code>,
+  <br/>
+  <code>pc-identity</code>,
+  <br/>
+  <code>zappo</code>,
+  <br/>
+  <code>taylor</code>,
+  <br/>
+  <code>gecos-flower</code>,
+  <br/>
+  <code>gecos-blossom</code>,
+  <br/>
+  <code>gecos-sunset</code>,
+  <br/>
+  <code>gecos-ocean</code>,
+  <br/>
+  <code>hydrophobic</code>,
+  <br/>
+  <code>helix-propensity</code>,
+  <br/>
+  <code>strand-propensity</code>,
+  <br/>
+  <code>turn-propensity</code>,
+  <br/>
+  <code>buried-index</code>,
+  <br/>
+  <code>nucleotide</code>,
+  <br/>
+  <code>nucleotide-ambiguity</code>,
+  <br/>
+  <code>purine-pyrimidine</code>,
+  <br/>
+  <code>rna-helices</code>,
+  <br/>
+  <code>t-coffee-scores</code>,
+  <br/>
+  <code>sequence-id</code>
+  </p>
+
+  <h3><a name="wrap"></a><code>--wrap</code></h3>
+  <p>
+  An alignment should open with your usual preferences stored in the <code>.jalview_properties</code> file.  To open an alignment with the sequences (definitely) wrapped, following your <code>--open</code> (or first <code>--append</code>) argument use the argument <code>--wrap</code>:
+  <pre>
+  jalview --open examples/uniref50.fa --wrap
+  </pre>
+  To ensure an alignment is not wrapped use <code>--nowrap</code>:
+  <pre>
+  jalview --open examples/uniref50.fa --nowrap
+  </pre>
+  </p>
+
+  <h3><a name="showannotations"></a><code>--showannotations</code> / <code>--noshowannotations</code></h3>
+
+  <p>
+  You can specify whether the currently opened alignment window should show alignment annotations (e.g. Conservation, Quality, Consensus...) or not with either <code>--showannotations</code> or <code>--noshowannotations</code>.  If you don't specify then your saved preference will be used.
+  <pre>
+  jalview --open examples/uniref50.fa --noshowannotations
+  </pre>
+  </p>
+
+  <h3><a name="title"></a><code>--title</code></h3>
+
+  <p>
+  If you would like to give the alignment window a specific title you can do so with the <code>--title</code> option:
+  <pre>
+  jalview --open examples/uniref50.fa --title "My example alignment"
+  </pre>
+  </p>
+
+
+
+
+  <h2><a name="adding3dstructures"></a>Adding 3D structures (<code>--structure</code>, <code>--seqid</code>, <code>--structureviewer</code>, <code>--paematrix</code>, <code>--tempfac</code>, <code>--showssannotations</code>)</h2>
+
+  <p>
+  </p>
+
+  <h3><a name="structure"></a><code>--structure</code></h3>
+
+  <p>
+  You can add a 3D structure file to a sequence in the current alignment window with the <code>--structure</code> option:
+  <pre>
+  jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb
+  </pre>
+  By default this attaches to the first sequence in the alignment but most likely you will want to attach it to a specific sequence.
+  </p>
+
+  <h3><a name="seqid"></a><code>--seqid</code></h3>
+
+  <p>
+  The easiest way to specify a sequence ID for your structure is to follow the <code>--structure</code> argument with a <code>--seqid</code> argument with a value of a sequence ID in the alignment.  This does of course require some knowledge of the sequences in the alignment files
+  that have been opened.
+  <br/>
+  Alternatively you can specify a <em>sub-value</em> with the <code>--structure</code> argument value.  You do this by preceding the value with square brackets and <code>seqid=SequenceId</code>,
+  like this:
+  <pre>
+  jalview --open examples/uniref50.fa --structure [seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.pdb
+  </pre>
+  which is equivalent to
+  <pre>
+  jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb --seqid FER1_SPIOL
+  </pre>
+  </p>
+
+  <p>
+  The sub-value <code>seqid=FER1_SPIOL</code> takes precedence over the following argument <code>--seqid FER1_SPIOL</code> if you accidentally specify both (in which case the argument will probably be completely unused).
+  </p>
+
+  <p>
+  If you don't know the sequence IDs but do know the position of the sequence in the alignment, you can also specify an <em>INDEX</em>
+  in the sub-values to indicate which sequence in the alignment to attach the sequence to (although this is less precise).  This is a zero-indexed value, so to specify the eighth sequence in the alignment use:
+  <pre>
+  jalview --open examples/uniref50.fa --structure [7]examples/AlphaFold/AF-P00221-F1-model_v4.pdb
+  </pre>
+
+  <p>
+  Remember that you might need to escape any spaces in the sequence ID or enclose the ID in quotation marks.
+  </p>
+
+  <h3><a name="structureviewer"></a><code>--structureviewer</code></h3>
+
+  <p>
+  You can specify which structure viewer (or none) to use to open the structure using either the <code>--structureviewer</code> argument or the <code>structureviewer</code> sub-value.  Multiple sub-values can be specified together, separated by a comma ','.  Possible values for the <code>structureviewer</code> are:
+  <br/>
+  <code>none</code>,
+  <br/>
+  <code>jmol</code>,
+  <br/>
+  <code>chimera</code>,
+  <br/>
+  <code>chimerax</code>,
+  <br/>
+  <code>pymol</code>.
+  </p>
+  <p>
+  <code>none</code> and <code>jmol</code> will always be available, but to use the others you must have the appropriate software already set up on your computer and in Jalview.  See the page <a href="../features/viewingpdbs.html">Discovering and Viewing PDB and 3D-Beacons structures</a> for more details.
+  <pre>
+  jalview --open examples/uniref50.fa --structure [seqid=FER1_SPIOL,structureviewer=none]examples/AlphaFold/AF-P00221-F1-model_v4.pdb
+  </pre>
+  or, if you prefer
+  <pre>
+  jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb --seqid FER1_SPIOL --structureviewer none
+  </pre>
+  </p>
+
+  <h3><a name="paematrix"></a><code>--paematrix</code></h3>
+
+  <p>
+  If you are opening a structure file that has a PAE matrix (provided as a JSON file), such as from an AlphaFold model or an nf-core pipeline, you can add the PAE matrix as an annotation by following the <code>--structure</code> argument with a <code>--paematrix</code> argument with the filename.  You can also specify a <code>paematrix=filename</code> sub-value.
+  <pre>
+  jalview --open examples/uniref50.fa --structure [seqid=FER1+SPIOL,structureviewer=pymol]examples/AlphaFold/AF-P00221-F1-model_v4.pdb --paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json
+  </pre>
+  </p>
+
+  <h3><a name="tempfac"></a><code>--tempfac</code></h3>
+
+  <p>
+  Structure files may have a temperature factor associated with the structure component positions.  If the temperature factor is a pLDDT confidence score, such as with an AlphaFold model, you can specify this by using a following argument of <code>--tempfac</code> with a value of <code>plddt</code>.  This will enable standard pLDDT colouring of the temperature factor annotation.  Valid values are:
+  <code>default</code>,
+  <code>plddt</code>.
+  More types of temperature factor may be added in future releases of Jalview.
+  <br/>
+  The value can also be specified as a sub-value:
+  <pre>
+  jalview --open examples/uniref50.fa --structure [seqid=FER1+SPIOL,structureviewer=jmol,tempfac=plddt]examples/AlphaFold/AF-P00221-F1-model_v4.pdb
+  </pre>
+  which is equivalent to
+  <pre>
+  jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb --tempfac plddt --seqid FER1+SPIOL
+   --structureviewer jmol
+  </pre>
+
+  </p>
+
+  <!-- notempfac not yet working. undocumented until then -->
+
+  <h3><a name="showssannotations"></a><code>--showssannotations</code> / <code>--noshowssannotations</code></h3>
+
+  <p>
+  You can specify whether the currently opened alignment window should show secondary structure annotations or not with either <code>--showssannotations</code> or <code>--noshowssannotations</code>.  If you don't specify then your saved preference will be used.
+  <pre>
+  jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb --noshowssannotations
+  </pre>
+  or you can use a sub-value modifier:
+  <pre>
+  jalview --open examples/uniref50.fa --structure [noshowssannotations]examples/AlphaFold/AF-P00221-F1-model_v4.pdb
+  </pre>
+  </p>
+
+  <h2><a name="outputtingalignmentfiles"></a>Outputting/converting alignment files and images (<code>--output</code>, <code>--format</code>, <code>--image</code>, <code>--type</code>, <code>--textrenderer</code>, <code>--scale</code>, <code>--backups</code>, <code>--overwrite</code>)</h2>
+
+  <p>
+  You can save an alignment as an alignment file, or exported as an image, in different formats.  Jalview's alignment output formats are:
+  fasta,
+  pfam,
+  stockholm,
+  pir,
+  blc,
+  amsa,
+  json,
+  pileup,
+  msf,
+  clustal,
+  phylip,
+  jalview.
+  </p>
+  <p>
+  Alignments can be exported as an image in formats EPS, SVG, HTML, BioJSON (vector formats) or PNG (bitmap format).
+  </p>
+  <p>
+  In vector formats you can specify whether text should be rendered as text (which may have font changes, but will produce a smaller and more usable file) or as lineart (which will retain exact appearance of text, but will be less easy to edit or use to copy text).
+  </p>
+  <p>
+  In bitmap formats (currently only PNG, but what else would you want?!) you can specify a scaling factor to improve the resolution of the output image.
+  </p>
+
+  <h3><a name="output"></a><code>--output</code></h3>
+
+  <p>
+  To save the open alignment in a new alignment file use <code>--output filename</code>.  The format for the file can be found from the extension of <code>filename</code>, or if you are using a non-standard extension you can use a following <code>--format</code> argument, or specify it as a sub-value modifier.
+  </p>
+  <p>
+  Recognised formats and their recognised extensions are:
+  <br/>
+  <code>fasta</code> (<code>fa, fasta, mfa, fastq</code>),
+  <br/>
+  <code>pfam</code> (<code>pfam</code>),
+  <br/>
+  <code>stockholm</code> (<code>sto, stk</code>),
+  <br/>
+  <code>pir</code> (<code>pir</code>),
+  <br/>
+  <code>blc</code> (<code>blc</code>),
+  <br/>
+  <code>amsa</code> (<code>amsa</code>),
+  <br/>
+  <code>json</code> (<code>json</code>),
+  <br/>
+  <code>pileup</code> (<code>pileup</code>),
+  <br/>
+  <code>msf</code> (<code>msf</code>),
+  <br/>
+  <code>clustal</code> (<code>aln</code>),
+  <br/>
+  <code>phylip</code> (<code>phy</code>),
+  <br/>
+  <code>jalview</code> (<code>jvp, jar</code>).
+  </p>
+  <p>
+  For example, to open a FASTA file, append another FASTA file and then save the concatenation as a Stockholm file, do
+  <pre>
+  jalview --open alignment1.fa --append alignment2.fa --output bothalignments.stk
+  </pre>
+  or
+  <pre>
+  jalview --append alignment*.fa --output bigballofstring.txt --format stockholm
+  </pre>
+  or
+  <pre>
+  jalview --append alignment*.fa --output [format=stockholm]bigballofstring.txt
+  </pre>
+  </p>
+
+  <p>
+  <em>Important!</em> If you use <code>--output</code> or any other argument that outputs a file, then it will be assumed you want to run Jalview in headless mode (as if you had specified <code>--headless</code>).  To use Jalview with <code>--output</code> and not assume headless mode, use the <code>--gui</code> argument (the order doesn't matter).
+  </p>
+
+  <p>
+  If you would like to output an alignment file directly to standard output (often referred to as STDOUT), then use the filename <code>-</code> (a single hyphen).  In this case any messages that would normally appear on STDOUT will be diverted to STDERR to avoid invalidating the output file.
+  </p>
+  <p>
+  For example, to open a Stockholm file and pipe it to another command as a Block file, do
+  <pre>
+  jalview --open alignment1.stk --output - --format blc | another_command
+  </pre>
+  or equivalently
+  <pre>
+  jalview alignment1.stk --output=[format=blc]- | another_command
+  </pre>
+  </p>
+
+  <h3><a name="format"></a><code>--format</code></h3>
+
+  <p>
+  To specify the format of the output file (if using an unrecognised file extension) use the <code>--format</code> argument to specify a value (see above).  A sub-value modifier on the <code>--output</code> value can also be used.
+  </p>
+
+  <h3><a name="image"></a><code>--image</code></h3>
+  To export the open alignment window as an image, use the <code>--image</code> argument, which will give an image of the alignment and annotations as it appears (or would appear if not in <code>--headless</code> mode) in the alignment window if it was large enough for the whole alignment, including colour choice and features.
+  <p>
+  <pre>
+  jalview --open examples/plantfdx.fa --colour gecos-blossom --features examples/plantfdx.features --annotations examples/plantfdx.annotations --image plantfdx.png --headless
+  </pre>
+  </p>
+
+  <p>
+  This by default produces a PNG image of screen or webpage resolution, which you may want to improve upon.  There are two ways of doing this with Jalview: increasing the scale of the PNG image, or using a vector based image format (EPS, SVG, HTML).
+  <p>
+
+  <h3><a name="bitmap"></a>Bitmap image types (<code>png</code>)</h3>
+
+  <p>
+  Bitmap images are composed of an array of pixels.  Bitmap images with a low resolution that are blown up to a larger size appear "blocky", so it is important to get the resolution for your purpose correct.  Older screens only require a modest resolution, whilst newer HiDPI screens look better with a higher resolution.  For print you will want an even higher resolution although in this case you would probably want to use a vector image format.  In general creating a bitmap image that has a large resolution means you can scale the image down if needed, although if you are running a batch process this will take more time and resources.
+  </p>
+  <p>
+  Jalview only produces a PNG bitmap image type.  This is a high-colour lossless format which can also use lossless compression so is suitable for alignment figures.
+  </p>
+  <p>
+  Let's increase the resolution of the PNG image:
+  </p>
+
+  <h3><a name="scale"></a><code>--scale</code></h3>
+
+  <p>
+  We can increase the size of the PNG image by a factor of <em>S</em> by following the <code>--image</code> argument with a <code>--scale <em>S</em></code> argument and value.  The value doesn't have to be an integer and should be given as an integer or floating point formatted number, e.g.
+  <pre>
+  jalview --open examples/uniref50.fa --colour gecos-ocean --image mypic.png --scale 5.5 --headless
+  </pre>
+  which will produce a PNG image 5.5 times larger (and more detailed) than without the <code>--scale</code> argument.
+  </p>
+  <p>
+  However, since you won't necessarily already know the size of an alignment's exported image you can specify either an exact width or height (in pixels) with either one of the
+  <code>--width</code> and <code>--height</code> arguments:
+
+  <h3><a name="width"></a><code>--width</code></h3>
+
+  <p>
+  Specify an exact width of an exported PNG image with <code>--width</code>:
+  <pre>
+  jalview --headless --open https://www.ebi.ac.uk/interpro/api/entry/pfam/PF03760/?annotation=alignment%3Aseed --noshowannotations --colour gecos-sunset --image wallpaper.png --width 3840
+  </pre>
+  </p>
+
+  <h3><a name="height"></a><code>--height</code></h3>
+
+  <p>
+  Alternatively specify an exact height with the <code>--height</code> argument:
+  <pre>
+  jalview --headless --open https://www.ebi.ac.uk/interpro/api/entry/pfam/PF03760/?annotation=alignment%3Aseed --noshowannotations --colour gecos-ocean --image wallpaper.png --height 2160
+  </pre>
+  </p>
+
+  <p>
+  You can specify two or all of <code>--scale</code>, <code>--width</code> and <code>--height</code> as limits to the size of the image (think of one or two bounding boxes) and the one which produces the smallest scale of image is used.  You can also specify each of these as sub-value modifiers to the <code>--image</code> value:
+  <pre>
+  jalview --headless --open https://www.ebi.ac.uk/interpro/api/entry/pfam/PF03760/?annotation=alignment%3Aseed --noshowannotations --colour gecos-flower --image [scale=0.25,width=320,height=240]thumbnail.png
+  </pre>
+  </p>
+
+  <p>
+  Next we look at vector image formats, which maintain detail at all resolutions.
+  </p>
+
+  <h3><a name="vector"></a>Vector image export</h3>
+
+  <p>
+  Jalview can export an alignment in Encapsulated PostScript (<code>eps</code>), Scalable Vector Graphics (<code>svg</code>), HTML (<code>html</code>) or BioJSON -- another HTML format (<code>biojs</code>), by using, e.g.
+  <pre>
+  jalview --open examples/uniref50.fa --colour gecos-flower --image printable.eps
+  </pre>
+  The image format can be specified with the <code>--type</code> argument or as a sub-value modifier on the <code>--image</code> value.  If neither is used the <code>type</code> will be guessed from the image file extension.  The following three examples should produce the same contents:
+  <pre>
+  jalview --open examples/uniref50.fa --colour gecos-flower --image printable.eps
+  jalview --open examples/uniref50.fa --colour gecos-flower --image printable.postscript --type eps
+  jalview --open examples/uniref50.fa --colour gecos-flower --image [type=eps]printable.postscript
+  </pre>
+  </p>
+
+  <h3><a name="textrenderer"></a><code>--textrenderer</code></h3>
+
+  <p>
+  In a vector format any text that appears on the page (including residue/base labels) can be saved in the image file either as <code>text</code> or as <code>lineart</code> using the <code>--textrenderer</code> argument.  This is only available for <code>eps</code>, <code>svg</code> and <code>html</code> formats.
+  </p>
+
+  <p>
+  The difference is potentially in the appearance of the file, and definitely in the filesize!  Saving with <code>text</code> requires the font used to display the text characters in the alignment to be present on the viewing platform to look exactly the same.  If it isn't then another suitable font will probably be used.  The filesize using <code>text</code> is relatively small.
+  </p>
+  <p>
+  When using <code>lineart</code> each individual character that appears in the alignment (including names/titles and resisdues/bases) is stored in the image with its own vector lines.  This means that the appearance of the text is retained exactly independent of installed fonts, but the filesize is increased.  You will also be unable to copy what appears to be text as text.
+  </p>
+
+  <p>
+  The type of <code>--textrenderer</code> can be specified with an argument following <code>--image</code> or as a sub-value modifier:
+  <pre>
+  jalview --open examples/uniref50.fa --colour gecos-flower --image printable.html --type biojs
+  jalview --open examples/uniref50.fa --colour gecos-flower --image [type=eps,textrenderer=lineart]printable.ps
+  </pre>
+  </p>
+
+
+  <h2><a name="filenamesubstitutionsandbatchprocessing"></a>Filename substitutions and batch processing (<code>--substitutions</code>, <code>--close</code>, <code>--all</code>)</h2>
+
+  <p>
+  One of the more powerful aspects of Jalview's command line operations is that stores all of the different opened alignment arguments (before opening them) and can apply some arguments to <em>all</em> of the alignments as they are opened.  This includes display and output arguments.
+  </p>
+
+  <p>
+  When outputting a file you will obviously want to use a different filename for each of the alignments that are opened.  There are several ways you can specify how that filename differs, but the easiest way is to refer to the input filename and change the extension.  In the case of an alignment where multiple files are appended, the filename of the first file to be appended or opened is used.
+  </p>
+
+  <p>
+  To refer to different parts of the opening filename, you can use the strings
+  <ul>
+  <li><code>{dirname}</code> -- is replaced by the directory path to the opened file.</li>
+  <li><code>{basename}</code> -- is replaced by the base of the filename of the opened file. This is without the path or file extension (if there is one).</li>
+  <li><code>{extension}</code> -- is replaced by the extension of the filename of the opened file.</li>
+  </ul>
+  The braces (curly brackets '{', '}') are important!
+  </p>
+
+  <p>
+  These filename substitutions are on by default, but if for whatever reason you wish to disable the substitutions, they can be turned off (or back on again) through the list of arguments with:
+  </p>
+
+  <h3><a name="substitutions"></a><code>--substitutions / --nosubstitutions</code></h3>
+
+  <p>
+  Enable (or disable) filename substitutions in the following argument values and sub-value modifier values.
+  <pre>
+  jalview --open exampes/uniref50.fa --nosubstitutions --output I_Want_A_Weird_Output_Filname_With_{basename}_Curly_Brackets_In_And_A_Sensible_One_Next.stk --substitutions --output tmp/{basename}.stk --headless
+  </pre>
+  </p>
+
+  <p>
+  For opening single files this is less useful, since you could obviously just type the output filename, but for multiple opened alignments you can also use these substituted values and they will be replaced by the relevant part of the filename given for each opened alignment window.  Normally an <code>--output</code> or <code>--image</code> argument will only be applied to the latest opened alignment window, but you can tell Jalview to apply some arguments to all alignments that have been opened (so far) by using the <code>--all</code> argument.
+  </p>
+
+  <h3><a name="all"></a><code>--all / -noall</code></h3>
+
+  <p>
+  When using the <code>--all</code> argument, following arguments will apply to all of the previously opened alignment windows.  You can turn this behaviour off again for following arguments using the <code>--noall</code> argument.  The arguments that can apply to all previously opened alignments are:
+  <br/>
+  <code>--colour</code>
+  <br/>
+  <code>--sortbytree</code>
+  <br/>
+  <code>--showannotations</code>
+  <br/>
+  <code>--wrap</code>
+  <br/>
+  <code>--nostructure</code>
+  <br/>
+  <code>--notempfac</code>
+  <br/>
+  <code>--showssannotations</code>
+  <br/>
+  <code>--image</code>
+  <br/>
+  <code>--type</code>
+  <br/>
+  <code>--textrenderer</code>
+  <br/>
+  <code>--scale</code>
+  <br/>
+  <code>--width</code>
+  <br/>
+  <code>--height</code>
+  <br/>
+  <code>--output</code>
+  <br/>
+  <code>--format</code>
+  <br/>
+  <code>--groovy</code>
+  <br/>
+  <code>--backups</code>
+  <br/>
+  <code>--overwrite</code>
+  <br/>
+  <code>--close</code>
+  </p>
+  <p>
+  In particular, for our example above, we can use <code>-all</code> and <code>--output</code> like this (<code>--close</code> will be explained in a moment):
+  <pre>
+  jalview --open all_my_fasta_files/*.fa --all --output all_my_converted_stockholm_files/{basename}.stk --close --headless
+  </pre>
+  </p>
+
+  <p>
+  Another example would be to create a print quality coloured postscript image for every Fasta file in several directories and place the image next to the alignment:
+  <pre>
+  jalview --open */*.fa --all --colour gecos-flower --image {dirname}/{basename}.eps --textrenderer text --close --headless
+  </pre>
+  or thumbnails for every Fasta file with
+  <pre>
+  jalview --open */*.fa --all --colour gecos-flower --image {dirname}/{basename}.png --width 256 --height 256 --close --headless
+  </pre>
+  </p>
+
+  <h3><a name="close"></a><code>--close</code></h3>
+
+  <p>
+  The <code>--close</code> tag is used to close an alignment window after all output files or image exports are performed.  This reduces memory use, especially if an <code>--open</code> value is set to open many files.  These will be opened, formatted and output sequentially so since they are closed before the next one is opened memory use will not build up over a large number of alignments.
+  <pre>
+  </pre>
+  </p>
+
+
+  <h2><a name="alloutputwildcard"></a>The all output wildcard: <code>--output "*.ext"</code>,  <code>--image "*.ext"</code></h2>
+
+  <p>
+  Purely as an intuitive syntactic sweetener, you can use the <code>--output</code> wildcard <code>*</code> <em>at the beginning of the output filename</em> as shorthand for <code>--all --output {dirname}/{basename}</code> followed by whatever you put after the '<code>*</code>'.  For example, to achieve the same as the thumbnails example above, you could use
+  <pre>
+  jalview --open */*.fa --image "*.png" --colour gecos-flower --width 256 --height 256 --close --headless
+  </pre>
+  Here we move the <code>--colour</code> argument after the <code>--output</code> argument (it will still be applied before the image export or file output) so that it is included after the implied <code>--all</code> argument.  The thumbnails will be placed in the same directory as the alignment file with the same filename except for a different extension of <code>.png</code>.
+  </p>
+
+  <p>
+  For a simple conversion of many fasta files into Stockholm format, simply use
+  <pre>
+  jalview --open all_my_fasta_files/*.fa --output "*.stk" --close --headless
+  </pre>
+  </p>
+
+  <p>
+  <strong>Important!</strong>  Please note that using a bareword <code>*.ext</code> (i.e. without an escape or quotation marks) in a shell command line will potentially be expanded by the shell to a list of all the files in the current directory ending with <code>.ext</code> <em>before</em> this value is passed to Jalview.  This will result in the first of these files being overwritten (multiple times)!  If you shell-escape the <code>*</code> (usually with a backslash '\') or enclose the value in quotation marks (<code>"*.ext"</code> - that's including the quotation marks) then the shell will not expand the wildcard.
+  </p>
+
+  <p>
+  An alternative is to use an equals sign ('=') with no spaces between the argument and the value, <code>--output=*.ext</code>, which Jalview will interpret the same, but the shell will not automatically expand before it is sent to Jalview, e.g.
+  <pre>
+  jalview --open all_my_fasta_files/*.fa --output=*.stk --close --headless
+  </pre>
+  </p>
+
+  <hr/>
+  Continue to <a href="clarguments-advanced.html">Command Line: advanced usage</a>.
+  <br/>
+  <a href="clarguments-reference.html">Command Line: reference</a>
+
+</body>
+</html>
diff --git a/help/help/html/features/clarguments-old.html b/help/help/html/features/clarguments-old.html
new file mode 100644 (file)
index 0000000..8346401
--- /dev/null
@@ -0,0 +1,289 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+<title>Jalview Command Line Arguments (pre 2.11.3.0) - DEPRECATED</title>
+<body>
+  <p>
+    <strong>The Jalview Executable's Command Line Arguments (pre 2.11.3.0) - DEPRECATED</strong>
+  </p>
+
+  <table border="1">
+  <tr><td>
+  <em>
+  This page describes the command line arguments used pre 2.11.3.0 (released mid 2023).
+  <br/>
+  Whilst these arguments will be supported for some versions after 2.11.3.0, they are now deprecated
+  and will be removed at some time in the future.
+  </em>
+  </td></tr>
+  </table>
+
+
+  See
+  <a href="commandline.html">running Jalview from the command line</a>
+  for more information.
+  <br />
+  <br />Jalview processes arguments on the command line sequentially. If
+  you would like to pass a <a href="jvlfiles.html">'JVL' file</a> containing
+  <a href="../memory.html">memory settings</a> or any other launch
+  parameters, then include it at the beginning of the command line to
+  ensure they are processed before any remaining arguments.
+  <br>
+  Typical command line execution follows the following pattern:
+  <pre>
+  jalview -open &lt;Alignment File/URL&gt; [additional import arguments] [export arguments]
+  </pre>
+  
+  <table width="100%" border="1" cellspacing="0" cellpadding="0">
+    <tr>
+      <td width="27%"><div align="center">-nodisplay</div></td>
+      <td width="73%"><div align="left">Run Jalview without
+          User Interface. (automatically disables questionnaire, version
+          and usage stats checks)</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-nowebservicediscovery</div></td>
+      <td><div align="left">Do not query configured servers to
+          discover web services (<em>Since 2.11.2.0</em>)</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-open FILE/URL</div></td>
+      <td><div align="left">Specify the alignment file to
+          open or process by providing additional arguments.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-props FILE/URL</div></td>
+      <td><div align="left">Use the given Jalview properties
+          file instead of users default.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-setprop PROPERTY=value</div></td>
+      <td><div align="left">(JalviewJS ONLY) sets the given
+          property to the given value</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-features FILE/URL</div></td>
+      <td><div align="left">
+          <p>
+            Use the given file to add sequence features to an alignment.
+            See <a href="featuresFormat.html" target="NEW">Features
+              File</a> (Known as Groups file prior to 2.08) description.
+          </p>
+
+        </div></td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-colour COLOURSCHEME</div>
+      </td>
+      <td>Set the colourscheme for the alignment. This can be any
+        of the built-in colourschemes, a name of a predefined
+        colourscheme (defined in the Jalview properties file), or an
+        'inline' colourscheme (see the applet's colour parameter for
+        more information).</td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-annotations FILE/URL</div>
+      </td>
+      <td>Add precalculated annotations to the alignment. See <a
+        href="annotationsFormat.html" target="NEW">Annotation
+          File</a> description.
+      </td>
+    </tr>
+        <tr>
+      <td>
+        <div align="center">-no-annotation</div>
+      </td>
+      <td>Do not display annotation below the alignment. 
+      </td>
+    </tr>
+    
+    <tr>
+      <td>
+        <div align="center">-tree FILE/URL</div>
+      <td>
+        <div align="left">Load the given newick format tree file
+          onto the alignment</div>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-questionnaire URL</div>
+      <td>
+        <div align="left">Queries the given URL for information
+          about any Jalview user questionnaires</div>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-noquestionnaire</div>
+      <td>
+        <div align="left">Turn off questionnaire check</div>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-nonews</div>
+      <td>
+        <div align="left">
+          Disable check for <a href="../webServices/newsreader.html">Jalview
+            news</a> on startup (not recommended other than for classroom /
+          demo usage)
+        </div>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-nousagestats</div>
+      <td>
+        <div align="left">Turn off google analytics usage tracking</div>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-[no]sortbytree</div>
+      <td>
+        <div align="left">Enable or disable automatic sorting of
+          associated view when a new tree is displayed</div>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-groovy FILE/URL</div>
+      <td>
+        <div align="left">Execute groovy script in FILE (where
+          FILE may be 'STDIN' to read from the standard input) after all
+          other arguments have been processed</div>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-jabaws URL</div>
+      <td>
+        <div align="left">Specify the URL of the preferred JABAWS
+          server</div>
+      </td>
+    </tr>
+    <tr>
+      <td>
+        <div align="center">-fasta FILE</div>
+      </td>
+
+      <td>
+        <div align="left">Create alignment file FILE in Fasta
+          format.</div>
+      </td>
+    </tr>
+    <tr>
+      <td><div align="center">-clustal FILE</div></td>
+      <td><div align="left">Create alignment file FILE in
+          Clustal format.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-msf FILE</div></td>
+
+      <td><div align="left">Create alignment file FILE in MSF
+          format.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-pileup FILE</div></td>
+      <td><div align="left">Create alignment file FILE in
+          Pileup format.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-pir FILE</div></td>
+
+      <td><div align="left">Create alignment file FILE in PIR
+          format.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-pfam FILE</div></td>
+      <td><div align="left">Create alignment file FILE in
+          PFAM format.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-blc FILE</div></td>
+      <td><div align="left">Create alignment file FILE in BLC
+          format.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-json FILE</div></td>
+      <td><div align="left">Create alignment file FILE in
+          JSON format.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-jalview FILE</div></td>
+
+      <td><div align="left">Create alignment file FILE in
+          Jalview format.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-png FILE</div></td>
+      <td><div align="left">Create PNG image FILE from
+          alignment.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-imgMap FILE</div></td>
+
+      <td><div align="left">Create HTML file FILE with image
+          map of PNG image.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-eps FILE</div></td>
+      <td><div align="left">Create EPS file FILE from
+          alignment.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-svg FILE</div></td>
+      <td><div align="left">Create Scalable Vector Graphics
+          file FILE from alignment.</div></td>
+    </tr>
+    <tr>
+      <td><div align="center">-biojsMSA FILE</div></td>
+      <td><div align="left">Write an HTML page to display
+          the alignment with the <a href="biojsmsa.html">
+          BioJS MSAviewer MSA</a>
+          </div>
+      </td>
+    </tr>
+    <tr>
+      <td><div align="center">-jvmmempc=PERCENT</div></td>
+      <td><div align="left"><em>Only available with standalone executable jar or jalview.bin.Launcher.</em>
+          Limit maximum heap size (memory) to PERCENT% of total physical memory detected.
+         This defaults to 90 if total physical memory can be detected.
+         See <a href="../memory.html">Memory usage settings for Jalview</a> for more details.
+          </div>
+      </td>
+    </tr>
+    <tr>
+      <td><div align="center">-jvmmemmax=MAXMEMORY</div></td>
+      <td><div align="left"><em>Only available with standalone executable jar or jalview.bin.Launcher.</em>
+          Limit maximum heap size (memory) to MAXMEMORY. MAXMEMORY can be specified in bytes, kilobytes(k), megabytes(m),
+         gigabytes(g) or if you're lucky enough, terabytes(t).
+         This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected.
+         See <a href="../memory.html">Memory usage settings for Jalview</a> for more details.
+          </div>
+      </td>
+    </tr>
+  </table>
+</body>
+</html>
diff --git a/help/help/html/features/clarguments-reference.html b/help/help/html/features/clarguments-reference.html
new file mode 100644 (file)
index 0000000..60951d8
--- /dev/null
@@ -0,0 +1,832 @@
+<html>
+<!--
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+<title>Command Line: reference</title>
+<body>
+
+  <h1>Command Line: reference</h1>
+
+  <p>
+  <a href="clarguments.html">Command Line: introduction</a>
+  <br/>
+  <a href="clarguments-basic.html">Command Line: basic usage</a>
+  <br/>
+  <a href="clarguments-advanced.html">Command Line: advanced usage</a>
+  <br/>
+  <a href="clarguments-argfiles.html">Command Line: argument files</a>
+  <br/>
+  Command Line: reference
+  </p>
+
+  <hr/>
+
+  <ul>
+  <li><a href="#initialisingarguments">Initialising arguments</a></li>
+  <li><a href="#openinganalignment">Opening an alignment</a></li>
+  <li><a href="#adding3dstructure">Adding 3D structure</a></li>
+  <li><a href="#processingalignments">Processing alignments</a></li>
+  <li><a href="#outputtingalignmentfiles">Outputting alignment files</a></li>
+  <li><a href="#exportingimagefiles">Exporting image files</a></li>
+  <li><a href="#exporting3dstructureimagefiles">Exporting 3D structure image files</a></li>
+  <li><a href="#controllingflowofarguments">Controlling flow of arguments</a></li>
+  </ul>
+
+
+  <h2><a name="initialisingarguments"></a>Initialising arguments</h2>
+
+  <table border="1" cellpadding="3">
+    <tr valign="top">
+    <td><strong>argument</strong></td>
+    <td><strong>action</strong></td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;help / -h</code>
+    </td>
+    <td>Display a help statement.</td>
+    </tr>
+
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;config</code></td><td>Help for arguments used to configure Jalview from startup</td></tr>
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;opening</code></td><td>Help for arguments used to open and format alignments</td></tr>
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;structure</code></td><td>Help for arguments used to add and format 3D structure data</td></tr>
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;process</code></td><td>Help for arguments used to process an alignment once opened</td></tr>
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;output</code></td><td>Help for arguments used to save data from a processed alignment</td></tr>
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;image</code></td><td>Help for arguments used to export an image of an alignment</td></tr>
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;structureimage</code></td><td>Help for arguments used to export an image of an structure</td></tr>
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;flow</code></td><td>Help for arguments that control processing of the other arguments</td></tr>
+    <tr valign="top"><td><code>&#8209;&#8209;help&#8209;all</code></td><td>Help for all arguments</td></tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;headless</code></td>
+    <td>Run Jalview in headless mode.  In headless mode, no GUI interface will be created and Jalview will quit after all arguments have been processed.
+    <br/>
+    If you use a command line argument to specify an output file of some kind (<code>--output</code>, <code>--image</code> or <code>--structureimage</code>) then <strong>headless mode will be assumed</strong>.  If you don't want this behaviour use <code>--gui</code>.
+    </td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;gui</code></td>
+    <td>Force Jalview to run in graphical mode.  This can be used to counter the assumption of headless mode when an argument that creates an output file is used.  <code>--gui</code> takes precedence over <code>--headless</code>.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;jabaws&nbsp;<em>URL</em></code></td>
+    <td>Set a different URL to connect to a JABAWS server.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;news / &#8209;&#8209;nonews</code></td>
+    <td>Show (/ or don't show) the news feed.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;splash / &#8209;&#8209;nosplash</code></td>
+    <td>Show (/ or don't show) the About Jalview splash screen.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;questionnaire / &#8209;&#8209;noquestionnaire</code></td>
+    <td>Show (/ or don't show) the questionnaire if one is available.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;nousagestats</code></td>
+    <td>Don't send usage stats via Google analytics for this session. <em>Note: usage stats are useful for future funding for Jalview!</em></td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;nostartupfile</code></td>
+    <td>Don't show the default startup file.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;webservicediscovery / &#8209;&#8209;nowebservicediscovery</code></td>
+    <td>Attempt (/ or don't attempt) to connect to JABAWS web services.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;props&nbsp;<em>filename</em></code></td>
+    <td>Use file <em>filename</em> as the preferences file <em>instead</em> of the usual <code>~/.jalview_properties</code> file.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;debug</code></td>
+    <td>Start Jalview in debug log level.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;quiet</code></td>
+    <td>Stop all output to STDOUT (after the Java Virtual Machine has started).  Use <code>&#8209;&#8209;quiet</code> a second time to stop all output to STDERR.</td>
+    </tr>
+
+<!--
+    <tr valign="top">
+    <td><code>&#8209;&#8209;P<em>PREFERENCE=VALUE</em></code></td>
+    <td>Set a Jalview preference for this session only.  Experimental.</td>
+    </tr>
+-->
+
+<!--
+    <tr valign="top">
+    <td><code>&#8209;&#8209;initsubstitutions / &#8209;&#8209;noinitsubstitutions</code></td>
+    <td>Set <code>&#8209;&#8209;substitutions</code> to be initially enabled (or initially disabled).</td>
+    </tr>
+-->
+
+<!--
+    <tr valign="top">
+    <td><code>&#8209;&#8209;threads <em>NUMBER</em></code></td>
+    <td>When opening multiple alignment windows, set a limit of <em>NUMBER</em> alignments being processed at one time.  The default is 3.</td>
+-->
+
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;jvmmempc=<em>PERCENT</em></code></td>
+    <td>
+      Limit maximum heap size (memory) to <em>PERCENT</em>% of total physical memory detected.
+      This defaults to 90 if total physical memory can be detected.
+      <br/>
+      The equals sign ("=") separator must be used with no spaces.
+      <br/>
+      See <a href="../memory.html">Memory usage settings for Jalview</a> for more details.
+    </td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;jvmmemmax=<em>MAXMEMORY</em></code></td>
+    <td>
+      Limit maximum heap size (memory) to <em>MAXMEMORY</em>. <em>MAXMEMORY</em> can be specified in bytes, kilobytes(k), megabytes(m),
+      gigabytes(g) or if you're lucky enough, terabytes(t).
+      This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected.
+      <br/>
+      The equals sign ("=") separator must be used with no spaces.
+      <br/>
+      See <a href="../memory.html">Memory usage settings for Jalview</a> for more details.
+    </td>
+    </tr>
+
+  </table>
+
+
+  <h2><a name="openinganalignment"></a>Opening an alignment</h2>
+
+  <table border="1" cellpadding="3">
+    <tr valign="top">
+    <td><strong>argument</strong></td>
+    <td><strong>action</strong></td>
+    <td><strong>sub-value modifiers</strong> (optional)</td>
+    <td><strong>linked</strong> (optional)</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;open&nbsp;<em>filename/URL ...</em></code></td>
+    <td>
+    Opens one or more alignment files <em>filename</em> or URLs <em>URL</em> in new alignment windows.
+    </td>
+    <td>
+      <code>
+        colour=<em>name</em>,
+        <br/>
+        title=<em>string</em>,
+        <br/>
+        features=<em>filename</em>,
+        <br/>
+        annotations=<em>filename</em>,
+        <br/>
+        tree=<em>filename</em>,
+        <br/>
+        showannotations,
+        <br/>
+        showssannotations,
+        <br/>
+        sortbytree,
+        <br/>
+        wrap
+      </code>
+    </td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;append&nbsp;<em>filename/URL ...</em></code></td>
+    <td>Appends one or more alignment files <em>filename</em> or URLs <em>URL</em> to the open alignment window (or opens a new alignment if none already open).</td>
+    <td>
+    <code>
+        colour=<em>name</em>,
+        <br/>
+        title=<em>string</em>,
+        <br/>
+        features=<em>filename</em>,
+        <br/>
+        annotations=<em>filename</em>,
+        <br/>
+        tree=<em>filename</em>,
+        <br/>
+        showannotations,
+        <br/>
+        showssannotations,
+        <br/>
+        sortbytree,
+        <br/>
+        wrap
+      </code>
+    </td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;title&nbsp;<em>"string"</em></code></td>
+    <td>Specifies the title for the open alignment window as <em>string</em>.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;colour&nbsp;<em>name</em></code></td>
+    <td>Applies the colour scheme <em>name</em> to the open alignment window.  Valid values for <em>name</em> include:
+    <br/>
+    <code>clustal</code>,
+    <br/>
+    <code>blosum62</code>,
+    <br/>
+    <code>pc-identity</code>,
+    <br/>
+    <code>zappo</code>,
+    <br/>
+    <code>taylor</code>,
+    <br/>
+    <code>gecos-flower</code>,
+    <br/>
+    <code>gecos-blossom</code>,
+    <br/>
+    <code>gecos-sunset</code>,
+    <br/>
+    <code>gecos-ocean</code>,
+    <br/>
+    <code>hydrophobic</code>,
+    <br/>
+    <code>helix-propensity</code>,
+    <br/>
+    <code>strand-propensity</code>,
+    <br/>
+    <code>turn-propensity</code>,
+    <br/>
+    <code>buried-index</code>,
+    <br/>
+    <code>nucleotide</code>,
+    <br/>
+    <code>nucleotide-ambiguity</code>,
+    <br/>
+    <code>purine-pyrimidine</code>,
+    <br/>
+    <code>rna-helices</code>,
+    <br/>
+    <code>t-coffee-scores</code>,
+    <br/>
+    <code>sequence-id</code>.
+    <br/>
+    <br/>
+    Names of user defined schemes will also work, and jalview colour scheme specifications like:
+    <br/>
+       <code>&#8209;&#8209;colour "D,E=red; K,R,H=0022FF; C,c=yellow"</code>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;features&nbsp;<em>filename/URL</em></code></td>
+    <td>Add a feature file <em>filename</em> or URL <em>URL</em> to the open alignment.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;tree&nbsp;<em>filename/URL</em></code></td>
+    <td>Add a tree file <em>filename</em> or URL <em>URL</em> to the open alignment.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;sortbytree / &#8209;&#8209;nosortbytree</code></td>
+    <td>Enforces sorting (or not sorting) the alignment in the order of an attached phylogenetic tree.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;annotations&nbsp;<em>filename/URL</em></code></td>
+    <td>Add an annotations file <em>filename</em> or URL <em>URL</em> to the open alignment.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;showannotations / &#8209;&#8209;noshowannotations</code></td>
+    <td>Enforces showing (or not showing) alignment annotations.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;wrap / &#8209;&#8209;nowrap</code></td>
+    <td>Enforces wrapped (or not wrapped) alignment formatting.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;nostructure</code></td>
+    <td>Do not open or process any 3D structure in the <code>&#8209;&#8209;open</code> or <code>&#8209;&#8209;append</code> files.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+  </table>
+
+
+  <h2><a name="adding3dstructure"></a>Adding 3D structure</h2>
+
+  <table border="1" cellpadding="3">
+    <tr valign="top">
+    <td><strong>argument</strong></td>
+    <td><strong>action</strong></td>
+    <td><strong>sub-value modifiers</strong> (optional)</td>
+    <td><strong>linked</strong> (optional)</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;structure&nbsp;<em>filename/URL</em></code></td>
+    <td>Load a structure file <em>filename</em> or URL <em>URL</em> associated with a sequence in the open alignment.  The sequence to be associated with can be specified with a following <code>&#8209;&#8209;seqid</code> argument, or the sub-value modifier <code>seqid=<em>ID</em></code> can be used.  A sub-value <em>INDEX</em> can also be used to specify the <em>INDEX-th</em> sequence in the open alignment.</td>
+    <td>
+      <code>
+        seqid=<em>id</em></code> or <code><em>INDEX</em>,
+        <br/>
+        paefile=<em>filename</em>,
+        <br/>
+        tempfac=<em>name</em>,
+        <br/>
+        showssannotations,
+        <!--
+        <br/>
+        notempfac,
+        -->
+        <br/>
+        structureviewer=<em>name</em>
+      </code></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;seqid&nbsp;<em>ID</em></code></td>
+    <td>Specify the sequence name for the preceding <code>&#8209;&#8209;structure</code> to be associated with.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;paematrix&nbsp;<em>filename</em></code></td>
+    <td>Add a PAE json matrix file <em>filename</em> to the preceding <code>&#8209;&#8209;structure</code>.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;tempfac&nbsp;<em>name</em></code></td>
+    <td>Set the type of temperature factor.  Valid values for <em>name</em> are:
+      <br/>
+      <code>default</code>,
+      <br/>
+      <code>plddt</code>
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;structureviewer&nbsp;<em>name</em></code></td>
+    <td>Set the structure viewer to use to open the 3d structure file specified in previous <code>&#8209;&#8209;structure</code> to <em>name</em>.  Valid values of <em>name</em> are:
+    <br/>
+    <code>none</code>,
+    <br/>
+    <code>jmol</code>,
+    <br/>
+    <code>chimera</code> <em>- requires installation, might need configuring in Preferences</em>,
+    <br/>
+    <code>chimerax</code> <em>- requires installation, might need configuring in Preferences</em>,
+    <br/>
+    <code>pymol</code> <em>- requires installation, might need configuring in Preferences</em>
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+
+    <!--
+    <tr valign="top">
+    <td><code>&#8209;&#8209;notempfac</code></td>
+    <td>Do not show the temperature factor annotation for the preceding <code>&#8209;&#8209;structure</code></td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+    -->
+
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;showssannotations / &#8209;&#8209;noshowssannotations</code></td>
+    <td>Do not show secondary structure annotations for the preceding <code>&#8209;&#8209;structure</code></td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;close</code></td>
+    <td>Close the open alignment window.  This occurs after other output, processing and image export arguments.  This applies to the current open alignment -- to apply to all <code>&#8209;&#8209;output</code> and <code>&#8209;&#8209;image</code> files, use after <code>&#8209;&#8209;all</code>.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+  </table>
+
+
+  <h2><a name="processingalignments"></a>Processing alignments</h2>
+
+  <table border="1" cellpadding="3">
+    <tr valign="top">
+    <td><strong>argument</strong></td>
+    <td><strong>action</strong></td>
+    <td><strong>sub-value modifiers</strong> (optional)</td>
+    <td><strong>linked</strong> (optional)</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;groovy&nbsp;<em>filename</em></code></td>
+    <td>Process a groovy script in the file for the open alignment.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+  </table>
+
+
+  <h2><a name="outputtingalignmentfiles"></a>Outputting alignment files</h2>
+
+  <table border="1" cellpadding="3">
+    <tr valign="top">
+    <td><strong>argument</strong></td>
+    <td><strong>action</strong></td>
+    <td><strong>sub-value modifiers</strong> (optional)</td>
+    <td><strong>linked</strong> (optional)</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;output&nbsp;<em>filename</em></code></td>
+    <td>Export the open alignment to file <em>filename</em>.  The format <em>name</em> is specified by the sub-value modifier <code>format=<em>name</em></code>, a following <code>&#8209;&#8209;format <em>name</em></code> argument or guessed from the file extension.  Valid format names (and file extensions) are:
+    <br/>
+    <code>fasta</code> (<code>fa, fasta, mfa, fastq</code>),
+    <br/>
+    <code>pfam</code> (<code>pfam</code>),
+    <br/>
+    <code>stockholm</code> (<code>sto, stk</code>),
+    <br/>
+    <code>pir</code> (<code>pir</code>),
+    <br/>
+    <code>blc</code> (<code>blc</code>),
+    <br/>
+    <code>amsa</code> (<code>amsa</code>),
+    <br/>
+    <code>json</code> (<code>json</code>),
+    <br/>
+    <code>pileup</code> (<code>pileup</code>),
+    <br/>
+    <code>msf</code> (<code>msf</code>),
+    <br/>
+    <code>clustal</code> (<code>aln</code>),
+    <br/>
+    <code>phylip</code> (<code>phy</code>),
+    <br/>
+    <code>jalview</code> (<code>jvp, jar</code>).
+    <br/>
+    To output directly to STDOUT (console output) use the filename <code>-</code> (a single hyphen).  In this case all STDOUT messages will instead go to STDERR.  If no <code>format</code> is supplied then Fasta will be assumed.
+    </td>
+    <td><code>format=<em>name</em></code></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;format&nbsp;<em>name</em></code></td>
+    <td>Sets the format for the preceding <code>&#8209;&#8209;output</code> file.  Valid formats are:
+    <br/>
+    <code>fasta</code>,
+    <br/>
+    <code>pfam</code>,
+    <br/>
+    <code>stockholm</code>,
+    <br/>
+    <code>pir</code>,
+    <br/>
+    <code>blc</code>,
+    <br/>
+    <code>amsa</code>,
+    <br/>
+    <code>json</code>,
+    <br/>
+    <code>pileup</code>,
+    <br/>
+    <code>msf</code>,
+    <br/>
+    <code>clustal</code>,
+    <br/>
+    <code>phylip</code>,
+    <br/>
+    <code>jalview</code>.
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;backups / &#8209;&#8209;nobackups</code></td>
+    <td>Enable (or disable) writing backup files when saving an <code>&#8209;&#8209;output</code> file.  This applies to the current open alignment -- to apply to all <code>&#8209;&#8209;output</code> and <code>&#8209;&#8209;image</code> files, use after <code>&#8209;&#8209;all</code>.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;overwrite / &#8209;&#8209;nooverwrite</code></td>
+    <td>Enable (or disable) overwriting of output files without backups enabled.  This applies to the current open alignment -- to apply to all <code>&#8209;&#8209;output</code> and <code>&#8209;&#8209;image</code> files, use after <code>&#8209;&#8209;all</code>.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+  </table>
+
+
+  <h2><a name="exportingimagefiles"></a>Exporting image files</h2>
+
+  <table border="1" cellpadding="3">
+    <tr valign="top">
+    <td><strong>argument</strong></td>
+    <td><strong>action</strong></td>
+    <td><strong>sub-value modifiers</strong> (optional)</td>
+    <td><strong>linked</strong> (optional)</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;image&nbsp;<em>filename</em></code></td>
+    <td>Output an image of the open alignment window.  Format is specified by the sub-value modifier, a following <code>&#8209;&#8209;type</code> argument or guessed from the file extension.  Valid formats/extensions are:
+    <br/>
+    <code>svg</code>,
+    <br/>
+    <code>png</code>,
+    <br/>
+    <code>eps</code>,
+    <br/>
+    <code>html</code>,
+    <br/>
+    <code>biojs</code>.
+    </td>
+    <td>
+      <code>type=<em>name</em>,
+      <code>textrenderer=<em>name</em>,
+      <code>scale=<em>number</em>,
+      <code>width=<em>number</em>,
+      <code>height=<em>number</em>
+    </td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;type&nbsp;<em>name</em></code></td>
+    <td>Set the image format for the preceding <code>&#8209;&#8209;image</code> to <em>name</em>.  Valid values for <em>name</em> are:
+    <br/>
+    <code>svg</code>,
+    <br/>
+    <code>png</code>,
+    <br/>
+    <code>eps</code>,
+    <br/>
+    <code>html</code>,
+    <br/>
+    <code>biojs</code>.
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;textrenderer&nbsp;<em>name</em></code></td>
+    <td>Sets whether text in a vector image format (SVG, HTML, EPS) should be rendered as text or vector line-art.  Valid values for <em>name</em> are:
+    <br/>
+    <code>text</code>,
+    <br/>
+    <code>lineart</code>.
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;scale&nbsp;<em>number</em></code></td>
+    <td>Sets a scaling for bitmap image format (PNG).  Should be given as a floating point number.  This can also be set as a sub-value modifier to the <code>--image</code> value.  If used in conjunction with <code>--width</code> and <code>--height</code> then the smallest scaling will be used (<code>scale</code>, <code>width</code> and <code>height</code> provide bounds for the image).
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;width&nbsp;<em>number</em></code></td>
+    <td>Sets a width for bitmap image format (PNG) with the height maintaining the aspect ratio.  Should be given as a positive integer.  This can also be set as a sub-value modifier to the <code>--image</code> value.  If used in conjunction with <code>--scale</code> and <code>--height</code> then the smallest scaling will be used (<code>scale</code>, <code>width</code> and <code>height</code> provide bounds for the image).
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;height&nbsp;<em>number</em></code></td>
+    <td>Sets a height for bitmap image format (PNG) with the width maintaining the aspect ratio.  Should be given as a positive integer.  This can also be set as a sub-value modifier to the <code>--image</code> value.  If used in conjunction with <code>--scale</code> and <code>--width</code> then the smallest scaling will be used (<code>scale</code>, <code>width</code> and <code>height</code> provide bounds for the image).</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;groovy&nbsp;<em>filename</em></code></td>
+    <td>Process a groovy script in the file for the open alignment.</td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+  </table>
+
+
+  <h2><a name="exporting3dstructureimagefiles"></a>Exporting 3D structure image files (<code>jmol</code> only)</h2>
+
+  <table border="1" cellpadding="3">
+    <tr valign="top">
+    <td><strong>argument</strong></td>
+    <td><strong>action</strong></td>
+    <td><strong>sub-value modifiers</strong> (optional)</td>
+    <td><strong>linked</strong> (optional)</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;structureimage&nbsp;<em>filename</em></code></td>
+    <td>Export an image of a 3D structure opened in JMOL.  Image formats can be:
+    <br/>
+    <code>svg</code>,
+    <br/>
+    <code>png</code>,
+    <br/>
+    <code>eps</code>.
+    </td>
+    <td>
+      <code>structureimagetype=<em>name</em>,
+      <code>structureimagetextrenderer=<em>name</em>,
+      <code>structureimagescale=<em>number</em>,
+      <code>structureimagewidth=<em>number</em>,
+      <code>structureimageheight=<em>number</em>
+    </td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;structureimagetype&nbsp;<em>name</em></code></td>
+    <td>Set the structure image format for the preceding --structureimage. Valid values are:
+    <br/>
+    <code>svg</code>,
+    <br/>
+    <code>png</code>,
+    <br/>
+    <code>eps</code>.
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;structureimagetextrenderer&nbsp;<em>name</em></code></td>
+    <td>Sets whether text in a vector structure image format (SVG, EPS) should be rendered as text or vector line-art. Possible values are:
+    <br/>
+    <code>text</code>,
+    <br/>
+    <code>lineart</code>.
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;structureimagescale&nbsp;<em>number</em></code></td>
+    <td>Sets a scaling for bitmap structure image format (PNG). Should be given as a floating point number. If used in conjunction with --structureimagewidth and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;structureimagewidth&nbsp;<em>number</em></code></td>
+    <td>Sets a width for bitmap structure image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;structureimageheight&nbsp;<em>number</em></code></td>
+    <td>Sets a height for bitmap structure image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimagewidth then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).
+    </td>
+    <td></td>
+    <td align="center">&#x2713;</td>
+    </tr>
+
+  </table>
+
+
+  <h2><a name="controllingflowofarguments"></a>Controlling flow of arguments</h2>
+
+  <table border="1" cellpadding="3">
+    <tr valign="top">
+    <td><strong>argument</strong></td>
+    <td><strong>action</strong></td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;new</code></td>
+    <td>
+    Move on to a new alignment window.  This will ensure <code>&#8209;&#8209;append</code> will start a new alignment window and other linked arguments will apply to the new alignment window.
+    <br/>
+    <em>Note</em> that <code>--open</code> already starts a new alignment window for each file it opens.
+    </td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;substitutions / &#8209;&#8209;nosubstitutions</code></td>
+    <td>The following argument values allow (or don't allow) subsituting filename parts.  This is initially true.  Valid substitutions are
+    <code>{basename}</code> - the filename-without-extension of the currently <code>&#8209;&#8209;open</code>ed file (or first <code>&#8209;&#8209;append</code>ed file),
+    <br/>
+    <code>{dirname}</code>, - the directory (folder) name of the currently <code>&#8209;&#8209;open</code>ed file (or first <code>&#8209;&#8209;append</code>ed file),
+    <br/>
+    <code>{argfilebasename}</code> - the filename-without-extension of the current <code>&#8209;&#8209;argfile</code>,
+    <br/>
+    <code>{argfiledirname}</code> - the directory (folder) name of the current <code>&#8209;&#8209;argfile</code>,
+    <br/>
+    <code>{n}</code> - the value of the index counter (starting at 0).
+    <br/>
+    <code>{++n}</code> - increase and substitute the value of the index counter,
+    <br/>
+    <code>{}</code> - the value of the current alignment window <em>default</em> index.
+    </td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;argfile&nbsp;<em>filename</em></code></td>
+    <td>
+    Open one or more files <em>filename</em> and read, line-by-line, as arguments to Jalview.
+    <br/>
+    Values in an argfile should be given with an equals sign ("=") separator with no spaces.
+    <br/>
+    <strong>Note</strong> that if you use one or more <code>&#8209;&#8209;argfile</code> arguments then all other non-initialising arguments will be ignored.
+    </td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;npp</code></td>
+    <td>Increase the index counter used in argument value substitutions.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;all / &#8209;&#8209;noall</code></td>
+    <td>Apply (or stop applying) the following output arguments to <em>all</em> sets of linked arguments.</td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;allstructures / &#8209;&#8209;noallstructures</code></td>
+    <td>
+        Apply (or stop applying) the following 3D structure formatting arguments to all structures <em>within the current open alignment</em>.  Whilst <code>--allstructures</code> will continue to operate for a <code>--new</code> alignment, the structure formatting arguments must be set again for each new alignment.
+    </td>
+    </tr>
+
+    <tr valign="top">
+    <td><code>&#8209;&#8209;quit</code></td>
+    <td>After all files have been opened, appended and output, quit Jalview.  In <code>&#8209;&#8209;headless</code> mode this already happens.</td>
+    </tr>
+
+  </table>
+
+</body>
+</html>
index c0f4c42..7c2e9d5 100644 (file)
@@ -1,15 +1,5 @@
 <html>
 <!--
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- * 
- * This file is part of Jalview.
- * 
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *  
  * Jalview is distributed in the hope that it will be useful, but 
  * WITHOUT ANY WARRANTY; without even the implied warranty 
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  -->
-<title>Jalview Command Line Arguments</title>
+<title>Command Line: introduction and reference</title>
 <body>
+
+  <h1>Command Line: introduction and reference</h1>
+
+  <p>
+  Command Line: introduction
+  <br/>
+  <a href="clarguments-basic.html">Command Line: basic usage</a>
+  <br/>
+  <a href="clarguments-advanced.html">Command Line: advanced usage</a>
+  <br/>
+  <a href="clarguments-argfiles.html">Command Line: argument files</a>
+  <br/>
+  <a href="clarguments-reference.html">Command Line: reference</a>
+  </p>
+
+
+  <hr/>
+
+  <ul>
+  <li><a href="#introduction">Introduction</a></li>
+  <li><a href="#syntax">Syntax</a></li>
+  <li><a href="#headlessmode">Headless mode</a></li>
+  </ul>
+
+  <h2><a name="introduction"></a>Introduction</h2>
+
+  <p>
+  From version 2.11.3.0 Jalview has a new set of command line arguments
+  which allow more powerful and flexible combinations of arguments, though can
+  also be used for simple use cases too.
+  </p>
+
+  <p>
+  These new arguments are all accessed with a <code>--doubledash</code> form of
+  command line argument (with the one exception where simply opening one or more
+  files can be performed without any arguments other than the filenames).
+  </p>
+
+  <p>
+  The old command line arguments can still be used (see
+  <a href="clarguments-old.html">the old page on command line arguments</a>) so
+  existing scripts utilising them should not break.
+  <br/>
+  <strong>These are now deprecated and will be removed</strong> in a future version of Jalview.
+  </p>
+
   <p>
-    <strong>The Jalview Executable's Command Line Arguments</strong>
+  However, you cannot mix old and new style arguments, so if you use any
+  <code>-singledash</code> arguments (with the exception of <code>-help</code> or <code>-h</code>), they will all be interpreted as
+  old style arguments with the new <code>--doubledash</code>
+  arguments being ignored.  If you have a script
+  that uses the old arguments without any dashes, and uses the bare-word
+  <code>open</code> then these will also be interpreted as old style arguments.
   </p>
-  See
-  <a href="commandline.html">running Jalview from the command line</a>
-  for more information.
-  <br />
-  <br />Jalview processes arguments on the command line sequentially. If
-  you would like to pass a <a href="jvlfiles.html">'JVL' file</a> containing
-  <a href="../memory.html">memory settings</a> or any other launch
-  parameters, then include it at the beginning of the command line to
-  ensure they are processed before any remaining arguments.
-  <br>
-  Typical command line execution follows the following pattern:
-  <pre>
-  jalview -open &lt;Alignment File/URL&gt; [additional import arguments] [export arguments]
-  </pre>
-  
-  <table width="100%" border="1" cellspacing="0" cellpadding="0">
-    <tr>
-      <td width="27%"><div align="center">-nodisplay</div></td>
-      <td width="73%"><div align="left">Run Jalview without
-          User Interface. (automatically disables questionnaire, version
-          and usage stats checks)</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-nowebservicediscovery</div></td>
-      <td><div align="left">Do not query configured servers to
-          discover web services (<em>Since 2.11.2.0</em>)</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-open FILE/URL</div></td>
-      <td><div align="left">Specify the alignment file to
-          open or process by providing additional arguments.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-props FILE/URL</div></td>
-      <td><div align="left">Use the given Jalview properties
-          file instead of users default.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-setprop PROPERTY=value</div></td>
-      <td><div align="left">(JalviewJS ONLY) sets the given
-          property to the given value</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-features FILE/URL</div></td>
-      <td><div align="left">
-          <p>
-            Use the given file to add sequence features to an alignment.
-            See <a href="featuresFormat.html" target="NEW">Features
-              File</a> (Known as Groups file prior to 2.08) description.
-          </p>
 
-        </div></td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-colour COLOURSCHEME</div>
-      </td>
-      <td>Set the colourscheme for the alignment. This can be any
-        of the built-in colourschemes, a name of a predefined
-        colourscheme (defined in the Jalview properties file), or an
-        'inline' colourscheme (see the applet's colour parameter for
-        more information).</td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-annotations FILE/URL</div>
-      </td>
-      <td>Add precalculated annotations to the alignment. See <a
-        href="annotationsFormat.html" target="NEW">Annotation
-          File</a> description.
-      </td>
-    </tr>
-        <tr>
-      <td>
-        <div align="center">-no-annotation</div>
-      </td>
-      <td>Do not display annotation below the alignment. 
-      </td>
-    </tr>
-    
-    <tr>
-      <td>
-        <div align="center">-tree FILE/URL</div>
-      <td>
-        <div align="left">Load the given newick format tree file
-          onto the alignment</div>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-questionnaire URL</div>
-      <td>
-        <div align="left">Queries the given URL for information
-          about any Jalview user questionnaires</div>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-noquestionnaire</div>
-      <td>
-        <div align="left">Turn off questionnaire check</div>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-nonews</div>
-      <td>
-        <div align="left">
-          Disable check for <a href="../webServices/newsreader.html">Jalview
-            news</a> on startup (not recommended other than for classroom /
-          demo usage)
-        </div>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-nousagestats</div>
-      <td>
-        <div align="left">Turn off google analytics usage tracking</div>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-[no]sortbytree</div>
-      <td>
-        <div align="left">Enable or disable automatic sorting of
-          associated view when a new tree is displayed</div>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-groovy FILE/URL</div>
-      <td>
-        <div align="left">Execute groovy script in FILE (where
-          FILE may be 'STDIN' to read from the standard input) after all
-          other arguments have been processed</div>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-jabaws URL</div>
-      <td>
-        <div align="left">Specify the URL of the preferred JABAWS
-          server</div>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <div align="center">-fasta FILE</div>
-      </td>
+  <p>
+  <strong>Warning!</strong> If you use command line arguments without any dashes and
+  <em>don't</em> use the bare-word argument <code>open</code> then all
+  your arguments will be interpreted as alignment files to be opened by the
+  new command line argument process!
+  </p>
 
-      <td>
-        <div align="left">Create alignment file FILE in Fasta
-          format.</div>
-      </td>
-    </tr>
-    <tr>
-      <td><div align="center">-clustal FILE</div></td>
-      <td><div align="left">Create alignment file FILE in
-          Clustal format.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-msf FILE</div></td>
+  <p>
+  To launch Jalview from the command line, see
+  <a href="commandline.html">running Jalview from the command line</a>.
+  </p>
 
-      <td><div align="left">Create alignment file FILE in MSF
-          format.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-pileup FILE</div></td>
-      <td><div align="left">Create alignment file FILE in
-          Pileup format.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-pir FILE</div></td>
 
-      <td><div align="left">Create alignment file FILE in PIR
-          format.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-pfam FILE</div></td>
-      <td><div align="left">Create alignment file FILE in
-          PFAM format.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-blc FILE</div></td>
-      <td><div align="left">Create alignment file FILE in BLC
-          format.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-json FILE</div></td>
-      <td><div align="left">Create alignment file FILE in
-          JSON format.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-jalview FILE</div></td>
+  <h2><a name="syntax"></a>Syntax</h2>
+
+  <p>
+  The new command line argument parser can group certain labelled arguments together, or give them a default label based on their position in the list of arguments (in which case you won't ever need to know what the label is).  All arguments are read before any alignment actions are performed.  For basic usage without additional syntax, please see the <a href="clarguments-basic.html">Command Line: basic usage</a> explanatory page.
+  </p>
+
+  <h3>
+  Parts of Jalview's command line arguments
+  </h3>
+  <pre>jalview --argname[linkedId]=[subvalues]value --switch --noswitch --argname[linkedId] [subvalues]filename1 filename2 ...</pre>
+
+  <p>
+  Different arguments can take one or more values, others take no value and act like a switch (some can be set on and off and others are only on, depending on the use).
+  <br/>
+  <ul>
+    <li>
+        For arguments that require a value, the value can be given after an equals-sign ('=') or a space (' ').
+        <br/>
+        <code>--arg value</code>
+        <br/>
+        <code>--arg=value</code>
+    </li>
+    <li>
+        For arguments that can take multiple values (these will be filenames), the multiple filenames should appear after a space. If you use a filename wildcard you can put this after a space (which will be expanded by the shell unto multiple filenames before they reach Jalview), or you can put it after an equals-sign, which will be used by Jalview to find a list of files.  You cannot use an equals-sign and value followed by further values.
+        <br/>
+        <code>--arg file1.fa otherfile.stk</code>
+        <br/>
+        <code>--arg filename*.fa</code> <em>(filenames expanded by shell)</em>
+        <br/>
+        <code>--arg=filename*.fa</code> <em>(filenames expanded by Jalview)</em>
+    </li>
+    <li>
+        For arguments that act as a switch, most can be negated by preceding the argument name with <code>no</code>.
+        <br/>
+        <code>--switch</code>
+        <br/>
+        <code>--noswitch</code>
+    </li>
+    <li>
+        Some values can be modified, or may need additional information (for instance an <code>--image</code> output can be modified with a <code>--scale=number</code> factor, or a <code>--structure</code> can refer to a sequence with a <code>--seqid=ID</code>).  This additional information can be added in a number of different ways.
+        <ul>
+          <li>
+              An argument immediately following the main argument.
+              <br/>
+              <code>--image output.png --scale 2.5</code>
+          </li>
+          <li>
+              A <em>sub-value modifier</em>, which is where one or more (comma-separated) values are added to the start of the main value, placed in square brackets.
+              <br/>
+              <code>--open=[nowrap,colour=gecos-blossom]uniref50.fa</code>
+              <br/>
+              Sub-value modifiers with a value must use an equals-sign separator, and those that act as a switch can simply be included without an equals-sign or value, and can be preceded with <code>no</code> to negate the value, as with the argument name.
+          </li>
+          <li>
+              Another argument with the same <em>linked ID</em>.  A linked ID is an optional identifier for a particular open alignment, placed in square brackets immediately following the argument name (before the equals-sign or space).  If linked IDs are specified they do not need to be near to each other.
+              <br/>
+              <code>--image[MYID]=output.png --other --args --scale[MYID]=2.5</code>
+          </li>
+          <li>
+              An argument that is designated as applying to <em>all linked IDs</em>
+              <br/>
+              <code>--image=output.png --other --args --all --scale=2.5</code>
+              <br/>
+              <code>--image=output.png --other --args --scale[*]=2.5</code>
+          </li>
+        </ul>
+    </li>
+  </ul>
+  </p>
+
+  <p>
+  This may sound complicated, but nearly everything can be done just with plain command line arguments (see <a href="clarguments-basic.html">Command Line: basic usage</a>), though in this case the ordering of the arguments is more important.
+  </p>
+
+
+  <h2><a name="headlessmode"></a>Headless mode</h2>
+
+  <p>
+  Jalview can be run in headless mode, i.e. without the usual graphical user interface (GUI), by specifying the <code>--headless</code> argument.  With command line arguments you can specify operations for Jalview to perform on one or more files and then stop running.  Most likely you will want to output another file, either an alignment for image file.
+  </p>
+  <p>
+  <strong>If you specify an argument for an output file</strong> (one or more of <code>--output</code>, <code>--image</code> or <code>--structureimage</code>) then it will be assumed that you wish to <strong>run in headless mode</strong>.
+  </p>
+  <p>
+  You can force Jalview to run in graphical mode using the <code>--gui</code> argument.
+  </p>
+
+  <p>
+  </p>
+
 
-      <td><div align="left">Create alignment file FILE in
-          Jalview format.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-png FILE</div></td>
-      <td><div align="left">Create PNG image FILE from
-          alignment.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-imgMap FILE</div></td>
+  <hr/>
+  Continue to <a href="clarguments-basic.html">Command Line: basic usage</a>.
+  <br/>
+  <a href="clarguments-reference.html">Command Line: reference</a>
 
-      <td><div align="left">Create HTML file FILE with image
-          map of PNG image.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-eps FILE</div></td>
-      <td><div align="left">Create EPS file FILE from
-          alignment.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-svg FILE</div></td>
-      <td><div align="left">Create Scalable Vector Graphics
-          file FILE from alignment.</div></td>
-    </tr>
-    <tr>
-      <td><div align="center">-biojsMSA FILE</div></td>
-      <td><div align="left">Write an HTML page to display
-          the alignment with the <a href="biojsmsa.html">
-          BioJS MSAviewer MSA</a>
-          </div>
-      </td>
-    </tr>
-    <tr>
-      <td><div align="center">-jvmmempc=PERCENT</div></td>
-      <td><div align="left"><em>Only available with standalone executable jar or jalview.bin.Launcher.</em>
-          Limit maximum heap size (memory) to PERCENT% of total physical memory detected.
-         This defaults to 90 if total physical memory can be detected.
-         See <a href="../memory.html">Memory usage settings for Jalview</a> for more details.
-          </div>
-      </td>
-    </tr>
-    <tr>
-      <td><div align="center">-jvmmemmax=MAXMEMORY</div></td>
-      <td><div align="left"><em>Only available with standalone executable jar or jalview.bin.Launcher.</em>
-          Limit maximum heap size (memory) to MAXMEMORY. MAXMEMORY can be specified in bytes, kilobytes(k), megabytes(m),
-         gigabytes(g) or if you're lucky enough, terabytes(t).
-         This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected.
-         See <a href="../memory.html">Memory usage settings for Jalview</a> for more details.
-          </div>
-      </td>
-    </tr>
-  </table>
 </body>
 </html>
index 381478f..b162740 100644 (file)
@@ -46,8 +46,7 @@
       <li>For older versions of Jalview, call the <a href="#olderinstalls">native launch program directly</a>.
   </ul>
   <p>
-    <strong><a name="script">Jalview's command line launch
-        script</a></strong>
+    <strong><a name="script">Jalview's command line launch</a></strong>
   <p>Since version 2.11.2, the Jalview native application includes a <strong>launching shell script</strong>. This is the easiest way to
   launch an installed Jalview application from the command line. </p><p>To run the <strong>launch script</strong>, simply open a Terminal (or Command prompt on Windows), and type:<pre>
   jalview</pre>
     included in the source distribution.
   </p>
   <p>
-    Use '-help' to get more information on the <a
+    Use '--help' to get more information on the <a
       href="clarguments.html">command line arguments</a> that Jalview
     accepts.
   </p>
index 4df0b0c..a2536e2 100755 (executable)
@@ -42,7 +42,7 @@
   
   <ul>
     <li>from the command line <pre>
-<strong> -features &lt;<em>Features filename</em>&gt;</strong>
+<strong> --features &lt;<em>Features filename</em>&gt;</strong>
 </pre>
     </li>
 
index cc91154..cb0b10c 100644 (file)
@@ -47,7 +47,7 @@
   </p>
   <p>
     <strong>Executing groovy scripts on Jalview startup</strong><br>
-    The -groovy &lt;script&gt; option on the <a href="commandline.html">
+    The --groovy &lt;script&gt; option on the <a href="commandline.html">
       Jalview command line</a> will execute the contents of &lt;script&gt;.
     &lt;script&gt; may be a file, a URL, or alternatively if it is
     &quot;STDIN&quot; then the standard input will be used.<br> <em>Note:
@@ -76,7 +76,7 @@
           window which is currently being looked at by the user</li>
       </ul></li>
     <li><strong>currentAlFrame</strong> - this is only defined when
-      running a Groovy script via the -groovy command line argument. It
+      running a Groovy script via the --groovy command line argument. It
       returns the first alignment window created after acting on the
       other arguments passed on the command line.</li>
   </ul>
index 7b699eb..ffc9fa7 100755 (executable)
@@ -109,7 +109,7 @@ VCF_ASSEMBLY=assembly19=GRCh37,hs37=GRCh37</pre><br /> <br />These allow
   </ol>
   <strong>Work in Progress!</strong>
   <p>VCF support in Jalview is under active development. Please get
-    in touch via our mailing list if you have any questions, problems or
+    in touch via our discussion forum if you have any questions, problems or
     otherwise find it useful !</p>
 </body>
 </html>
index 04216da..c940373 100755 (executable)
     </li>
 
   </ul>
-  <a name="htmlexport" />
   <p>
+    <strong>PNG Export Options</strong>
+  
+  <p>
+    <em>Since Jalview 2.11.3</em> it is possible to specify options when <a
+      href="../features/clarguments-reference.html#exportingimagefiles">exporting
+      figures via the command line</a> to increase the resolution of the
+    exported PNG, and configure maximum width and height settings.
+  
+  <p>You can also configure default export settings by adding the
+    following lines to
+  
+  <pre>.jalview_properties</pre>
+  <pre>BITMAP_SCALE=&lt;Scale factor multiplied by 10&gt;
+  BITMAP_WIDTH=Width of export in pixels
+  BITMAP_HEIGHT=Height of figure export in pixels
+  </pre>
+  When scale is not set, the figure will be scaled to fit in the smallest
+  specified dimension. Scale will be ignored if it results in an image
+  dimension greater than the smallest specified dimension.
+  <p>
+  <a name="htmlexport" /><p>
     <strong>Exporting alignments as Web Pages</strong>
   <p>
     In Jalview 2.9, new HTML exporting options were introduced. The
index 4d7e2e3..a7da021 100644 (file)
   <p>
     For other queries or comments about Jalview, remember you can
     contact the Jalview team using email via the
-    <a href="https://www.jalview.org/mailman/listinfo/jalview-discuss">Jalview
-      discussion list</a>, on Twitter <a
+    <a href="https://discourse.jalview.org/">Jalview
+      Discussion Forum</a>, on Twitter <a
       href="https://twitter.com/Jalview/">@Jalview</a>, or for technical
     discussions, via the Jalview developer's chatroom at
     <a href="https://gitter.im/jalview/developers">https://gitter.im/jalview/developers</a>.
index ec57530..17dc557 100755 (executable)
       with a different percentage of physical memory available is to
       adjust your user preferences via the <a
       ref="preferences.html#startup">Startup Preferences</a> panel.</li>
+    <li>
+      <em><code>jalview</code> command line launch</em>
+      <br/>
+      When starting Jalview from a <a href="features/commandline.html">command line launch</a> you can use the memory setting arguments <a href="features/clarguments.html#jvmmemmax"><code>--jvmmemmax=MAXMEMORY</code></a> and <a href="features/clarguments.html#jvmmempc"><code>--jvmmempc=PERCENT</code></a>.  <code>MAXMEMORY</code> should be an integer optionally followed by one of <code>k</code>, <code>m</code>, <code>g</code>, <code>t</code>.  <code>PERCENT</code> should be an integer between 1 and 100.
+    </li>
     <li><em><font size="3">JVL file</font></em> <br />Another way
       to adjust launch settings is with a text file with extension <em>.jvl</em>
       and a single line to specify the percentage of memory you wish
       /PATH_TO_JALVIEW/Jalview /path/to/file/mymemorysetting.jvl /path/to/alignments/myalignment.fa</pre>
       Alternatively, you can use the standard Jalview command line
       arguments with or without the jvl file (first), e.g. <pre>
-       /PATH_TO_JALVIEW/Jalview /path/to/file/mymemorysetting.jvl -open https://www.jalview.org/examples/jpred_msa.fasta -annotations https://www.jalview.org/examples/jpred_msa.seq.concise -colour Clustal</pre>
+       /PATH_TO_JALVIEW/Jalview /path/to/file/mymemorysetting.jvl --open https://www.jalview.org/examples/jpred_msa.fasta --annotations https://www.jalview.org/examples/jpred_msa.seq.concise --colour Clustal</pre>
       You can use command line arguments to control memory settings in
       Windows and macOS too: <br /> In Windows you must use, e.g. <pre>
-      \PATH_TO_JALVIEW\Jalview.exe %HOMEPATH%\mymemorysetting.jvl -open %HOMEPATH%\myalignment.fa</pre>
+      \PATH_TO_JALVIEW\Jalview.exe %HOMEPATH%\mymemorysetting.jvl --open %HOMEPATH%\myalignment.fa</pre>
       In macOS you can use the macOS <em>open</em> command like this: <pre>
-      open /Applications/Jalview.app --args ~/mymemorysetting.jvl -open ~/myalignment.fa</pre><em>(put
+      open /Applications/Jalview.app --args ~/mymemorysetting.jvl --open ~/myalignment.fa</pre><em>(put
         all the Jalview arguments <em>after</em> the --args parameter)
     </em><br />
     <br /></li>
     </li>
     <li><em><font size="3"><a name="jar">Command line arguments when using the executable jar (jalview-all.jar) or jalview.bin.Launcher</a></em><br/>
       If you are using the Jalview standalone executable jar (usually named <em>jalview-all-....jar</em> with a Jalview and Java version designation) or using <em>jalview.bin.Launcher</em> to start Jalview,
-      then you can set the <em>jvmmempc</em> and <em>jvmmemmax</em> values using application command line arguments <em>-jvmmempc=PERCENT</em>
-      and <em>-jvmmemmax=MAXMEMORY</em> respectively.  <em>PERCENT</em> should be an integer between 1 and 100, and MAXMEMORY should be an amount of memory in bytes, or you can append a "k", "m", "g", or "t" to use units of kilobytes, megabytes, gigabytes or terabytes, e.g.
-      <pre>java -jar jalview-all-2.11.1.0-j1.8.jar -jvmmempc=50 -jvmmemmax=20g</pre>
+      then you can set the <em>jvmmempc</em> and <em>jvmmemmax</em> values using application command line arguments <em>--jvmmempc=PERCENT</em>
+      and <em>--jvmmemmax=MAXMEMORY</em> respectively.  <em>PERCENT</em> should be an integer between 1 and 100, and MAXMEMORY should be an amount of memory in bytes, or you can append a "k", "m", "g", or "t" to use units of kilobytes, megabytes, gigabytes or terabytes, e.g.
+      <pre>java -jar jalview-all-2.11.1.0-j1.8.jar --jvmmempc=50 --jvmmemmax=20g</pre>
       (this example will launch Jalview with a maximum heap size of the smaller of 20GB or 50% of physical memory detected).
       <br/>The default value for jvmmempc is 90, whilst the default value for jvmmemmax is 32g if Jalview can determine a total physical memory size of the host system, and a more cautious 8g if Jalview is unable to determine a total physical memory size.
       <br/><br/>
index 6534d2d..fef5bb9 100755 (executable)
           and the intensity threshold for transition between them. </em></li>
       <li>Colour Scheme options: <strong>None, ClustalX,
           Blosum62 Score, Percentage Identity, Zappo, Taylor,
-         gecos:flower, gecos:blossom, gecos:sunset, gecos:ocean,
+         gecos-flower, gecos-blossom, gecos-sunset, gecos-ocean,
           Hydrophobicity, Helix Propensity, Strand Propensity, Turn
           Propensity, Buried Index, Nucleotide, Nucleotide Ambiguity, Purine/Pyrimidine, User
           Defined<br>
index 5b8d00b..33da749 100755 (executable)
@@ -38,7 +38,7 @@
         the intensity threshold for transition between them. </em></li>
     <li>Colour Scheme options: <strong>None, ClustalX,
         Blosum62 Score, Percentage Identity, Zappo, Taylor,
-       gecos:flower, gecos:blossom, gecos:sunset, gecos:ocean,
+       gecos-flower, gecos-blossom, gecos-sunset, gecos-ocean,
         Hydrophobicity, Helix Propensity, Strand Propensity, Turn
         Propensity, Buried Index, Nucleotide, Nucleotide Ambiguity, Purine/Pyrimidine, User
         Defined<br>
index 9ad61b5..8704ce8 100644 (file)
   <p>Usage data is collected from the logs of various web services
     that the Jalview Desktop contacts through its normal operation.
     These are described below:</p>
-  <ul>
-    <li><em>HTTP logs on the Jalview website</em><br> We
-      record IP addresses of machines which access the web site, either
-      via the browser when downloading the application, or when the
-      Jalview Desktop user interface is launched.<br> <br>
-      <ul>
-        <li><i>The Jalview Getdown Launcher</i> (Since 2.11.0) examines release
-          channels every time Jalview launches to determine if a new
-          release is available.</li>
-        <li><i>The questionnaire web service at
-            www.jalview.org/cgi-bin/questionnaire.pl is checked and a
-            unique cookie for the current questionnaire is stored in the
-            Jalview properties file.</i></li>
-        <li><i>The Jalview web services stack is contacted to
-            retrieve the currently available web services. All
-            interactions with the public Jalview web services are
-            logged, but we delete all job data (input data and results)
-            after about two weeks.</i></li>
-      </ul> <br></li>
-    <li><em>Google Analytics</em><br> Since Jalview 2.4.0b2,
-      the Jalview Desktop records usage data with Google Analytics via
-      the <a href="http://code.google.com/p/jgoogleanalytics/">JGoogleAnalytics</a>
-      class.<br> The Google Analytics logs for Jalview version 2.4
-      only record the fact that the application was started, but in the
-      future, we will use this mechanism to improve the Desktop user
-      interface, by tracking which parts of the user interface are being
-      used most often.</li>
-  </ul>
-  </p>
+       <ul>
+               <li><em>HTTP logs on the Jalview website</em><br> We record
+                       IP addresses of machines which access the web site, either via the
+                       browser when downloading the application, or when the Jalview Desktop
+                       user interface is launched.<br> <br>
+                       <ul>
+                               <li><i>The Jalview Getdown Launcher</i> (Since 2.11.0) examines
+                                       release channels every time Jalview launches to determine if a new
+                                       release is available.</li>
+                               <li><i>The questionnaire web service at
+                                               www.jalview.org/cgi-bin/questionnaire.pl is checked and a unique
+                                               cookie for the current questionnaire is stored in the Jalview
+                                               properties file.</i></li>
+                               <li><i>The Jalview web services stack is contacted to
+                                               retrieve the currently available web services. All interactions
+                                               with the public Jalview web services are logged, but we delete all
+                                               job data (input data and results) after about two weeks.</i></li>
+                       </ul> <br></li>
+               <li><em>Usage Analytics</em><br> Since Jalview 2.11.2.7, the
+                       Jalview Desktop records usage data with a self-hosted instance of the
+                       analytics stack <a href="https://plausible.io">Plausible.io</a> via a
+                       custom GPLv3 client developed by Ben Soares. Prior to this, Jalview
+                       versions as far back as 2.4 recorded application launches via <a
+                       href="http://code.google.com/p/jgoogleanalytics/">JGoogleAnalytics</a>
+                       .<br> Usage logs for Jalview record the fact that the
+                       application was started, and details about the OS, installed Jalview
+                       launcher (if any) and java version used. In the future, we will use
+                       this mechanism to improve the Desktop user interface, by tracking
+                       which parts of the user interface are being used most often.</li>
+       </ul>
   <p>
     <strong>Stopping Jalview from calling home</strong><br> If you
     run Jalview in 'headless mode' via the command line, then the
diff --git a/help/help/icons/jalview_docs_logo.png b/help/help/icons/jalview_docs_logo.png
new file mode 100644 (file)
index 0000000..21f5386
Binary files /dev/null and b/help/help/icons/jalview_docs_logo.png differ
diff --git a/help/markdown/releases/release-2_11_2_7.md b/help/markdown/releases/release-2_11_2_7.md
new file mode 100644 (file)
index 0000000..361d39a
--- /dev/null
@@ -0,0 +1,12 @@
+---
+version: 2.11.2.7
+date: 2023-06-30
+channel: "release"
+---
+
+## New Features
+- <!-- JAL-4001 --> Jalview now reports usage statistics via Plausible.io
+
+## Issues Resolved
+- <!-- JAL-4116 --> PDB structures slow to view when Jalview Java console is open
+- <!-- JAL-4216 --> chains in PDB or mmCIF files with negative RESNUMs not correctly parsed
index 46de783..0fa114d 100644 (file)
@@ -1,6 +1,6 @@
 ---
 version: 2.11.3.0
-date: 2023-03-07
+date: 2023-07-19
 channel: "release"
 ---
 
@@ -8,41 +8,92 @@ channel: "release"
 - <!-- JAL-4064 --> Native M1 build for macOS using Adoptium JRE 11 macos-aarch64
 - <!-- JAL-4054 --> Installers built with install4j10
 - <!-- JAL-3676 --> Allow log level configuration via Jalview's Java Console, and a Copy to Clipboard button
-- <!-- JAL-3416 --> FlatLAF default look and feel on Linux, OSX and everywhere else ?
+- <!-- JAL-3416 --> FlatLAF default look and feel on Linux, OSX and everywhere else
 
 - <!-- JAL-4019 --> Ambiguous Base Colourscheme
 - <!-- JAL-4061 --> Find can search sequence features' type and description
 - <!-- JAL-4062 --> Hold down Shift + CMD/CTRL C to copy highlighted regions as new sequences
+- <!-- JAL-1556 --> Quickly enable select and/or colour by for displayed annotation row via its popup menu
+- <!-- JAL-4094 --> Shift+Click+Drag to adjust height of all annotation tracks of same type
+- <!-- JAL-4190 --> Pressing escape in tree panel clears any current selection
+
 - <!-- JAL-4089 --> Use selected columns for superposition
 - <!-- JAL-4086 --> Highlight aligned positions on all associated structures when mousing over a column
 
+- <!-- JAL-4221 --> sequence descriptions are updated from database reference sources if not already defined
+- <!-- JAL-4273 --> Visible adjuster marks to grab and adjust annotation panel height and id width
+- <!-- JAL-4260 --> Adjustable ID margin when alignment is wrapped
+
+- <!-- JAL-4274 --> Command line options and configurable bitmap export preferences for height, width and scale factor
+
+### Improved support for working with computationally determined models
+
 - <!-- JAL-3895 --> Alphafold red/orange/yellow/green colourscheme for structures
 - <!-- JAL-4095 --> Interactive picking of low pAE score regions
 - <!-- JAL-4027 --> contact matrix datatype in Jalview
 - <!-- JAL-4033 --> Selections with visual feedback via contact matrix annotation
 
-- <!-- JAL-4075 --> Don't add string label version of DSSP secondary structure codes in secondary structure annotation rows
 - <!-- JAL-3855 --> Discover and import alphafold2 models and metadata from https://alphafold.ebi.ac.uk/
 
-- <!-- JAL-2961 --> Jmol view not always centred on structures when multiple structures are viewed
+- <!-- JAL-4091 --> Visual indication of relationship with associated sequence to distinguish different sequence associated annotation rows
+- <!-- JAL-4123 --> GUI and command line allows configuration of how temperature factor in imported 3D structure data should be interpreted
+- <!-- JAL-3914 --> Import model reliability scores encoded as temperature factor annotation with their correct name and semantics
+- <!-- JAL-3858 --> Import and display alphafold alignment uncertainty matrices from JSON
+- <!-- JAL-4134,JAL-4158 --> Column-wise alignment groups and selections and interactive tree viewer for PAE matrices
+- <!-- JAL-4124 --> Store/Restore PAE data and visualisation settings from Jalview Project
+- <!-- JAL-4083 --> Multiple residue sidechain highlighting in structure viewers from PAE mouseovers
 
-- <!-- JAL-2528, JAL-1713 --> Overview window is saved in project file, and state of 'show hidden regions' is preserved.
 
+### Jalview on the command line
+
+- <!-- JAL-4160,JAL-629 --> New command line argument framework allowing flexible batch processing, figure generation, and import of structures, pae matrices and other sequence associated data
+- <!-- JAL-4121 --> Assume --headless when jalview is run with a command line argument that generates output
+- <!-- JAL-244 --> Automatically adjust Left margin on import to avoid cropping of annotation labels & sequence IDs
+- <!-- JAL-901 --> Specify alignment title on import via --title argument
+
+### Other improvements
+
+
+- <!-- JAL-4250 --> Secondary structure annotation glyphs are rendered anti-aliasing when enabled
+- <!-- JAL-325 --> Helix and Sheet glyphs vertically centered with respect to grey coil secondary structure annotation track
+- <!-- JAL-4253 --> Lower line of the sequence group border does not align with vertical and background residue box
+- <!-- JAL-4250 --> Updated JFreeSVG (https://www.jfree.org/jfreesvg) from 2.1 to 3.4.3
 - <!-- JAL-3119 --> Name of alignment and view included in overview window's title
+- <!-- JAL-4213 --> "add reference annotation" add all positions in reference annotation tracks, not just positions in the currently highlighted columns/selection range
+- <!-- JAL-4119 --> EMBL-EBI SIFTS file downloads now use split directories
 
-- <!-- JAL-4091 --> Visual indication of relationship with associated sequence to distinguish different sequence associated annotation rows
-- <!-- JAL-4094 --> Shift+Click+Drag to adjust height of all annotation tracks of same type
+- <!-- JAL-4195,JAL-4194,JAL-4193 --> sensible responses from the CLI when things go wrong during image export
+Add a command line option to set Jalview properties for this session only
+Add a command line option to suppress opening the startup file for this session
 
 
+JAL-4187        Powershell launcher script fails when given no arguments with the old ArgsParser
+
+known issue ? <!-- JAL-4127    --> 'Reload' for a jalview project results in all windows being duplicated
+
+
+- <!-- JAL-3830 --> Command-line wrapper script for macOS bundle, linux and Windows installations (bash, powershell and .bat wrappers)
+- <!-- JAL-3820 --> In Linux desktops' task-managers, the grouped Jalview windows get a generic name
+- <!-- JAL-4206 --> Improved file chooser's 'recent files' view and added filter for 'All known alignment files'
+- <!-- JAL-4206 --> Relative files added to recent files list via import from command line are selected when Jalview opened from same location
+
+       
 ## Still in progress (delete on release)
 
 - <!-- JAL-2382 --> Import and display sequence-associated contact predictions in CASP-RR format
 - <!-- JAL-2349 --> Contact prediction visualisation
 - <!-- JAL-2348 --> modularise annotation renderer
 
+### Development and Deployment
+
+- <!-- JAL-4167 --> Create separate gradle test task for some tests
+- <!-- JAL-4212 --> Prevent gradle test on macOS continuously grabbing focus
+- <!-- JAL-4111 --> Allow gradle build to create suffixed DEVELOP-... builds with channel appbase
+- <!-- JAL-4243 --> Jalview bio.tools description maintained under jalview's git repo and bundled with source release
 
 
 ## Issues Resolved
+- <!-- JAL-2961 --> Jmol view not always centred on structures when multiple structures are viewed
 - <!-- JAL-3776 --> Cancelling interactive calculation leaves empty progress bar.
 - <!-- JAL-3772 --> Unsaved Alignment windows close without prompting to save, individually or at application quit.
 - <!-- JAL-1988 --> Can quit Jalview while 'save project' is in progress
@@ -50,4 +101,28 @@ channel: "release"
 - <!-- JAL-4116 --> PDB structures slow to view when Jalview Java Console is open (2.11.2.7 patch)
 - <!-- JAL-3784 --> Multiple overview windows can be opened for a particular alignment view when multiple views are present
 - <!-- JAL-3785 --> Overview windows opened automatically (due to preferences settings) lack title
-- <!-- JAL-2353 --> Show Crossrefs fails to retrieve CDS from ENA or Ensembl for sequences retrieved from Uniprot due to version numbers in cross-reference accession
\ No newline at end of file
+- <!-- JAL-2353 --> Show Crossrefs fails to retrieve CDS from ENA or Ensembl for sequences retrieved from Uniprot due to version numbers in cross-reference accession
+- <!-- JAL-4184 --> Stockholm export does not include sequence descriptions
+- <!-- JAL-4075 --> Don't add string label version of DSSP secondary structure codes in secondary structure annotation rows
+- <!-- JAL-4182 --> reference annotation not correctly transferred to alignment containing a sub-sequence when a selection is active
+- <!-- JAL-4177 --> Can press 'Add' or 'New View' multiple times when manually adding and viewing a 3D structure via structure chooser
+- <!-- JAL-4133 --> Jalview project does not preserve font aspect ratio when Viewport is zoomed with mouse
+- <!-- JAL-4128 --> Resizing overview quickly with solid-drags enabled causes exception
+- <!-- JAL-4150 --> Sequences copied to clipboard from within Jalview cannot be pasted via the desktop's popup menu to a new alignment window
+- <!-- JAL-2528, JAL-1713 --> Overview window is saved in project file, and state of 'show hidden regions' is preserved.
+- <!-- JAL-4153 --> JvCacheableInputBoxTest flaky on build server
+- <!-- JAL-4255 --> SLF4J produces an error to STDERR at Jalview startup due to missing class
+- <!-- JAL-4189 --> macOS Dock and KDE taskbar names Jalview icon "java" when running
+- <!-- JAL-2910 --> HeadlessException in console in headless mode (actually fixed in 2.11.{0,1,2))
+
+
+## New Known defects
+- <!-- JAL-4178 --> Cannot cancel structure view open action once it has been started via the structure chooser dialog
+- <!-- JAL-4142 --> Example project's multiple views do not open in distinct locations when eXpand views is used to show them all separately
+- <!-- JAL-4165 --> Missing last letter when copying consensus sequence from alignment if first column is hidden
+- <!-- JAL-4261 --> Last sequence ID in alignment not shown and annotation labels are misaligned in HTML export
+- <!-- JAL-3024 --> Files opened via command line with a relative path are added as relative paths to Recent files list (since 2.0.x)
+
+
+
+
diff --git a/help/markdown/whatsnew/whatsnew-2_11_2_7.md b/help/markdown/whatsnew/whatsnew-2_11_2_7.md
new file mode 100644 (file)
index 0000000..f884134
--- /dev/null
@@ -0,0 +1,5 @@
+Jalview 2.11.2.7 is a minor patch release - it includes patches affecting efficiency when importing structures and a small revision to the import processing of structures with negative residue numbering. 
+
+With this release, Jalview usage statistics are now collected by a jalview.org hosted instance of the open source privacy-preserving analytics stack, Plausible.io. 
+
+
index 59495d5..ec82f83 100644 (file)
@@ -1,5 +1,7 @@
 The 2.11.3 series includes support for in-depth exploration of predicted alignment error matrices from AlphaFold in the context of multiple alignments, along with support for standard colourschemes for shading models according to their pLDDT.
 
+We're launching this release at ISMB 2023 - come find us !
+
 It also introduces new support for native ARM-based OSX architectures, and a few other goodies!
 
 
diff --git a/j11lib/JGoogleAnalytics_0.3.jar b/j11lib/JGoogleAnalytics_0.3.jar
deleted file mode 100644 (file)
index 0dbc98c..0000000
Binary files a/j11lib/JGoogleAnalytics_0.3.jar and /dev/null differ
diff --git a/j11lib/flatlaf-3.0.jar b/j11lib/flatlaf-3.0.jar
deleted file mode 100644 (file)
index 75d90d3..0000000
Binary files a/j11lib/flatlaf-3.0.jar and /dev/null differ
diff --git a/j11lib/flatlaf-3.2.jar b/j11lib/flatlaf-3.2.jar
new file mode 100644 (file)
index 0000000..450c1e8
Binary files /dev/null and b/j11lib/flatlaf-3.2.jar differ
diff --git a/j11lib/flatlaf-extras-3.0.jar b/j11lib/flatlaf-extras-3.0.jar
deleted file mode 100644 (file)
index 1f6bbc3..0000000
Binary files a/j11lib/flatlaf-extras-3.0.jar and /dev/null differ
diff --git a/j11lib/flatlaf-extras-3.2.jar b/j11lib/flatlaf-extras-3.2.jar
new file mode 100644 (file)
index 0000000..ccdbf94
Binary files /dev/null and b/j11lib/flatlaf-extras-3.2.jar differ
index 5c98d23..fb8f1bc 100644 (file)
Binary files a/j11lib/getdown-core.jar and b/j11lib/getdown-core.jar differ
diff --git a/j11lib/jfreesvg-2.1.jar b/j11lib/jfreesvg-2.1.jar
deleted file mode 100644 (file)
index 91d453c..0000000
Binary files a/j11lib/jfreesvg-2.1.jar and /dev/null differ
diff --git a/j11lib/jfreesvg-3.4.3.jar b/j11lib/jfreesvg-3.4.3.jar
new file mode 100644 (file)
index 0000000..cfd1463
Binary files /dev/null and b/j11lib/jfreesvg-3.4.3.jar differ
diff --git a/j11lib/slf4j-api-1.7.32.jar b/j11lib/slf4j-api-1.7.32.jar
deleted file mode 100644 (file)
index b16a078..0000000
Binary files a/j11lib/slf4j-api-1.7.32.jar and /dev/null differ
diff --git a/j11lib/slf4j-api-1.7.36.jar b/j11lib/slf4j-api-1.7.36.jar
new file mode 100644 (file)
index 0000000..7d3ce68
Binary files /dev/null and b/j11lib/slf4j-api-1.7.36.jar differ
diff --git a/j11lib/slf4j-nop-1.7.36.jar b/j11lib/slf4j-nop-1.7.36.jar
new file mode 100644 (file)
index 0000000..734ad96
Binary files /dev/null and b/j11lib/slf4j-nop-1.7.36.jar differ
diff --git a/j8lib/JGoogleAnalytics_0.3.jar b/j8lib/JGoogleAnalytics_0.3.jar
deleted file mode 100644 (file)
index 0dbc98c..0000000
Binary files a/j8lib/JGoogleAnalytics_0.3.jar and /dev/null differ
diff --git a/j8lib/flatlaf-3.0.jar b/j8lib/flatlaf-3.0.jar
deleted file mode 100644 (file)
index 75d90d3..0000000
Binary files a/j8lib/flatlaf-3.0.jar and /dev/null differ
diff --git a/j8lib/flatlaf-3.2.jar b/j8lib/flatlaf-3.2.jar
new file mode 100644 (file)
index 0000000..450c1e8
Binary files /dev/null and b/j8lib/flatlaf-3.2.jar differ
diff --git a/j8lib/flatlaf-extras-3.0.jar b/j8lib/flatlaf-extras-3.0.jar
deleted file mode 100644 (file)
index 1f6bbc3..0000000
Binary files a/j8lib/flatlaf-extras-3.0.jar and /dev/null differ
diff --git a/j8lib/flatlaf-extras-3.2.jar b/j8lib/flatlaf-extras-3.2.jar
new file mode 100644 (file)
index 0000000..ccdbf94
Binary files /dev/null and b/j8lib/flatlaf-extras-3.2.jar differ
index 5c98d23..fb8f1bc 100644 (file)
Binary files a/j8lib/getdown-core.jar and b/j8lib/getdown-core.jar differ
diff --git a/j8lib/jfreesvg-2.1.jar b/j8lib/jfreesvg-2.1.jar
deleted file mode 100644 (file)
index 91d453c..0000000
Binary files a/j8lib/jfreesvg-2.1.jar and /dev/null differ
diff --git a/j8lib/jfreesvg-3.4.3.jar b/j8lib/jfreesvg-3.4.3.jar
new file mode 100644 (file)
index 0000000..cfd1463
Binary files /dev/null and b/j8lib/jfreesvg-3.4.3.jar differ
diff --git a/j8lib/slf4j-api-1.7.32.jar b/j8lib/slf4j-api-1.7.32.jar
deleted file mode 100644 (file)
index b16a078..0000000
Binary files a/j8lib/slf4j-api-1.7.32.jar and /dev/null differ
diff --git a/j8lib/slf4j-api-1.7.36.jar b/j8lib/slf4j-api-1.7.36.jar
new file mode 100644 (file)
index 0000000..7d3ce68
Binary files /dev/null and b/j8lib/slf4j-api-1.7.36.jar differ
diff --git a/j8lib/slf4j-nop-1.7.36.jar b/j8lib/slf4j-nop-1.7.36.jar
new file mode 100644 (file)
index 0000000..734ad96
Binary files /dev/null and b/j8lib/slf4j-nop-1.7.36.jar differ
index 271454a..0c4f165 100644 (file)
@@ -220,10 +220,10 @@ label.colourScheme_nucleotideambiguity = Nucleotide Ambiguity
 label.colourScheme_t-coffeescores = T-Coffee Scores
 label.colourScheme_rnahelices = By RNA Helices
 label.colourScheme_sequenceid = Sequence ID Colour
-label.colourScheme_gecos\:flower = gecos Flower
-label.colourScheme_gecos\:blossom = gecos Blossom
-label.colourScheme_gecos\:sunset = gecos Sunset
-label.colourScheme_gecos\:ocean = gecos Ocean
+label.colourScheme_gecos-flower = gecos Flower
+label.colourScheme_gecos-blossom = gecos Blossom
+label.colourScheme_gecos-sunset = gecos Sunset
+label.colourScheme_gecos-ocean = gecos Ocean
 label.blc = BLC
 label.fasta = Fasta
 label.msf = MSF
@@ -363,6 +363,7 @@ label.sequences_from = Sequences from {0}
 label.successfully_loaded_file  = Successfully loaded file {0}
 label.successfully_loaded_matrix  = Successfully loaded score matrix {0}
 label.successfully_saved_to_file_in_format = Successfully saved to file: {0} in {1} format.
+label.successfully_printed_to_stdout_in_format = Successfully printed to STDOUT in {0} format.
 label.copied_sequences_to_clipboard = Copied {0} sequences to clipboard.
 label.check_file_matches_sequence_ids_alignment = Check that the file matches sequence IDs in the alignment.
 label.problem_reading_tcoffee_score_file = Problem reading T-COFFEE score file
@@ -449,6 +450,7 @@ label.input_cut_paste_params = Cut & Paste Input - {0}
 label.alignment_output_command = Alignment output - {0}
 label.annotations = Annotations
 label.structure_options = Structure Options
+label.structure_import_options = Structure Import Options
 label.features = Features
 label.overview_params = Overview {0}
 label.paste_newick_file = Paste Newick file
@@ -702,7 +704,7 @@ label.sequence_details_for = Sequence Details for {0}
 label.sequence_name = Sequence Name
 label.sequence_description = Sequence Description
 label.edit_sequence_name_description = Edit Sequence Name/Description
-label.spaces_converted_to_underscores = Spaces have been converted to _
+label.spaces_converted_to_underscores = Spaces have been converted to underscores (_)
 label.no_spaces_allowed_sequence_name = No spaces allowed in Sequence Name
 label.select_outline_colour = Select Outline Colour
 label.web_browser_not_found_unix = Unixers\: Couldn't find default web browser.\nAdd the full path to your browser in Preferences."
@@ -1448,5 +1450,17 @@ label.tftype_default = Default
 label.tftype_plddt = pLDDT
 label.optional = (optional)
 label.choose_tempfac_type = Choose Temperature Factor type
+label.interpret_tempfac_as = Interpret Temperature Factor as
 label.add_pae_matrix_file = Add PAE matrix file
 label.nothing_selected = Nothing selected
+prompt.analytics_title = Jalview Usage Statistics
+prompt.analytics = Do you want to help make Jalview better by enabling the collection of usage statistics with Plausible analytics?\nYou can enable or disable usage tracking in the preferences.
+label.working_ellipsis = Working ... 
+action.show_groups_on_matrix = Show groups on matrix
+action.show_groups_on_matrix_tooltip = When enabled, clusters defined on the matrix's associated tree or below the assigned threshold are shown as different colours on the matrix annotation row
+action.show_tree_for_matrix = Show tree for matrix
+action.show_tree_for_matrix_tooltip = Opens a tree viewer to display the average distance tree for the matrix
+action.cluster_matrix = Cluster matrix
+action.clustering_matrix_for = Calculating tree for matrix {0} and clustering at {1}
+action.cluster_matrix_tooltip = Computes an average distance tree for the matrix and displays it
+label.all_known_alignment_files = All known alignment files
index c427104..1f256cb 100644 (file)
@@ -211,10 +211,10 @@ label.colourScheme_nucleotideambiguity = Ambig
 label.colourScheme_t-coffeescores = Puntuación del T-Coffee
 label.colourScheme_rnahelices = Por hélices de RNA
 label.colourScheme_sequenceid = Color de ID de secuencia
-label.colourScheme_gecos\:flower = gecos Flower
-label.colourScheme_gecos\:blossom = gecos Blossom
-label.colourScheme_gecos\:sunset = gecos Sunset
-label.colourScheme_gecos\:ocean = gecos Ocean
+label.colourScheme_gecos-flower = gecos Flower
+label.colourScheme_gecos-blossom = gecos Blossom
+label.colourScheme_gecos-sunset = gecos Sunset
+label.colourScheme_gecos-ocean = gecos Ocean
 label.blc = BLC
 label.fasta = Fasta
 label.msf = MSF
@@ -326,6 +326,7 @@ label.sequences_from = Secuencias de {0}
 label.successfully_loaded_file  = Fichero cargado exitosamente {0}
 label.successfully_loaded_matrix  = Matriz cargada exitosamente {0}
 label.successfully_saved_to_file_in_format = Guardado exitosamente en el fichero: {0} en formato {1}.
+label.successfully_printed_to_stdout_in_format = Impresso exitosamente al STDOUT en formato {0}.
 label.copied_sequences_to_clipboard = Copiadas {0} secuencias en el portapapeles.
 label.check_file_matches_sequence_ids_alignment = Comprobar que el fichero coincide con el ID de la secuencia en el alineamiento.
 label.problem_reading_tcoffee_score_file = Problema de lectura del fichero de puntuaciones T-COFFEE
@@ -640,7 +641,7 @@ label.sequence_details_for = Detalles de la secuencia para {0}
 label.sequence_name = Nombre de la secuencia
 label.sequence_description = Descripción de la secuencia
 label.edit_sequence_name_description = Editar el nombre/descripción de la secuencia
-label.spaces_converted_to_underscores = Los espacios se han convertido en _
+label.spaces_converted_to_underscores = Los espacios se han convertido en guión bajos (_)
 label.no_spaces_allowed_sequence_name = No se permiten espacios en el nombre de la secuencia
 label.select_outline_colour = Seleccionar el color del límite
 label.web_browser_not_found_unix = Unixers\: No es posible encontrar el navegador web por defecto.\nA\u00F1ada la ruta completa de su navegador en la pesta\u00F1a de Preferencias.
@@ -1434,3 +1435,6 @@ label.tftype_default = Default
 label.tftype_plddt = pLDDT
 label.add_pae_matrix_file = Añadir un fichero de matriz PAE
 label.nothing_selected = Nada seleccionado
+prompt.analytics_title = Jalview Estadísticas de Uso
+prompt.analytics = ¿Quiere ayudar a mejorar Jalview habilitando la recopilación de estadísticas de uso con análisis Plausible?\nPuede habilitar o deshabilitar el seguimiento de uso en las preferencias.
+label.all_known_alignment_files = Todos los archivos de alineación conocidos
index abfabb1..fedbae3 100755 (executable)
                        <xs:element name="groups" type="xs:string" minOccurs="0"
                                maxOccurs="unbounded">
                                <xs:annotation>
-                                       <xs:documentation>Comma separated series of BigIntegers formed from
+                                       <xs:documentation>Comma separated series of longs formed from
                                                bitsets defining partitions on the rows/columns of the matrix
                                        </xs:documentation>
                                </xs:annotation>
                        </xs:element>
                        <xs:element name="property" type="vamsas:property"
                                minOccurs="0" maxOccurs="unbounded" />
+                       <xs:element name="mapping" type="vamsas:mapListType"
+                               minOccurs="0" maxOccurs="1">
+                       <xs:annotation>
+                               <xs:documentation>mapping from the matrix row and column positions to
+                                       associated reference frame</xs:documentation>
+                               </xs:annotation>
+                       </xs:element>
                </xs:sequence>
 
                <xs:attribute name="type" type="xs:string" use="required" />
index b1505d6..6967885 100755 (executable)
@@ -147,7 +147,7 @@ public class AAFrequency
       {
         if (sequences[row] == null)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "WARNING: Consensus skipping null sequence - possible race condition.");
           continue;
         }
@@ -188,7 +188,7 @@ public class AAFrequency
     }
     return new Profiles(result);
     // long elapsed = System.currentTimeMillis() - now;
-    // System.out.println(elapsed);
+    // jalview.bin.Console.outPrintln(elapsed);
   }
 
   /**
@@ -285,7 +285,7 @@ public class AAFrequency
               ' ', value);
     }
     // long elapsed = System.currentTimeMillis() - now;
-    // System.out.println(-elapsed);
+    // jalview.bin.Console.outPrintln(-elapsed);
   }
 
   /**
index 65fd110..e1d5669 100755 (executable)
@@ -826,7 +826,7 @@ public class AlignSeq
       }
     }
 
-    System.out.println(max + " " + min);
+    jalview.bin.Console.outPrintln(max + " " + min);
 
     for (int i = 0; i < n; i++)
     {
@@ -835,12 +835,12 @@ public class AlignSeq
         int x = psize * i;
         int y = psize * j;
 
-        // System.out.println(mat[i][j]);
+        // jalview.bin.Console.outPrintln(mat[i][j]);
         float score = (float) (mat[i][j] - min) / (float) (max - min);
         g.setColor(new Color(score, 0, 0));
         g.fillRect(x, y, psize, psize);
 
-        // System.out.println(x + " " + y + " " + score);
+        // jalview.bin.Console.outPrintln(x + " " + y + " " + score);
       }
     }
   }
@@ -890,7 +890,8 @@ public class AlignSeq
         pdbpos++;
       }
 
-      if (allowmismatch || c1 == c2)
+      // ignore case differences
+      if (allowmismatch || (c1 == c2) || (Math.abs(c2-c1)==('a'-'A')))
       {
         // extend mapping interval
         if (lp1 + 1 != alignpos || lp2 + 1 != pdbpos)
@@ -982,7 +983,7 @@ public class AlignSeq
             bestm = msq;
           }
         }
-        // System.out.println("Best Score for " + (matches.size() + 1) + " :"
+        // jalview.bin.Console.outPrintln("Best Score for " + (matches.size() + 1) + " :"
         // + bestscore);
         matches.add(bestm);
         aligns.add(bestaseq);
index 0f3edfd..b037336 100755 (executable)
@@ -453,7 +453,7 @@ public class AlignmentSorter
 
       if (tmp.size() != nSeq)
       {
-        System.err.println("WARNING: tmp.size()=" + tmp.size() + " != nseq="
+        jalview.bin.Console.errPrintln("WARNING: tmp.size()=" + tmp.size() + " != nseq="
                 + nSeq
                 + " in getOrderByTree - tree contains sequences not in alignment");
       }
@@ -548,7 +548,9 @@ public class AlignmentSorter
 
     if ((left == null) && (right == null))
     {
-      if (!(node instanceof SequenceNode && ((SequenceNode)node).isPlaceholder()) && (node.element() != null))
+      if (!(node instanceof SequenceNode
+              && ((SequenceNode) node).isPlaceholder())
+              && (node.element() != null))
       {
         if (node.element() instanceof SequenceI)
         {
@@ -712,7 +714,7 @@ public class AlignmentSorter
       String msg = String.format(
               "Implementation Error - sortByFeature method must be either '%s' or '%s'",
               FEATURE_SCORE, FEATURE_DENSITY);
-      System.err.println(msg);
+      jalview.bin.Console.errPrintln(msg);
       return;
     }
 
@@ -830,7 +832,7 @@ public class AlignmentSorter
           {
             // int nf = (feats[i] == null) ? 0
             // : ((SequenceFeature[]) feats[i]).length;
-            // // System.err.println("Sorting on Score: seq " +
+            // // jalview.bin.Console.errPrintln("Sorting on Score: seq " +
             // seqs[i].getName()
             // + " Feats: " + nf + " Score : " + scores[i]);
           }
@@ -845,7 +847,7 @@ public class AlignmentSorter
         int featureCount = feats[i] == null ? 0
                 : ((SequenceFeature[]) feats[i]).length;
         scores[i] = featureCount;
-        // System.err.println("Sorting on Density: seq "+seqs[i].getName()+
+        // jalview.bin.Console.errPrintln("Sorting on Density: seq "+seqs[i].getName()+
         // " Feats: "+featureCount+" Score : "+scores[i]);
       }
       QuickSort.sortByDouble(scores, seqs, sortByFeatureAscending);
index 0906872..f470dc6 100644 (file)
@@ -184,10 +184,10 @@ public class AlignmentUtils
       // TODO use Character.toLowerCase to avoid creating String objects?
       char[] upstream = new String(ds
               .getSequence(s.getStart() - 1 - ustream_ds, s.getStart() - 1))
-              .toLowerCase(Locale.ROOT).toCharArray();
+                      .toLowerCase(Locale.ROOT).toCharArray();
       char[] downstream = new String(
               ds.getSequence(s_end - 1, s_end + dstream_ds))
-              .toLowerCase(Locale.ROOT).toCharArray();
+                      .toLowerCase(Locale.ROOT).toCharArray();
       char[] coreseq = s.getSequence();
       char[] nseq = new char[offset + upstream.length + downstream.length
               + coreseq.length];
@@ -547,7 +547,7 @@ public class AlignmentUtils
       if (translated == null || !(aaRes == translated.charAt(0)))
       {
         // debug
-        // System.out.println(("Mismatch at " + i + "/" + aaResidue + ": "
+        // jalview.bin.Console.outPrintln(("Mismatch at " + i + "/" + aaResidue + ": "
         // + codon + "(" + translated + ") != " + aaRes));
         return false;
       }
@@ -698,7 +698,7 @@ public class AlignmentUtils
          * unmapped position; treat like a gap
          */
         sourceGapMappedLength += ratio;
-        // System.err.println("Can't align: no codon mapping to residue "
+        // jalview.bin.Console.errPrintln("Can't align: no codon mapping to residue "
         // + sourceDsPos + "(" + sourceChar + ")");
         // return;
         continue;
@@ -883,7 +883,7 @@ public class AlignmentUtils
   {
     if (protein.isNucleotide() || !dna.isNucleotide())
     {
-      System.err.println("Wrong alignment type in alignProteinAsDna");
+      jalview.bin.Console.errPrintln("Wrong alignment type in alignProteinAsDna");
       return 0;
     }
     List<SequenceI> unmappedProtein = new ArrayList<>();
@@ -908,7 +908,7 @@ public class AlignmentUtils
   {
     if (protein.isNucleotide() || !dna.isNucleotide())
     {
-      System.err.println("Wrong alignment type in alignProteinAsDna");
+      jalview.bin.Console.errPrintln("Wrong alignment type in alignProteinAsDna");
       return 0;
     }
     // todo: implement this
@@ -988,7 +988,7 @@ public class AlignmentUtils
                           .getLength() == mappedFromLength - 1);
           if (cdsLength != mappedToLength && !addStopCodon)
           {
-            System.err.println(String.format(
+            jalview.bin.Console.errPrintln(String.format(
                     "Can't align cds as protein (length mismatch %d/%d): %s",
                     cdsLength, mappedToLength, cdsSeq.getName()));
           }
@@ -1162,7 +1162,7 @@ public class AlignmentUtils
         AlignedCodon codon = sequenceCodon.getValue();
         if (codon.peptideCol > 1)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Problem mapping protein with >1 unmapped start positions: "
                           + seq.getName());
         }
@@ -1471,19 +1471,20 @@ public class AlignmentUtils
          */
         final Iterable<AlignmentAnnotation> matchedAlignmentAnnotations = al
                 .findAnnotations(seq, dsann.getCalcId(), dsann.label);
-        boolean found=false;
+        boolean found = false;
         if (matchedAlignmentAnnotations != null)
         {
-          for (AlignmentAnnotation matched:matchedAlignmentAnnotations)
+          for (AlignmentAnnotation matched : matchedAlignmentAnnotations)
           {
             if (dsann.description.equals(matched.description))
             {
-              found=true;
+              found = true;
               break;
             }
           }
         }
-        if (!found) {
+        if (!found)
+        {
           result.add(dsann);
           if (labelForCalcId != null)
           {
@@ -1503,14 +1504,15 @@ public class AlignmentUtils
 
   /**
    * Adds annotations to the top of the alignment annotations, in the same order
-   * as their related sequences.
+   * as their related sequences. If you already have an annotation and want to
+   * add it to a sequence in an alignment use {@code addReferenceAnnotationTo}
    * 
    * @param annotations
    *          the annotations to add
    * @param alignment
    *          the alignment to add them to
    * @param selectionGroup
-   *          current selection group (or null if none)
+   *          current selection group - may be null, if provided then any added annotation will be trimmed to just those columns in the selection group
    */
   public static void addReferenceAnnotations(
           Map<SequenceI, List<AlignmentAnnotation>> annotations,
@@ -1520,38 +1522,60 @@ public class AlignmentUtils
     {
       for (AlignmentAnnotation ann : annotations.get(seq))
       {
-        AlignmentAnnotation copyAnn = new AlignmentAnnotation(ann);
-        int startRes = 0;
-        int endRes = ann.annotations.length;
-        if (selectionGroup != null)
-        {
-          startRes = selectionGroup.getStartRes();
-          endRes = selectionGroup.getEndRes();
-        }
-        copyAnn.restrict(startRes, endRes + 0);
+        addReferenceAnnotationTo(alignment, seq, ann, selectionGroup);
+      }
+    }
+  }
 
-        /*
-         * Add to the sequence (sets copyAnn.datasetSequence), unless the
-         * original annotation is already on the sequence.
-         */
-        if (!seq.hasAnnotation(ann))
-        {
-          ContactMatrixI cm = seq.getDatasetSequence()
-                  .getContactMatrixFor(ann);
-          if (cm != null)
-          {
-            seq.addContactListFor(copyAnn, cm);
-          }
-          seq.addAlignmentAnnotation(copyAnn);
-        }
-        // adjust for gaps
-        copyAnn.adjustForAlignment();
-        // add to the alignment and set visible
-        alignment.addAnnotation(copyAnn);
-        copyAnn.visible = true;
+  /**
+   * Make a copy of a reference annotation {@code ann} and add it to an
+   * alignment sequence {@code seq} in {@code alignment}, optionally limited to
+   * the extent of {@code selectionGroup}
+   * 
+   * @param alignment
+   * @param seq
+   * @param ann
+   * @param selectionGroup
+   *          current selection group - may be null, if provided then any added annotation will be trimmed to just those columns in the selection group
+   * @return annotation added to {@code seq and {@code alignment}
+   */
+  public static AlignmentAnnotation addReferenceAnnotationTo(
+          final AlignmentI alignment, final SequenceI seq,
+          final AlignmentAnnotation ann, final SequenceGroup selectionGroup)
+  {
+    AlignmentAnnotation copyAnn = new AlignmentAnnotation(ann);
+    int startRes = 0;
+    int endRes = ann.annotations.length;
+    if (selectionGroup != null)
+    {
+      startRes = -1 + Math.min(seq.getEnd(), Math.max(seq.getStart(),
+              seq.findPosition(selectionGroup.getStartRes())));
+      endRes = -1 + Math.min(seq.getEnd(),
+              seq.findPosition(selectionGroup.getEndRes()));
+
+    }
+    copyAnn.restrict(startRes, endRes + 0);
+
+    /*
+     * Add to the sequence (sets copyAnn.datasetSequence), unless the
+     * original annotation is already on the sequence.
+     */
+    if (!seq.hasAnnotation(ann))
+    {
+      ContactMatrixI cm = seq.getDatasetSequence().getContactMatrixFor(ann);
+      if (cm != null)
+      {
+        seq.addContactListFor(copyAnn, cm);
       }
+      seq.addAlignmentAnnotation(copyAnn);
     }
+    // adjust for gaps
+    copyAnn.adjustForAlignment();
+    // add to the alignment and set visible
+    alignment.addAnnotation(copyAnn);
+    copyAnn.visible = true;
 
+    return copyAnn;
   }
 
   /**
@@ -2746,7 +2770,7 @@ public class AlignmentUtils
                 fromRange[i + 1]);
         if (range == null)
         {
-          System.err.println("Error in mapping " + seqMap + " from "
+          jalview.bin.Console.errPrintln("Error in mapping " + seqMap + " from "
                   + fromSeq.getName());
           return false;
         }
index 0f0cf68..1f2e78f 100644 (file)
@@ -157,12 +157,13 @@ public class AnnotationSorter
         return showAutocalcAbove ? 1 : -1;
       }
       int computedOrder = compareSequences(o1, o2);
-      if (computedOrder==0) {
+      if (computedOrder == 0)
+      {
         computedOrder = compareLabels(o1, o2);
       }
-      if (computedOrder==0)
+      if (computedOrder == 0)
       {
-        computedOrder = compareDescriptions(o1,o2);
+        computedOrder = compareDescriptions(o1, o2);
       }
       return computedOrder;
     }
@@ -365,18 +366,19 @@ public class AnnotationSorter
     }
     String label1 = o1.label;
     String label2 = o2.label;
-    return compareString(label1,label2);
+    return compareString(label1, label2);
   }
 
   /**
-   * Non-case-sensitive comparison of annotation descriptions. Returns zero if either
-   * argument is null.
+   * Non-case-sensitive comparison of annotation descriptions. Returns zero if
+   * either argument is null.
    * 
    * @param o1
    * @param o2
    * @return
    */
-  private int compareDescriptions(AlignmentAnnotation o1, AlignmentAnnotation o2)
+  private int compareDescriptions(AlignmentAnnotation o1,
+          AlignmentAnnotation o2)
   {
     if (o1 == null || o2 == null)
     {
@@ -384,8 +386,9 @@ public class AnnotationSorter
     }
     String label1 = o1.description;
     String label2 = o2.description;
-    return compareString(label1,label2);
+    return compareString(label1, label2);
   }
+
   private int compareString(String label1, String label2)
   {
     if (label1 == null && label2 == null)
index e6a763b..d81dd44 100644 (file)
@@ -44,29 +44,31 @@ public class AverageDistanceEngine extends TreeEngine
 
   AlignmentAnnotation aa;
 
+  // 0 - normalised dot product
+  // 1 - L1 - ie (abs(v_1-v_2)/dim(v))
+  // L1 is more rational - since can reason about value of difference,
+  // normalised dot product might give cleaner clusters, but more difficult to
+  // understand.
+
+  int mode = 1;
+
   /**
    * compute cosine distance matrix for a given contact matrix and create a
    * UPGMA tree
-   * 
    * @param cm
+   * @param cosineOrDifference false - dot product : true - L1
    */
   public AverageDistanceEngine(AlignmentViewport av, AlignmentAnnotation aa,
-          ContactMatrixI cm)
+          ContactMatrixI cm, boolean cosineOrDifference)
   {
     this.av = av;
     this.aa = aa;
     this.cm = cm;
+    mode = (cosineOrDifference) ? 1 :0; 
     calculate(cm);
 
   }
 
-  // 0 - normalised dot product
-  // 1 - L1 - ie (abs(v_1-v_2)/dim(v))
-  // L1 is more rational - since can reason about value of difference,
-  // normalised dot product might give cleaner clusters, but more difficult to
-  // understand.
-
-  int mode = 1;
 
   public void calculate(ContactMatrixI cm)
   {
@@ -100,11 +102,18 @@ public class AverageDistanceEngine extends TreeEngine
 
       // compute distance matrix element
       ContactListI ith = cm.getContactList(i);
-
+      distances.setValue(i, i, 0);
+      if (ith==null)
+      {
+        continue;
+      }
       for (int j = 0; j < i; j++)
       {
-        distances.setValue(i, i, 0);
         ContactListI jth = cm.getContactList(j);
+        if (jth == null)
+        {
+          break;
+        }
         double prd = 0;
         for (int indx = 0; indx < cm.getHeight(); indx++)
         {
index cbc4dca..5bb0b09 100755 (executable)
@@ -243,13 +243,13 @@ public class Conservation
       }
       else
       {
-        System.out.println("SEQUENCE HAS BEEN DELETED!!!");
+        jalview.bin.Console.outPrintln("SEQUENCE HAS BEEN DELETED!!!");
       }
     }
     else
     {
       // JBPNote INFO level debug
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "ERROR: calcSeqNum called with out of range sequence index for Alignment\n");
     }
   }
@@ -711,7 +711,7 @@ public class Conservation
       // tmp = ((max - tmp) * (size - cons2[j][23])) / size;
       tmp = ((max - tmp) * (size - cons2GapCounts[j])) / size;
 
-      // System.out.println(tmp+ " " + j);
+      // jalview.bin.Console.outPrintln(tmp+ " " + j);
       quality.setElementAt(Double.valueOf(tmp), j);
 
       if (tmp > newmax)
index 9b90ca5..41582b4 100644 (file)
@@ -293,7 +293,7 @@ public class CrossRef
             if (matchInDataset != null && xref.getMap().getTo() != null
                     && matchInDataset != xref.getMap().getTo())
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Implementation problem (reopen JAL-2154): CrossRef.findInDataset seems to have recovered a different sequence than the one explicitly mapped for xref."
                               + "Found:" + matchInDataset + "\nExpected:"
                               + xref.getMap().getTo() + "\nFor xref:"
@@ -424,7 +424,7 @@ public class CrossRef
       retrieved = sftch.getSequences(sourceRefs, !fromDna);
     } catch (Exception e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Problem whilst retrieving cross references for Sequence : "
                       + seq.getName());
       e.printStackTrace();
@@ -607,7 +607,7 @@ public class CrossRef
                 String msg = "Mapping updated from " + ms.getName()
                         + " to retrieved crossreference "
                         + matched.getName();
-                System.out.println(msg);
+                jalview.bin.Console.outPrintln(msg);
 
                 List<DBRefEntry> toRefs = map.getTo().getDBRefs();
                 if (toRefs != null)
@@ -662,7 +662,7 @@ public class CrossRef
               cf.addMap(retrievedSequence, map.getTo(), map.getMap());
             } catch (Exception e)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Exception when consolidating Mapped sequence set...");
               e.printStackTrace(System.err);
             }
@@ -1029,7 +1029,7 @@ public class CrossRef
     }
     if (dataset.getSequences() == null)
     {
-      System.err.println("Empty dataset sequence set - NO VECTOR");
+      jalview.bin.Console.errPrintln("Empty dataset sequence set - NO VECTOR");
       return false;
     }
     List<SequenceI> ds = dataset.getSequences();
@@ -1041,7 +1041,7 @@ public class CrossRef
         {
           if (nxt.getDatasetSequence() != null)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Implementation warning: CrossRef initialised with a dataset alignment with non-dataset sequences in it! ("
                             + nxt.getDisplayId(true) + " has ds reference "
                             + nxt.getDatasetSequence().getDisplayId(true)
index 5dcf212..aa71eb7 100644 (file)
@@ -653,7 +653,7 @@ public class Dna
       if (rf != 0)
       {
         final String errMsg = "trimming contigs for incomplete terminal codon.";
-        System.err.println(errMsg);
+        jalview.bin.Console.errPrintln(errMsg);
         // map and trim contigs to ORF region
         vc = scontigs.length - 1;
         lastnpos = vismapping.shift(lastnpos); // place npos in context of
index 133cb3a..4c826b2 100644 (file)
@@ -140,7 +140,7 @@ public final class GeneticCodes
       InputStream is = getClass().getResourceAsStream(fileName);
       if (is == null)
       {
-        System.err.println("Resource file not found: " + fileName);
+        jalview.bin.Console.errPrintln("Resource file not found: " + fileName);
         return;
       }
       BufferedReader dataIn = new BufferedReader(new InputStreamReader(is));
@@ -166,7 +166,7 @@ public final class GeneticCodes
     }
     if (codeTables.isEmpty())
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "No genetic code tables loaded, check format of file "
                       + fileName);
     }
@@ -190,7 +190,7 @@ public final class GeneticCodes
       InputStream is = getClass().getResourceAsStream(fileName);
       if (is == null)
       {
-        System.err.println("Resource file not found: " + fileName);
+        jalview.bin.Console.errPrintln("Resource file not found: " + fileName);
         return;
       }
       BufferedReader dataIn = new BufferedReader(new InputStreamReader(is));
@@ -208,7 +208,7 @@ public final class GeneticCodes
           }
           else
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Unexpected data in " + fileName + ": " + line);
           }
         }
index 066814e..def5d5a 100644 (file)
@@ -269,7 +269,7 @@ public class Grouping
      * seqs.length) { for (int i = 0; i < seqs.length; i++) { if (!hasScore[i])
      * { scores[i] = (max + i); } else { int nf=(feats[i]==null) ? 0
      * :((SequenceFeature[]) feats[i]).length;
-     * System.err.println("Sorting on Score: seq "+seqs[i].getName()+
+     * jalview.bin.Console.errPrintln("Sorting on Score: seq "+seqs[i].getName()+
      * " Feats: "+nf+" Score : "+scores[i]); } } }
      * 
      * jalview.util.QuickSort.sort(scores, seqs); } else if
@@ -280,7 +280,7 @@ public class Grouping
      * (int i=0;i<seqs.length; i++) { double nf; scores[i] =
      * (0.05+fr*i)+(nf=((feats[i]==null) ? 0.0 :1.0*((SequenceFeature[])
      * feats[i]).length));
-     * System.err.println("Sorting on Density: seq "+seqs[i].getName()+
+     * jalview.bin.Console.errPrintln("Sorting on Density: seq "+seqs[i].getName()+
      * " Feats: "+nf+" Score : "+scores[i]); }
      * jalview.util.QuickSort.sort(scores, seqs); } else { if
      * (method==FEATURE_LABEL) { throw new Error("Not yet implemented."); } } if
index 4b68d93..94b7b99 100644 (file)
@@ -145,7 +145,7 @@ public class ParseProperties
                   ScoreNames[cols] + ((reps > 0) ? "_" + reps : ""),
                   ScoreDescriptions[cols], null);
           an.setScore(score);
-          System.out.println(seqs[i].getName() + " score: '"
+          jalview.bin.Console.outPrintln(seqs[i].getName() + " score: '"
                   + ScoreNames[cols] + "' = " + score); // DEBUG
           an.setSequenceRef(seqs[i]);
           seqs[i].addAlignmentAnnotation(an);
index 9649240..911ee04 100644 (file)
@@ -421,8 +421,8 @@ public class Rna
       final int open = basePair.getBP5();
       final int close = basePair.getBP3();
 
-      // System.out.println("open " + open + " close " + close);
-      // System.out.println("lastclose " + lastclose + " lastopen " + lastopen);
+      // jalview.bin.Console.outPrintln("open " + open + " close " + close);
+      // jalview.bin.Console.outPrintln("lastclose " + lastclose + " lastopen " + lastopen);
 
       // we're moving from right to left based on closing pair
       /*
@@ -441,7 +441,7 @@ public class Rna
       {
         int popen = bps.get(j).getBP5();
 
-        // System.out.println("j " + j + " popen " + popen + " lastopen "
+        // jalview.bin.Console.outPrintln("j " + j + " popen " + popen + " lastopen "
         // +lastopen + " open " + open);
         if ((popen < lastopen) && (popen > open))
         {
index fdca89d..837462f 100755 (executable)
@@ -129,7 +129,7 @@ public class SeqsetUtils
     {
       if (sfeatures != null)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Implementation error: setting dataset sequence for a sequence which has sequence features.\n\tDataset sequence features will not be visible.");
       }
       sq.setDatasetSequence(seqds);
@@ -244,7 +244,7 @@ public class SeqsetUtils
         {
           if (!quiet)
           {
-            System.err.println("Can't find '" + ((String) key)
+            jalview.bin.Console.errPrintln("Can't find '" + ((String) key)
                     + "' in uniquified alignment");
           }
         }
@@ -252,7 +252,7 @@ public class SeqsetUtils
     }
     if (unmatched.size() > 0 && !quiet)
     {
-      System.err.println("Did not find matches for :");
+      jalview.bin.Console.errPrintln("Did not find matches for :");
       for (Enumeration i = unmatched.elements(); i
               .hasMoreElements(); System.out
                       .println(((SequenceI) i.nextElement()).getName()))
index c04df6c..3f5099b 100644 (file)
@@ -148,7 +148,7 @@ public class StructureFrequency
           {
             if (sequences[j] == null)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "WARNING: Consensus skipping null sequence - possible race condition.");
               continue;
             }
index daf7836..a7cbc25 100644 (file)
@@ -214,7 +214,7 @@ public abstract class TreeEngine
   {
     // if (_lycount<_lylimit)
     // {
-    // System.err.println("Warning: depth of _recount greater than number of
+    // jalview.bin.Console.errPrintln("Warning: depth of _recount greater than number of
     // nodes.");
     // }
     if (nd == null)
index dd56424..90fe089 100644 (file)
@@ -80,7 +80,7 @@ public class TreeModel
   public TreeModel(SequenceI[] seqs, AlignmentView odata,
           NewickFile treefile)
   {
-    this(seqs,  treefile.getTree(), treefile.HasDistances(),
+    this(seqs, treefile.getTree(), treefile.HasDistances(),
             treefile.HasBootstrap(), treefile.HasRootDistance());
     seqData = odata;
 
@@ -94,7 +94,7 @@ public class TreeModel
    */
   public TreeModel(TreeBuilder tree)
   {
-    this(tree.getSequences(),  tree.getTopNode(), tree.hasDistances(),
+    this(tree.getSequences(), tree.getTopNode(), tree.hasDistances(),
             tree.hasBootstrap(), tree.hasRootDistance());
     seqData = tree.getOriginalData();
   }
@@ -141,7 +141,7 @@ public class TreeModel
     while (i < leaves.size())
     {
       // TODO - decide if we get rid of the polymorphism here ?
-      j = (SequenceNode)leaves.elementAt(i++);
+      j = (SequenceNode) leaves.elementAt(i++);
       realnam = j.getName();
       nam = null;
 
@@ -311,8 +311,7 @@ public class TreeModel
    * 
    * @return Vector of leaf nodes on binary tree
    */
-  Vector<BinaryNode> findLeaves(BinaryNode nd,
-          Vector<BinaryNode> leaves)
+  Vector<BinaryNode> findLeaves(BinaryNode nd, Vector<BinaryNode> leaves)
   {
     if (nd == null)
     {
@@ -354,13 +353,13 @@ public class TreeModel
 
     if ((nd.left() == null) && (nd.right() == null))
     {
-      System.out.println("Leaf = " + ((SequenceI) nd.element()).getName());
-      System.out.println("Dist " + nd.dist);
-      System.out.println("Boot " + nd.getBootstrap());
+      jalview.bin.Console.outPrintln("Leaf = " + ((SequenceI) nd.element()).getName());
+      jalview.bin.Console.outPrintln("Dist " + nd.dist);
+      jalview.bin.Console.outPrintln("Boot " + nd.getBootstrap());
     }
     else
     {
-      System.out.println("Dist " + nd.dist);
+      jalview.bin.Console.outPrintln("Dist " + nd.dist);
       printNode((BinaryNode) nd.left());
       printNode((BinaryNode) nd.right());
     }
@@ -409,8 +408,8 @@ public class TreeModel
     }
     else
     {
-      _groupNodes(groups, (SequenceNode) nd.left(), threshold);
-      _groupNodes(groups, (SequenceNode) nd.right(), threshold);
+      _groupNodes(groups, nd.left(), threshold);
+      _groupNodes(groups, nd.right(), threshold);
     }
   }
 
@@ -481,10 +480,10 @@ public class TreeModel
     }
     else
     {
-      System.out.println(" name = " + ((SequenceI) nd.element()).getName());
+      jalview.bin.Console.outPrintln(" name = " + ((SequenceI) nd.element()).getName());
     }
 
-    System.out.println(
+    jalview.bin.Console.outPrintln(
             " dist = " + nd.dist + " " + nd.count + " " + nd.height);
   }
 
@@ -514,7 +513,7 @@ public class TreeModel
   {
     // if (_lycount<_lylimit)
     // {
-    // System.err.println("Warning: depth of _recount greater than number of
+    // jalview.bin.Console.errPrintln("Warning: depth of _recount greater than number of
     // nodes.");
     // }
     if (nd == null)
index 9c2f6d1..bcc0855 100644 (file)
@@ -63,7 +63,7 @@ public class FeatureDistanceModel extends DistanceScoreModel
       return instance;
     } catch (InstantiationException | IllegalAccessException e)
     {
-      System.err.println("Error in " + getClass().getName()
+      jalview.bin.Console.errPrintln("Error in " + getClass().getName()
               + ".getInstance(): " + e.getMessage());
       return null;
     } catch (ReflectiveOperationException roe)
index b206339..aa841ac 100644 (file)
@@ -331,12 +331,12 @@ public class ScoreMatrix extends SimilarityScoreModel
   {
     if (c >= symbolIndex.length)
     {
-      System.err.println(String.format(BAD_ASCII_ERROR, c));
+      jalview.bin.Console.errPrintln(String.format(BAD_ASCII_ERROR, c));
       return 0;
     }
     if (d >= symbolIndex.length)
     {
-      System.err.println(String.format(BAD_ASCII_ERROR, d));
+      jalview.bin.Console.errPrintln(String.format(BAD_ASCII_ERROR, d));
       return 0;
     }
 
index ebc9a26..d0f21bd 100644 (file)
@@ -105,7 +105,7 @@ public class ScoreModels
       return sm;
     } catch (IOException e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error reading " + resourcePath + ": " + e.getMessage());
     }
     return null;
@@ -143,7 +143,7 @@ public class ScoreModels
     ScoreModelI sm2 = models.get(sm.getName());
     if (sm2 != null)
     {
-      System.err.println("Warning: replacing score model " + sm2.getName());
+      jalview.bin.Console.errPrintln("Warning: replacing score model " + sm2.getName());
     }
     models.put(sm.getName(), sm);
   }
diff --git a/src/jalview/analytics/Plausible.java b/src/jalview/analytics/Plausible.java
new file mode 100644 (file)
index 0000000..ab2de77
--- /dev/null
@@ -0,0 +1,602 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.analytics;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.lang.invoke.MethodHandles;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import jalview.bin.Cache;
+import jalview.bin.Console;
+import jalview.util.ChannelProperties;
+import jalview.util.HttpUtils;
+
+public class Plausible
+{
+  private static final String USER_AGENT;
+
+  private static final String JALVIEW_ID = "Jalview Desktop";
+
+  private static final String DOMAIN = "jalview.org";
+
+  private static final String CONFIG_API_BASE_URL = "https://www.jalview.org/services/config/analytics/url";
+
+  private static final String DEFAULT_API_BASE_URL = "https://analytics.jalview.org/api/event";
+
+  private static final String API_BASE_URL;
+
+  private static final String clientId;
+
+  public static final String APPLICATION_BASE_URL = "desktop://localhost";
+
+  private List<Map.Entry<String, String>> queryStringValues;
+
+  private List<Map.Entry<String, Object>> jsonObject;
+
+  private List<Map.Entry<String, String>> cookieValues;
+
+  private static boolean ENABLED = false;
+
+  private static boolean DEBUG = true;
+
+  private static Plausible instance = null;
+
+  private static final Map<String, String> defaultProps;
+
+  static
+  {
+    defaultProps = new HashMap<>();
+    defaultProps.put("app_name",
+            ChannelProperties.getProperty("app_name") + " Desktop");
+    defaultProps.put("version", Cache.getProperty("VERSION"));
+    defaultProps.put("build_date",
+            Cache.getDefault("BUILD_DATE", "unknown"));
+    defaultProps.put("java_version", System.getProperty("java.version"));
+    String val = System.getProperty("sys.install4jVersion");
+    if (val != null)
+    {
+      defaultProps.put("install4j_version", val);
+    }
+    val = System.getProperty("installer_template_version");
+    if (val != null)
+    {
+      defaultProps.put("install4j_template_version", val);
+    }
+    val = System.getProperty("launcher_version");
+    if (val != null)
+    {
+      defaultProps.put("launcher_version", val);
+    }
+    defaultProps.put("java_arch",
+            System.getProperty("os.arch") + " "
+                    + System.getProperty("os.name") + " "
+                    + System.getProperty("os.version"));
+    defaultProps.put("os", System.getProperty("os.name"));
+    defaultProps.put("os_version", System.getProperty("os.version"));
+    defaultProps.put("os_arch", System.getProperty("os.arch"));
+    String installation = Cache.applicationProperties
+            .getProperty("INSTALLATION");
+    if (installation != null)
+    {
+      defaultProps.put("installation", installation);
+    }
+
+    // ascertain the API_BASE_URL
+    API_BASE_URL = getAPIBaseURL();
+
+    // random clientId to make User-Agent unique (to register analytic)
+    clientId = String.format("%08x", new Random().nextInt());
+
+    USER_AGENT = HttpUtils.getUserAgent(
+            MethodHandles.lookup().lookupClass().getCanonicalName() + " "
+                    + clientId);
+  }
+
+  private Plausible()
+  {
+    this.resetLists();
+  }
+
+  public static void setEnabled(boolean b)
+  {
+    ENABLED = b;
+  }
+
+  public void sendEvent(String eventName, String urlString,
+          String... propsStrings)
+  {
+    sendEvent(eventName, urlString, false, propsStrings);
+  }
+
+  /**
+   * The simplest way to send an analytic event.
+   * 
+   * @param eventName
+   *          The event name. To emulate a webpage view use "pageview" and set a
+   *          "url" key/value. See https://plausible.io/docs/events-api
+   * @param sendDefaultProps
+   *          Flag whether to add the default props about the application.
+   * @param propsStrings
+   *          Optional multiple Strings in key, value pairs (there should be an
+   *          even number of propsStrings) to be set as property of the event.
+   *          To emulate a webpage view set "url" as the URL in a "pageview"
+   *          event.
+   */
+  public void sendEvent(String eventName, String urlString,
+          boolean sendDefaultProps, String... propsStrings)
+  {
+    // clear out old lists
+    this.resetLists();
+
+    if (!ENABLED)
+    {
+      Console.debug("Plausible not enabled.");
+      return;
+    }
+    Map<String, String> props = new HashMap<>();
+
+    // add these to all events from this application instance
+    if (sendDefaultProps)
+    {
+      props.putAll(defaultProps);
+    }
+
+    // add (and overwrite with) the passed in props
+    if (propsStrings != null && propsStrings.length > 0)
+    {
+      if (propsStrings.length % 2 != 0)
+      {
+        Console.warn(
+                "Cannot addEvent with odd number of propsStrings.  Ignoring the last one.");
+      }
+      for (int i = 0; i < propsStrings.length - 1; i += 2)
+      {
+        String key = propsStrings[i];
+        String value = propsStrings[i + 1];
+        props.put(key, value);
+      }
+    }
+
+    addJsonValue("domain", DOMAIN);
+    addJsonValue("name", eventName);
+    StringBuilder eventUrlSb = new StringBuilder(APPLICATION_BASE_URL);
+    if (!APPLICATION_BASE_URL.endsWith("/") && !urlString.startsWith("/"))
+    {
+      eventUrlSb.append("/");
+    }
+    eventUrlSb.append(urlString);
+    addJsonValue("url", eventUrlSb.toString());
+    addJsonObject("props", props);
+    StringBuilder urlSb = new StringBuilder();
+    urlSb.append(API_BASE_URL);
+    String qs = buildQueryString();
+    if (qs != null && qs.length() > 0)
+    {
+      urlSb.append('?');
+      urlSb.append(qs);
+    }
+    try
+    {
+      URL url = new URL(urlSb.toString());
+      URLConnection urlConnection = url.openConnection();
+      HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
+      httpURLConnection.setRequestMethod("POST");
+      httpURLConnection.setDoOutput(true);
+
+      String jsonString = buildJson();
+
+      Console.debug(
+              "Plausible: HTTP Request is: '" + urlSb.toString() + "'");
+      if (DEBUG)
+      {
+        Console.debug("Plausible: User-Agent is: '" + USER_AGENT + "'");
+      }
+      Console.debug("Plausible: POSTed JSON is:\n" + jsonString);
+
+      byte[] jsonBytes = jsonString.getBytes(StandardCharsets.UTF_8);
+      int jsonLength = jsonBytes.length;
+
+      httpURLConnection.setFixedLengthStreamingMode(jsonLength);
+      httpURLConnection.setRequestProperty("Content-Type",
+              "application/json");
+      httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
+      httpURLConnection.connect();
+      try (OutputStream os = httpURLConnection.getOutputStream())
+      {
+        os.write(jsonBytes);
+      }
+      int responseCode = httpURLConnection.getResponseCode();
+      String responseMessage = httpURLConnection.getResponseMessage();
+
+      if (responseCode < 200 || responseCode > 299)
+      {
+        Console.warn("Plausible connection failed: '" + responseCode + " "
+                + responseMessage + "'");
+      }
+      else
+      {
+        Console.debug("Plausible connection succeeded: '" + responseCode
+                + " " + responseMessage + "'");
+      }
+
+      if (DEBUG)
+      {
+        BufferedReader br = new BufferedReader(new InputStreamReader(
+                (httpURLConnection.getInputStream())));
+        StringBuilder sb = new StringBuilder();
+        String response;
+        while ((response = br.readLine()) != null)
+        {
+          sb.append(response);
+        }
+        String body = sb.toString();
+        Console.debug("Plausible response content:\n" + body);
+      }
+    } catch (MalformedURLException e)
+    {
+      Console.debug(
+              "Somehow the Plausible BASE_URL and queryString is malformed: '"
+                      + urlSb.toString() + "'",
+              e);
+      return;
+    } catch (IOException e)
+    {
+      Console.debug("Connection to Plausible BASE_URL '" + API_BASE_URL
+              + "' failed.", e);
+    } catch (ClassCastException e)
+    {
+      Console.debug(
+              "Couldn't cast URLConnection to HttpURLConnection in Plausible.",
+              e);
+    }
+  }
+
+  private void addJsonObject(String key, Map<String, String> map)
+  {
+    List<Map.Entry<String, ? extends Object>> list = new ArrayList<>();
+    for (String k : map.keySet())
+    {
+      list.add(stringEntry(k, map.get(k)));
+    }
+    addJsonObject(key, list);
+
+  }
+
+  private void addJsonObject(String key,
+          List<Map.Entry<String, ? extends Object>> object)
+  {
+    jsonObject.add(objectEntry(key, object));
+  }
+
+  private void addJsonValues(String key, List<Object> values)
+  {
+    jsonObject.add(objectEntry(key, values));
+  }
+
+  private void addJsonValue(String key, String value)
+  {
+    jsonObject.add(objectEntry(key, value));
+  }
+
+  private void addJsonValue(String key, int value)
+  {
+    jsonObject.add(objectEntry(key, Integer.valueOf(value)));
+  }
+
+  private void addJsonValue(String key, boolean value)
+  {
+    jsonObject.add(objectEntry(key, Boolean.valueOf(value)));
+  }
+
+  private void addQueryStringValue(String key, String value)
+  {
+    queryStringValues.add(stringEntry(key, value));
+  }
+
+  private void addCookieValue(String key, String value)
+  {
+    cookieValues.add(stringEntry(key, value));
+  }
+
+  private void resetLists()
+  {
+    jsonObject = new ArrayList<>();
+    queryStringValues = new ArrayList<>();
+    cookieValues = new ArrayList<>();
+  }
+
+  public static Plausible getInstance()
+  {
+    if (instance == null)
+    {
+      instance = new Plausible();
+    }
+    return instance;
+  }
+
+  public static void reset()
+  {
+    getInstance().resetLists();
+  }
+
+  private String buildQueryString()
+  {
+    StringBuilder sb = new StringBuilder();
+    for (Map.Entry<String, String> entry : queryStringValues)
+    {
+      if (sb.length() > 0)
+      {
+        sb.append('&');
+      }
+      try
+      {
+        sb.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
+      } catch (UnsupportedEncodingException e)
+      {
+        sb.append(entry.getKey());
+      }
+      sb.append('=');
+      try
+      {
+        sb.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
+      } catch (UnsupportedEncodingException e)
+      {
+        sb.append(entry.getValue());
+      }
+    }
+    return sb.toString();
+  }
+
+  private void buildCookieHeaders()
+  {
+    // TODO not needed yet
+  }
+
+  private String buildJson()
+  {
+    StringBuilder sb = new StringBuilder();
+    addJsonObject(sb, 0, jsonObject);
+    return sb.toString();
+  }
+
+  private void addJsonObject(StringBuilder sb, int indent,
+          List<Map.Entry<String, Object>> entries)
+  {
+    indent(sb, indent);
+    sb.append('{');
+    newline(sb);
+    Iterator<Map.Entry<String, Object>> entriesI = entries.iterator();
+    while (entriesI.hasNext())
+    {
+      Map.Entry<String, Object> entry = entriesI.next();
+      String key = entry.getKey();
+      // TODO sensibly escape " characters in key
+      Object value = entry.getValue();
+      indent(sb, indent + 1);
+      sb.append('"').append(quoteEscape(key)).append('"').append(':');
+      space(sb);
+      if (value != null && value instanceof List)
+      {
+        newline(sb);
+      }
+      addJsonValue(sb, indent + 2, value);
+      if (entriesI.hasNext())
+      {
+        sb.append(',');
+      }
+      newline(sb);
+    }
+    indent(sb, indent);
+    sb.append('}');
+  }
+
+  private void addJsonValue(StringBuilder sb, int indent, Object value)
+  {
+    if (value == null)
+    {
+      return;
+    }
+    try
+    {
+      if (value instanceof Map.Entry)
+      {
+        Map.Entry<String, Object> entry = (Map.Entry<String, Object>) value;
+        List<Map.Entry<String, Object>> object = new ArrayList<>();
+        object.add(entry);
+        addJsonObject(sb, indent, object);
+      }
+      else if (value instanceof List)
+      {
+        // list of Map.Entries or list of values?
+        List<Object> valueList = (List<Object>) value;
+        if (valueList.size() > 0 && valueList.get(0) instanceof Map.Entry)
+        {
+          // entries
+          // indent(sb, indent);
+          List<Map.Entry<String, Object>> entryList = (List<Map.Entry<String, Object>>) value;
+          addJsonObject(sb, indent, entryList);
+        }
+        else
+        {
+          // values
+          indent(sb, indent);
+          sb.append('[');
+          newline(sb);
+          Iterator<Object> valueListI = valueList.iterator();
+          while (valueListI.hasNext())
+          {
+            Object v = valueListI.next();
+            addJsonValue(sb, indent + 1, v);
+            if (valueListI.hasNext())
+            {
+              sb.append(',');
+            }
+            newline(sb);
+          }
+          indent(sb, indent);
+          sb.append("]");
+        }
+      }
+      else if (value instanceof String)
+      {
+        sb.append('"').append(quoteEscape((String) value)).append('"');
+      }
+      else if (value instanceof Integer)
+      {
+        sb.append(((Integer) value).toString());
+      }
+      else if (value instanceof Boolean)
+      {
+        sb.append('"').append(((Boolean) value).toString()).append('"');
+      }
+    } catch (ClassCastException e)
+    {
+      Console.debug(
+              "Could not deal with type of json Object " + value.toString(),
+              e);
+    }
+  }
+
+  private static String quoteEscape(String s)
+  {
+    if (s == null)
+    {
+      return null;
+    }
+    // this escapes quotation marks (") that aren't already escaped (in the
+    // string) ready to go into a quoted JSON string value
+    return s.replaceAll("((?<!\\\\)(?:\\\\{2})*)\"", "$1\\\\\"");
+  }
+
+  private static void prettyWhitespace(StringBuilder sb, String whitespace,
+          int repeat)
+  {
+    // only add whitespace if we're in DEBUG mode
+    if (!Console.getLogger().isDebugEnabled())
+    {
+      return;
+    }
+    if (repeat >= 0 && whitespace != null)
+    {
+      // sb.append(whitespace.repeat(repeat));
+      sb.append(String.join("", Collections.nCopies(repeat, whitespace)));
+
+    }
+    else
+    {
+      sb.append(whitespace);
+    }
+  }
+
+  private static void indent(StringBuilder sb, int indent)
+  {
+    prettyWhitespace(sb, "  ", indent);
+  }
+
+  private static void newline(StringBuilder sb)
+  {
+    prettyWhitespace(sb, "\n", -1);
+  }
+
+  private static void space(StringBuilder sb)
+  {
+    prettyWhitespace(sb, " ", -1);
+  }
+
+  protected static Map.Entry<String, Object> objectEntry(String s, Object o)
+  {
+    return new AbstractMap.SimpleEntry<String, Object>(s, o);
+  }
+
+  protected static Map.Entry<String, String> stringEntry(String s, String v)
+  {
+    return new AbstractMap.SimpleEntry<String, String>(s, v);
+  }
+
+  private static String getAPIBaseURL()
+  {
+    try
+    {
+      URL url = new URL(CONFIG_API_BASE_URL);
+      URLConnection urlConnection = url.openConnection();
+      HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
+      httpURLConnection.setRequestMethod("GET");
+      httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
+      httpURLConnection.setConnectTimeout(5000);
+      httpURLConnection.setReadTimeout(3000);
+      httpURLConnection.connect();
+      int responseCode = httpURLConnection.getResponseCode();
+      String responseMessage = httpURLConnection.getResponseMessage();
+
+      if (responseCode < 200 || responseCode > 299)
+      {
+        Console.warn("Config URL connection to '" + CONFIG_API_BASE_URL
+                + "' failed: '" + responseCode + " " + responseMessage
+                + "'");
+      }
+
+      BufferedReader br = new BufferedReader(
+              new InputStreamReader((httpURLConnection.getInputStream())));
+      StringBuilder sb = new StringBuilder();
+      String response;
+      while ((response = br.readLine()) != null)
+      {
+        sb.append(response);
+      }
+      if (sb.length() > 7 && sb.substring(0, 5).equals("https"))
+      {
+        return sb.toString();
+      }
+
+    } catch (MalformedURLException e)
+    {
+      Console.debug("Somehow the config URL is malformed: '"
+              + CONFIG_API_BASE_URL + "'", e);
+    } catch (IOException e)
+    {
+      Console.debug("Connection to Plausible BASE_URL '" + API_BASE_URL
+              + "' failed.", e);
+    } catch (ClassCastException e)
+    {
+      Console.debug(
+              "Couldn't cast URLConnection to HttpURLConnection in Plausible.",
+              e);
+    }
+    return DEFAULT_API_BASE_URL;
+  }
+}
index 3c266e5..ba3ed75 100644 (file)
@@ -478,6 +478,15 @@ public interface AlignViewportI extends ViewStyleI
    */
   SearchResultsI getSearchResults();
 
+  /**
+   * Retrieve a ContactListI corresponding to column in an annotation row in an
+   * alignment.
+   * 
+   * @param _aa
+   *          - annotation with associated matrix data
+   * @param column
+   *          - column in alignment where _aa is associated
+   */
   ContactListI getContactList(AlignmentAnnotation _aa, int column);
 
   /**
index c6eb6de..1646d89 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2b1)
- * Copyright (C) 2014 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
index 54f7fb6..d5d07ef 100644 (file)
  */
 package jalview.api;
 
+import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.seqfeatures.FeatureColourFinder;
 
 import java.awt.Color;
+import java.awt.Graphics;
 
 public interface SequenceRenderer
 {
@@ -31,4 +33,19 @@ public interface SequenceRenderer
   Color getResidueColour(SequenceI seq, int position,
           FeatureColourFinder finder);
 
+  /**
+   * Configure the Graphics canvas and render options for the renderer
+   * @param g - the canvas to render to
+   * @param renderGaps - when true, gap characters will be included when rendered
+   *          
+   */
+  void prepare(Graphics g, boolean renderGaps);
+
+  void drawSequence(SequenceI nextSeq, SequenceGroup[] findAllGroups,
+          int startRes, int endRes, int i);
+
+  void drawHighlightedText(SequenceI nextSeq, int i, int j, int k, int l);
+
+  void drawCursor(Graphics g, char s, int i, int j);
+
 }
index a1b92df..532e545 100644 (file)
  */
 package jalview.api.structures;
 
+import java.io.File;
+
 import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.StructureViewer;
 import jalview.structures.models.AAStructureBindingModel;
 
 public interface JalviewStructureDisplayI
@@ -172,4 +176,20 @@ public interface JalviewStructureDisplayI
    */
   boolean hasViewerActionsMenu();
 
+  String getViewId();
+
+  StructureViewer.ViewerType getViewerType();
+
+  boolean isUsedforaligment(AlignmentViewPanel ap);
+
+  boolean isColouredByViewer();
+
+  int getHeight();
+
+  int getWidth();
+
+  int getY();
+
+  File saveSession();
+
 }
index b860a36..413b0d4 100644 (file)
@@ -393,14 +393,14 @@ public class APopupMenu extends java.awt.PopupMenu
         urlLink = new UrlLink(link);
       } catch (Exception foo)
       {
-        System.err.println("Exception for URLLink '" + link + "': "
+        jalview.bin.Console.errPrintln("Exception for URLLink '" + link + "': "
                 + foo.getMessage());
         continue;
       }
 
       if (!urlLink.isValid())
       {
-        System.err.println(urlLink.getInvalidMessage());
+        jalview.bin.Console.errPrintln(urlLink.getInvalidMessage());
         continue;
       }
 
index 2a2fc70..4b858e1 100644 (file)
  */
 package jalview.appletgui;
 
+import java.awt.BorderLayout;
+import java.awt.Canvas;
+import java.awt.CheckboxMenuItem;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Label;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.Panel;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.jmol.viewer.Viewer;
+
 import jalview.analysis.AlignmentSorter;
 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.analysis.TreeBuilder;
@@ -81,45 +120,6 @@ import jalview.util.MessageManager;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.ViewportRanges;
 
-import java.awt.BorderLayout;
-import java.awt.Canvas;
-import java.awt.CheckboxMenuItem;
-import java.awt.Color;
-import java.awt.FlowLayout;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Frame;
-import java.awt.Graphics;
-import java.awt.Label;
-import java.awt.Menu;
-import java.awt.MenuBar;
-import java.awt.MenuItem;
-import java.awt.Panel;
-import java.awt.Rectangle;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-import org.jmol.viewer.Viewer;
-
 public class AlignFrame extends EmbmenuFrame implements ActionListener,
         ItemListener, KeyListener, AlignViewControllerGuiI
 {
@@ -1577,7 +1577,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     /*
      * When we finally deprecate 1.1 compatibility, we can start to use
      * URLEncoder.encode(url,"UTF-8") and then we'll need this catch: catch
-     * (UnsupportedEncodingException ex) { System.err.println("WARNING -
+     * (UnsupportedEncodingException ex) { jalview.bin.Console.errPrintln("WARNING -
      * IMPLEMENTATION ERROR - UNSUPPORTED ENCODING EXCEPTION FOR "+url);
      * ex.printStackTrace(); }
      */
@@ -1586,7 +1586,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       url = viewport.applet.getCodeBase() + url;
     } catch (UnsupportedEncodingException ex)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "WARNING = IMPLEMENTATION ERROR - UNSUPPORTED ENCODING EXCEPTION FOR "
                       + url);
       ex.printStackTrace();
@@ -2975,7 +2975,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
     if (viewport.applet.debug)
     {
-      System.err.println("Sorting " + alorder.getOrder().size()
+      jalview.bin.Console.errPrintln("Sorting " + alorder.getOrder().size()
               + " in alignment '" + getTitle() + "'");
     }
     AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
@@ -3061,7 +3061,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   {
     if (viewport.applet == null)
     {
-      System.out.println("Not running as applet - no browser available.");
+      jalview.bin.Console.outPrintln("Not running as applet - no browser available.");
     }
     else
     {
@@ -3977,12 +3977,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       viewer = (Viewer) jmolviewer;
     } catch (ClassCastException ex)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Unsupported viewer object :" + jmolviewer.getClass());
     }
     if (viewer == null)
     {
-      System.err.println("Can't use this object as a structure viewer:"
+      jalview.bin.Console.errPrintln("Can't use this object as a structure viewer:"
               + jmolviewer.getClass());
       return null;
     }
@@ -4127,7 +4127,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     chains = (String[]) sqch[1];
     if (seqs == null || seqs.length == 0)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "JalviewLite.AlignFrame:newStructureView: No sequence to bind structure to.");
     }
     if (protocol == null)
@@ -4142,7 +4142,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       }
       if (protocol == null)
       {
-        System.err.println("Couldn't work out protocol to open structure: "
+        jalview.bin.Console.errPrintln("Couldn't work out protocol to open structure: "
                 + pdb.getId());
         return;
       }
@@ -4154,7 +4154,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
               .setMapping(seqs, chains, pdb.getFile(), protocol,
                       null) == null)
       {
-        System.err.println("Failed to map " + pdb.getFile() + " ("
+        jalview.bin.Console.errPrintln("Failed to map " + pdb.getFile() + " ("
                 + protocol + ") to any sequences");
       }
       return;
@@ -4176,7 +4176,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       }
       if (ajm != null)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Incremental adding and aligning structure to existing Jmol view not yet implemented.");
         // try and add the pdb structure
         // ajm.addS
@@ -4201,7 +4201,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
           SequenceI[][] seqs, String[][] chains, String[] protocols)
   {
     // TODO Auto-generated method stub
-    System.err.println("Aligned Structure View: Not yet implemented.");
+    jalview.bin.Console.errPrintln("Aligned Structure View: Not yet implemented.");
   }
 
   /**
@@ -4258,9 +4258,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     if (!file.isValid())
     {
       // TODO: raise dialog for gui
-      System.err.println("Problems parsing T-Coffee scores: "
+      jalview.bin.Console.errPrintln("Problems parsing T-Coffee scores: "
               + file.getWarningMessage());
-      System.err.println("Origin was:\n" + source);
+      jalview.bin.Console.errPrintln("Origin was:\n" + source);
       return false;
     }
 
@@ -4273,7 +4273,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
                     || aln.getWidth() != file.getWidth()))
     {
       // TODO: raise a dialog box here rather than bomb out.
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "The scores matrix does not match the alignment dimensions");
 
     }
@@ -4289,10 +4289,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     }
     else
     {
-      System.err.println("Problems resolving T-Coffee scores:");
+      jalview.bin.Console.errPrintln("Problems resolving T-Coffee scores:");
       if (file.getWarningMessage() != null)
       {
-        System.err.println(file.getWarningMessage());
+        jalview.bin.Console.errPrintln(file.getWarningMessage());
       }
     }
     return false;
index d64cd75..c1de259 100644 (file)
@@ -77,14 +77,14 @@ public class AlignViewport extends AlignmentViewport
         }
         if (widthScale <= 1.0)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Invalid alignment character width scaling factor ("
                           + widthScale + "). Ignoring.");
           widthScale = 1;
         }
         if (JalviewLite.debug)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Alignment character width scaling factor is now "
                           + widthScale);
         }
@@ -100,14 +100,14 @@ public class AlignViewport extends AlignmentViewport
         }
         if (heightScale <= 1.0)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Invalid alignment character height scaling factor ("
                           + heightScale + "). Ignoring.");
           heightScale = 1;
         }
         if (JalviewLite.debug)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Alignment character height scaling factor is now "
                           + heightScale);
         }
index fd75296..71ddcef 100644 (file)
@@ -363,7 +363,7 @@ public class AlignmentPanel extends Panel
       {
         if (JalviewLite.debug)
         {// DEBUG
-          System.out.println(
+          jalview.bin.Console.outPrintln(
                   "DEBUG: scroll didn't happen - results not within alignment : "
                           + seq.getStart() + "," + seq.getEnd());
         }
@@ -373,7 +373,7 @@ public class AlignmentPanel extends Panel
       {
         // DEBUG
         /*
-         * System.out.println("DEBUG: scroll: start=" + r[0] +
+         * jalview.bin.Console.outPrintln("DEBUG: scroll: start=" + r[0] +
          * " av.getStartRes()=" + av.getStartRes() + " end=" + r[1] +
          * " seq.end=" + seq.getEnd() + " av.getEndRes()=" + av.getEndRes() +
          * " hextent=" + hextent);
@@ -555,7 +555,7 @@ public class AlignmentPanel extends Panel
     // this is called after loading new annotation onto alignment
     if (alignFrame.getSize().height == 0)
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "adjustAnnotationHeight frame size zero NEEDS FIXING");
     }
     fontChanged();
@@ -693,7 +693,7 @@ public class AlignmentPanel extends Panel
 
       if ((hextent + x) > width)
       {
-        System.err.println("hextent was " + hextent + " and x was " + x);
+        jalview.bin.Console.errPrintln("hextent was " + hextent + " and x was " + x);
 
         x = width - hextent;
       }
@@ -710,7 +710,7 @@ public class AlignmentPanel extends Panel
 
       if (x < 0)
       {
-        System.err.println("x was " + x);
+        jalview.bin.Console.errPrintln("x was " + x);
         x = 0;
       }
 
@@ -1111,7 +1111,7 @@ public class AlignmentPanel extends Panel
   public void raiseOOMWarning(String string, OutOfMemoryError error)
   {
     // TODO: JAL-960
-    System.err.println("Out of memory whilst '" + string + "'");
+    jalview.bin.Console.errPrintln("Out of memory whilst '" + string + "'");
     error.printStackTrace();
   }
 
index b0722c0..cca9aff 100644 (file)
@@ -275,7 +275,7 @@ public class AppletJmol extends EmbmenuFrame implements
               "-applet", scriptWindow, null);
     } catch (Exception e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Couldn't create a jmol viewer. Args to allocate viewer were:\nDocumentBase="
                       + ap.av.applet.getDocumentBase() + "\nCodebase="
                       + ap.av.applet.getCodeBase());
@@ -320,7 +320,7 @@ public class AppletJmol extends EmbmenuFrame implements
           {
             if (jalview.bin.JalviewLite.debug)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "AppletJmol:Trying to reuse existing PDBfile IO parser.");
             }
             // re-use the one we opened earlier
@@ -330,7 +330,7 @@ public class AppletJmol extends EmbmenuFrame implements
           {
             if (jalview.bin.JalviewLite.debug)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "AppletJmol:Creating new PDBfile IO parser.");
             }
             FileParse fp = new FileParse(pdbentry.getFile(), protocol);
@@ -355,7 +355,7 @@ public class AppletJmol extends EmbmenuFrame implements
         } catch (Exception e)
         {
           // give up!
-          System.err.println("Couldn't access pdbentry id="
+          jalview.bin.Console.errPrintln("Couldn't access pdbentry id="
                   + pdbentry.getId() + " and file=" + pdbentry.getFile()
                   + " using protocol=" + protocol);
           e.printStackTrace();
@@ -433,7 +433,7 @@ public class AppletJmol extends EmbmenuFrame implements
       } catch (OutOfMemoryError ex)
       {
         frame.dispose();
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Out of memory when trying to create dialog box with sequence-structure mapping.");
         return;
       }
index 47f9df0..e2b8f23 100644 (file)
@@ -154,7 +154,7 @@ public class ExtJmol extends JalviewJmolBinding
   {
     // This never gets called because we haven't overriden the associated Jmol's
     // console
-    System.err.println(
+    jalview.bin.Console.errPrintln(
             "WARNING: unexpected call to ExtJmol's showConsole method. (showConsole="
                     + show);
   }
index 7c0dfa9..7730210 100644 (file)
@@ -145,7 +145,7 @@ public class PCAPanel extends EmbmenuFrame
       top = pcaModel.getTop();
     } catch (OutOfMemoryError x)
     {
-      System.err.println("Out of memory when calculating PCA.");
+      jalview.bin.Console.errPrintln("Out of memory when calculating PCA.");
       return;
     }
     calcSettings.setEnabled(true);
index bc775c6..566aad9 100644 (file)
@@ -102,7 +102,7 @@ public class PairwiseAlignPanel extends Panel implements ActionListener
 
     if (count > 2)
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "Pairwise alignment scaled similarity score matrix\n");
 
       for (int i = 0; i < count; i++)
@@ -111,7 +111,7 @@ public class PairwiseAlignPanel extends Panel implements ActionListener
                 ("" + i) + " " + seqs[i].getName());
       }
 
-      System.out.println("\n");
+      jalview.bin.Console.outPrintln("\n");
 
       for (int i = 0; i < count; i++)
       {
@@ -122,7 +122,7 @@ public class PairwiseAlignPanel extends Panel implements ActionListener
         }
       }
 
-      System.out.println("\n");
+      jalview.bin.Console.outPrintln("\n");
     }
   }
 
index bd36b0d..a5b652f 100644 (file)
@@ -148,7 +148,7 @@ public class RedundancyPanel extends SliderPanel
 
     validate();
     sliderValueChanged();
-    // System.out.println("blob done "+ (System.currentTimeMillis()-start));
+    // jalview.bin.Console.outPrintln("blob done "+ (System.currentTimeMillis()-start));
   }
 
   void sliderValueChanged()
index a870ca4..87266b4 100755 (executable)
@@ -145,7 +145,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
 
     scale = findScale();
 
-    // System.out.println("Scale factor = " + scale);
+    // jalview.bin.Console.outPrintln("Scale factor = " + scale);
 
     addMouseListener(this);
     addKeyListener(this);
@@ -301,7 +301,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
 
         scale = findScale();
 
-        // System.out.println("New scale = " + scale);
+        // jalview.bin.Console.outPrintln("New scale = " + scale);
         img = createImage(getSize().width, getSize().height);
         ig = img.getGraphics();
 
@@ -427,7 +427,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
     }
     else if (evt.getKeyChar() == 's')
     {
-      System.err.println("DEBUG: Rectangle selection"); // log.debug
+      jalview.bin.Console.errPrintln("DEBUG: Rectangle selection"); // log.debug
       if (rectx2 != -1 && recty2 != -1)
       {
         rectSelect(rectx1, recty1, rectx2, recty2);
index 3b79f12..735046e 100755 (executable)
@@ -644,7 +644,9 @@ public class SeqCanvas extends Panel implements ViewportListenerI
       if (av.cursorMode && cursorY == i && cursorX >= startRes
               && cursorX <= endRes)
       {
-        sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * avcharWidth,
+        char s = nextSeq.getCharAt(cursorX);
+
+        sr.drawCursor(g,s, (cursorX - startRes) * avcharWidth,
                 offset + ((i - startSeq) * avcharHeight));
       }
     }
index 70366e4..c573612 100644 (file)
@@ -772,7 +772,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
   @Override
   public void updateColours(SequenceI seq, int index)
   {
-    System.out.println("update the seqPanel colours");
+    jalview.bin.Console.outPrintln("update the seqPanel colours");
     // repaint();
   }
 
@@ -1817,7 +1817,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       {
         if (av.getAlignment() == null)
         {
-          System.out.println("Selection message: alignviewport av SeqSetId="
+          jalview.bin.Console.outPrintln("Selection message: alignviewport av SeqSetId="
                   + av.getSequenceSetId() + " ViewId=" + av.getViewId()
                   + " 's alignment is NULL! returning immediatly.");
           return;
@@ -1869,7 +1869,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     if (copycolsel && av.hasHiddenColumns()
             && (av.getColumnSelection() == null))
     {
-      System.err.println("Bad things");
+      jalview.bin.Console.errPrintln("Bad things");
     }
     if (repaint)
     {
index eab6e39..34ad217 100755 (executable)
@@ -353,7 +353,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
     }
   }
 
-  public void drawCursor(SequenceI seq, int res, int x1, int y1)
+  public void drawCursor(Graphics graphics, char s, int x1, int y1)
   {
     int pady = av.getCharHeight() / 5;
     int charOffset = 0;
@@ -363,7 +363,6 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
 
     graphics.setColor(Color.white);
 
-    char s = seq.getCharAt(res);
     if (av.validCharWidth)
     {
 
index 8c3e39a..f965ff4 100755 (executable)
@@ -131,7 +131,7 @@ public class TreeCanvas extends Panel
     {
       BinaryNode lf = leaves.elementAt(i);
 
-      if (lf instanceof SequenceNode && ((SequenceNode)lf).isPlaceholder())
+      if (lf instanceof SequenceNode && ((SequenceNode) lf).isPlaceholder())
       {
         has_placeholders = true;
       }
@@ -211,9 +211,10 @@ public class TreeCanvas extends Panel
         g.drawString(nodeLabel, xstart + 2, ypos - 2);
       }
 
-      String name = (markPlaceholders && node instanceof SequenceNode && ((SequenceNode) node).isPlaceholder())
-              ? (PLACEHOLDER + node.getName())
-              : node.getName();
+      String name = (markPlaceholders && node instanceof SequenceNode
+              && ((SequenceNode) node).isPlaceholder())
+                      ? (PLACEHOLDER + node.getName())
+                      : node.getName();
       FontMetrics fm = g.getFontMetrics(font);
       int charWidth = fm.stringWidth(name) + 3;
       int charHeight = fm.getHeight();
@@ -385,8 +386,8 @@ public class TreeCanvas extends Panel
     }
     else
     {
-      pickNode(pickBox, (BinaryNode) node.left(), chunk, scale, width,
-              offx, offy);
+      pickNode(pickBox, (BinaryNode) node.left(), chunk, scale, width, offx,
+              offy);
       pickNode(pickBox, (BinaryNode) node.right(), chunk, scale, width,
               offx, offy);
     }
index 671fee1..0316e0b 100644 (file)
@@ -166,7 +166,7 @@ public class TreePanel extends EmbmenuFrame
     }
     else
     {
-      System.out.println("Original Tree Data not available");
+      jalview.bin.Console.outPrintln("Original Tree Data not available");
     }
   }
 
diff --git a/src/jalview/bin/ArgParser.java b/src/jalview/bin/ArgParser.java
deleted file mode 100644 (file)
index c7527c8..0000000
+++ /dev/null
@@ -1,1107 +0,0 @@
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- * 
- * This file is part of Jalview.
- * 
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *  
- * Jalview is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty 
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
- * PURPOSE.  See the GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.bin;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URLDecoder;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import jalview.util.Platform;
-
-public class ArgParser
-{
-  private static final String NEGATESTRING = "no";
-
-  private static final String DEFAULTLINKEDID = "";
-
-  private static enum Opt
-  {
-    BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES
-  }
-
-  // These bootstrap args are simply parsed before a full parse of arguments and
-  // so are accessible at an earlier stage to (e.g.) set debug log leve, provide
-  // a props file (that might set log level), run headlessly, read an argfile
-  // instead of other args.
-  private static final Collection<Arg> bootstrapArgs = new ArrayList(
-          Arrays.asList(Arg.PROPS, Arg.DEBUG, Arg.HEADLESS, Arg.ARGFILE));
-
-  public enum Arg
-  {
-    /*
-    NOCALCULATION, NOMENUBAR, NOSTATUS, SHOWOVERVIEW, ANNOTATIONS, COLOUR,
-    FEATURES, GROOVY, GROUPS, HEADLESS, JABAWS, NOANNOTATION, NOANNOTATION2,
-    NODISPLAY, NOGUI, NONEWS, NOQUESTIONNAIRE, NOSORTBYTREE, NOUSAGESTATS,
-    OPEN, OPEN2, PROPS, QUESTIONNAIRE, SETPROP, SORTBYTREE, TREE, VDOC,
-    VSESS;
-    */
-    HELP("h"), CALCULATION, MENUBAR, STATUS, SHOWOVERVIEW, ANNOTATIONS,
-    COLOUR, FEATURES, GROOVY, GROUPS, HEADLESS, JABAWS, ANNOTATION,
-    ANNOTATION2, DISPLAY, GUI, NEWS, NOQUESTIONNAIRE, SORTBYTREE,
-    USAGESTATS, OPEN, OPEN2, PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC,
-    VSESS, OUTPUT, OUTPUTTYPE, SSANNOTATION, NOTEMPFAC, TEMPFAC,
-    TEMPFAC_LABEL, TEMPFAC_DESC, TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP,
-    NOSTRUCTURE, STRUCTURE, IMAGE, QUIT, DEBUG("d"), ARGFILE;
-
-    static
-    {
-      HELP.setOptions(Opt.UNARY);
-      CALCULATION.setOptions(true, Opt.BOOLEAN); // default "true" implies only
-                                                 // expecting "--nocalculation"
-      MENUBAR.setOptions(true, Opt.BOOLEAN);
-      STATUS.setOptions(true, Opt.BOOLEAN);
-      SHOWOVERVIEW.setOptions(Opt.UNARY, Opt.LINKED);
-      ANNOTATIONS.setOptions(Opt.STRING, Opt.LINKED);
-      COLOUR.setOptions(Opt.STRING, Opt.LINKED);
-      FEATURES.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
-      GROOVY.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
-      GROUPS.setOptions(Opt.STRING, Opt.LINKED);
-      HEADLESS.setOptions(Opt.UNARY);
-      JABAWS.setOptions(Opt.STRING);
-      ANNOTATION.setOptions(true, Opt.BOOLEAN);
-      ANNOTATION2.setOptions(true, Opt.BOOLEAN);
-      DISPLAY.setOptions(true, Opt.BOOLEAN);
-      GUI.setOptions(true, Opt.BOOLEAN);
-      NEWS.setOptions(true, Opt.BOOLEAN);
-      NOQUESTIONNAIRE.setOptions(Opt.UNARY); // unary as --questionnaire=val
-                                             // expects a string value
-      SORTBYTREE.setOptions(true, Opt.BOOLEAN);
-      USAGESTATS.setOptions(true, Opt.BOOLEAN);
-      OPEN.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
-      OPEN2.setOptions(Opt.STRING, Opt.LINKED);
-      PROPS.setOptions(Opt.STRING);
-      QUESTIONNAIRE.setOptions(Opt.STRING);
-      SETPROP.setOptions(Opt.STRING);
-      TREE.setOptions(Opt.STRING);
-
-      VDOC.setOptions(Opt.UNARY);
-      VSESS.setOptions(Opt.UNARY);
-
-      OUTPUT.setOptions(Opt.STRING, Opt.LINKED);
-      OUTPUTTYPE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
-
-      SSANNOTATION.setOptions(Opt.BOOLEAN, Opt.LINKED);
-      NOTEMPFAC.setOptions(Opt.UNARY, Opt.LINKED);
-      TEMPFAC.setOptions(Opt.STRING, Opt.LINKED);
-      TEMPFAC_LABEL.setOptions(Opt.STRING, Opt.LINKED);
-      TEMPFAC_DESC.setOptions(Opt.STRING, Opt.LINKED);
-      TEMPFAC_SHADING.setOptions(Opt.BOOLEAN, Opt.LINKED);
-      TITLE.setOptions(Opt.STRING, Opt.LINKED);
-      PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
-      NOSTRUCTURE.setOptions(Opt.UNARY, Opt.LINKED);
-      STRUCTURE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
-      WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED);
-      IMAGE.setOptions(Opt.STRING, Opt.LINKED);
-      QUIT.setOptions(Opt.UNARY);
-      DEBUG.setOptions(Opt.BOOLEAN);
-      ARGFILE.setOptions(Opt.STRING);
-    }
-
-    private final String[] argNames;
-
-    private Opt[] argOptions;
-
-    private boolean defaultBoolValue = false;
-
-    public String toLongString()
-    {
-      StringBuilder sb = new StringBuilder();
-      sb.append("Arg: ").append(this.name());
-      for (String name : getNames())
-      {
-        sb.append(", '").append(name).append("'");
-      }
-      sb.append("\nOptions: ");
-      boolean first = true;
-      for (Opt o : argOptions)
-      {
-        if (!first)
-        {
-          sb.append(", ");
-        }
-        sb.append(o.toString());
-        first = false;
-      }
-      sb.append("\n");
-      return sb.toString();
-    }
-
-    private Arg()
-    {
-      this(new String[0]);
-    }
-
-    private Arg(String... names)
-    {
-      int length = (names == null || names.length == 0
-              || (names.length == 1 && names[0] == null)) ? 1
-                      : names.length + 1;
-      this.argNames = new String[length];
-      this.argNames[0] = this.getName();
-      if (length > 1)
-        System.arraycopy(names, 0, this.argNames, 1, names.length);
-    }
-
-    public String[] getNames()
-    {
-      return argNames;
-    }
-
-    public String getName()
-    {
-      return this.name().toLowerCase(Locale.ROOT).replace('_', '-');
-    }
-
-    @Override
-    public final String toString()
-    {
-      return getName();
-    }
-
-    public boolean hasOption(Opt o)
-    {
-      if (argOptions == null)
-        return false;
-      for (Opt option : argOptions)
-      {
-        if (o == option)
-          return true;
-      }
-      return false;
-    }
-
-    protected void setOptions(Opt... options)
-    {
-      setOptions(false, options);
-    }
-
-    protected void setOptions(boolean defaultBoolValue, Opt... options)
-    {
-      this.defaultBoolValue = defaultBoolValue;
-      argOptions = options;
-    }
-
-    protected boolean getDefaultBoolValue()
-    {
-      return defaultBoolValue;
-    }
-  }
-
-  public static class ArgValues
-  {
-    private static final String ID = "id";
-
-    private Arg arg;
-
-    private int argCount = 0;
-
-    private boolean boolValue = false;
-
-    private boolean negated = false;
-
-    private int boolIndex = -1;
-
-    private List<Integer> argsIndexes;
-
-    private List<ArgValue> argValueList;
-
-    private Map<String, ArgValue> idMap = new HashMap<>();
-
-    protected ArgValues(Arg a)
-    {
-      this.arg = a;
-      this.argValueList = new ArrayList<ArgValue>();
-      this.boolValue = arg.getDefaultBoolValue();
-    }
-
-    public Arg arg()
-    {
-      return arg;
-    }
-
-    protected int getCount()
-    {
-      return argCount;
-    }
-
-    protected void incrementCount()
-    {
-      argCount++;
-    }
-
-    protected void setNegated(boolean b)
-    {
-      this.negated = b;
-    }
-
-    protected boolean isNegated()
-    {
-      return this.negated;
-    }
-
-    protected void setBoolean(boolean b, int i)
-    {
-      this.boolValue = b;
-      this.boolIndex = i;
-    }
-
-    protected boolean getBoolean()
-    {
-      return this.boolValue;
-    }
-
-    @Override
-    public String toString()
-    {
-      if (argValueList == null)
-        return null;
-      StringBuilder sb = new StringBuilder();
-      sb.append(arg.toLongString());
-      if (arg.hasOption(Opt.BOOLEAN) || arg.hasOption(Opt.UNARY))
-        sb.append("Boolean: ").append(boolValue).append("; Default: ")
-                .append(arg.getDefaultBoolValue()).append("; Negated: ")
-                .append(negated).append("\n");
-      if (arg.hasOption(Opt.STRING))
-      {
-        sb.append("Values:");
-        boolean first = true;
-        for (ArgValue av : argValueList)
-        {
-          String v = av.getValue();
-          if (!first)
-            sb.append(",");
-          sb.append("\n  '");
-          sb.append(v).append("'");
-          first = false;
-        }
-        sb.append("\n");
-      }
-      sb.append("Count: ").append(argCount).append("\n");
-      return sb.toString();
-    }
-
-    protected void addValue()
-    {
-      addValue(null, -1);
-    }
-
-    protected void addValue(String val, int argIndex)
-    {
-      addArgValue(new ArgValue(val, argIndex));
-    }
-
-    protected void addArgValue(ArgValue av)
-    {
-      if ((!arg.hasOption(Opt.MULTI) && argValueList.size() > 0)
-              || (arg.hasOption(Opt.NODUPLICATEVALUES)
-                      && argValueList.contains(av.getValue())))
-        return;
-      if (argValueList == null)
-      {
-        argValueList = new ArrayList<ArgValue>();
-      }
-      SubVals sv = ArgParser.getSubVals(av.getValue());
-      if (sv.has(ID))
-      {
-        String id = sv.get(ID);
-        av.setId(id);
-        idMap.put(id, av);
-      }
-      argValueList.add(av);
-    }
-
-    protected boolean hasValue(String val)
-    {
-      return argValueList.contains(val);
-    }
-
-    protected ArgValue getArgValue()
-    {
-      if (arg.hasOption(Opt.MULTI))
-        Console.warn("Requesting single value for multi value argument");
-      return argValueList.size() > 0 ? argValueList.get(0) : null;
-    }
-
-    protected List<ArgValue> getArgValueList()
-    {
-      return argValueList;
-    }
-
-    protected boolean hasId(String id)
-    {
-      return idMap.containsKey(id);
-    }
-
-    protected ArgValue getId(String id)
-    {
-      return idMap.get(id);
-    }
-  }
-
-  // old style
-  private List<String> vargs = null;
-
-  private boolean isApplet;
-
-  // private AppletParams appletParams;
-
-  public boolean isApplet()
-  {
-    return isApplet;
-  }
-
-  public String nextValue()
-  {
-    return vargs.remove(0);
-  }
-
-  public int getSize()
-  {
-    return vargs.size();
-  }
-
-  public String getValue(String arg)
-  {
-    return getValue(arg, false);
-  }
-
-  public String getValue(String arg, boolean utf8decode)
-  {
-    int index = vargs.indexOf(arg);
-    String dc = null;
-    String ret = null;
-    if (index != -1)
-    {
-      ret = vargs.get(index + 1).toString();
-      vargs.remove(index);
-      vargs.remove(index);
-      if (utf8decode && ret != null)
-      {
-        try
-        {
-          dc = URLDecoder.decode(ret, "UTF-8");
-          ret = dc;
-        } catch (Exception e)
-        {
-          // TODO: log failure to decode
-        }
-      }
-    }
-    return ret;
-  }
-
-  /*
-  public Object getAppletValue(String key, String def, boolean asString)
-  {
-    Object value;
-    return (appletParams == null ? null
-            : (value = appletParams.get(key.toLowerCase())) == null ? def
-                    : asString ? "" + value : value);
-  }
-  */
-
-  // new style
-  private static final Map<String, Arg> argMap;
-
-  private Map<String, ArgValuesMap> linkedArgs = new HashMap<>();
-
-  private List<String> linkedOrder = null;
-
-  private List<Arg> argList;
-
-  static
-  {
-    argMap = new HashMap<>();
-    for (Arg a : EnumSet.allOf(Arg.class))
-    {
-      ARGNAME: for (String argName : a.getNames())
-      {
-        if (argMap.containsKey(argName))
-        {
-          Console.warn("Trying to add argument name multiple times: '"
-                  + argName + "'"); // RESTORE THIS WHEN MERGED
-          if (argMap.get(argName) != a)
-          {
-            Console.error(
-                    "Trying to add argument name multiple times for different Args: '"
-                            + argMap.get(argName).getName() + ":" + argName
-                            + "' and '" + a.getName() + ":" + argName
-                            + "'");
-          }
-          continue ARGNAME;
-        }
-        argMap.put(argName, a);
-      }
-    }
-  }
-
-  public ArgParser(String[] args)
-  {
-    // old style
-    vargs = new ArrayList<>();
-    isApplet = (args.length > 0 && args[0].startsWith("<applet"));
-    if (isApplet)
-    {
-      // appletParams = AppletParams.getAppletParams(args, vargs);
-    }
-    else
-    {
-      if (Platform.isJS())
-
-      {
-        isApplet = true;
-        // appletParams =
-        // AppletParams.getAppletParams(Platform.getAppletInfoAsMap(), vargs);
-      }
-      for (int i = 0; i < args.length; i++)
-      {
-        String arg = args[i].trim();
-        if (arg.charAt(0) == '-')
-        {
-          arg = arg.substring(1);
-        }
-        vargs.add(arg);
-      }
-    }
-
-    // new style
-    Enumeration<String> argE = Collections.enumeration(Arrays.asList(args));
-    int argIndex = 0;
-    while (argE.hasMoreElements())
-    {
-      String arg = argE.nextElement();
-      String argName = null;
-      String val = null;
-      String linkedId = null;
-      if (arg.startsWith("--"))
-      {
-        int equalPos = arg.indexOf('=');
-        if (equalPos > -1)
-        {
-          argName = arg.substring(2, equalPos);
-          val = arg.substring(equalPos + 1);
-        }
-        else
-        {
-          argName = arg.substring(2);
-        }
-        int idOpen = argName.indexOf('[');
-        int idClose = argName.indexOf(']');
-
-        if (idOpen > -1 && idClose == argName.length() - 1)
-        {
-          linkedId = argName.substring(idOpen + 1, idClose);
-          argName = argName.substring(0, idOpen);
-        }
-
-        Arg a = argMap.get(argName);
-        // check for boolean prepended by "no"
-        boolean negated = false;
-        if (a == null && argName.startsWith(NEGATESTRING) && argMap
-                .containsKey(argName.substring(NEGATESTRING.length())))
-        {
-          argName = argName.substring(NEGATESTRING.length());
-          a = argMap.get(argName);
-          negated = true;
-        }
-
-        // check for config errors
-        if (a == null)
-        {
-          // arg not found
-          Console.error("Argument '" + arg + "' not recognised. Ignoring.");
-          continue;
-        }
-        if (!a.hasOption(Opt.BOOLEAN) && negated)
-        {
-          // used "no" with a non-boolean option
-          Console.error("Argument '--" + NEGATESTRING + argName
-                  + "' not a boolean option. Ignoring.");
-          continue;
-        }
-        if (!a.hasOption(Opt.STRING) && equalPos > -1)
-        {
-          // set --argname=value when arg does not accept values
-          Console.error("Argument '--" + argName
-                  + "' does not expect a value (given as '" + arg
-                  + "').  Ignoring.");
-          continue;
-        }
-        if (!a.hasOption(Opt.LINKED) && linkedId != null)
-        {
-          // set --argname[linkedId] when arg does not use linkedIds
-          Console.error("Argument '--" + argName
-                  + "' does not expect a linked id (given as '" + arg
-                  + "'). Ignoring.");
-          continue;
-        }
-
-        if (a.hasOption(Opt.STRING) && equalPos == -1)
-        {
-          // take next arg as value if required, and '=' was not found
-          if (!argE.hasMoreElements())
-          {
-            // no value to take for arg, which wants a value
-            Console.error("Argument '" + a.getName()
-                    + "' requires a value, none given. Ignoring.");
-            continue;
-          }
-          val = argE.nextElement();
-        }
-
-        // use default linkedId for linked arguments
-        if (a.hasOption(Opt.LINKED) && linkedId == null)
-          linkedId = DEFAULTLINKEDID;
-
-        if (!linkedArgs.containsKey(linkedId))
-          linkedArgs.put(linkedId, new ArgValuesMap());
-
-        ArgValuesMap avm = linkedArgs.get(linkedId);
-
-        if (a.hasOption(Opt.NODUPLICATEVALUES) && avm.hasValue(a, val))
-        {
-          Console.error("Argument '--" + argName
-                  + "' cannot contain a duplicate value ('" + val
-                  + "'). Ignoring this and subsequent occurrences.");
-          continue;
-        }
-
-        // check for unique id
-        SubVals sv = ArgParser.getSubVals(val);
-        String id = sv.get(ArgValues.ID);
-        if (id != null && avm.hasId(a, id))
-        {
-          Console.error("Argument '--" + argName + "' has a duplicate id ('"
-                  + id + "'). Ignoring.");
-          continue;
-        }
-
-        ArgValues avs = avm.getOrCreateArgValues(a);
-        if (avs == null)
-        {
-          avs = new ArgValues(a);
-        }
-        // store appropriate value
-        if (a.hasOption(Opt.STRING))
-        {
-          avs.addValue(val, argIndex);
-        }
-        else if (a.hasOption(Opt.BOOLEAN))
-        {
-          avs.setBoolean(!negated, argIndex);
-          avs.setNegated(negated);
-        }
-        else if (a.hasOption(Opt.UNARY))
-        {
-          avs.setBoolean(true, argIndex);
-        }
-        avs.incrementCount();
-
-        // store in appropriate place
-        if (a.hasOption(Opt.LINKED))
-        {
-          // allow a default linked id for single usage
-          if (linkedId == null)
-            linkedId = DEFAULTLINKEDID;
-          // store the order of linkedIds
-          if (linkedOrder == null)
-            linkedOrder = new ArrayList<>();
-          if (!linkedOrder.contains(linkedId))
-            linkedOrder.add(linkedId);
-        }
-
-        // store arg in the list of args used
-        if (argList == null)
-          argList = new ArrayList<>();
-        if (!argList.contains(a))
-          argList.add(a);
-      }
-    }
-  }
-
-  public boolean isSet(Arg a)
-  {
-    return a.hasOption(Opt.LINKED) ? isSet("", a) : isSet(null, a);
-  }
-
-  public boolean isSet(String linkedId, Arg a)
-  {
-    ArgValuesMap avm = linkedArgs.get(linkedId);
-    return avm == null ? false : avm.containsArg(a);
-  }
-
-  public boolean getBool(Arg a)
-  {
-    if (!a.hasOption(Opt.BOOLEAN) && !a.hasOption(Opt.UNARY))
-    {
-      Console.warn("Getting boolean from non boolean Arg '" + a.getName()
-              + "'.");
-    }
-    return a.hasOption(Opt.LINKED) ? getBool("", a) : getBool(null, a);
-  }
-
-  public boolean getBool(String linkedId, Arg a)
-  {
-    ArgValuesMap avm = linkedArgs.get(linkedId);
-    if (avm == null)
-      return a.getDefaultBoolValue();
-    ArgValues avs = avm.getArgValues(a);
-    return avs == null ? a.getDefaultBoolValue() : avs.getBoolean();
-  }
-
-  public List<String> linkedIds()
-  {
-    return linkedOrder;
-  }
-
-  public ArgValuesMap linkedArgs(String id)
-  {
-    return linkedArgs.get(id);
-  }
-
-  @Override
-  public String toString()
-  {
-    StringBuilder sb = new StringBuilder();
-    sb.append("UNLINKED\n");
-    sb.append(argValuesMapToString(linkedArgs.get(null)));
-    if (linkedIds() != null)
-    {
-      sb.append("LINKED\n");
-      for (String id : linkedIds())
-      {
-        // already listed these as UNLINKED args
-        if (id == null)
-          continue;
-
-        ArgValuesMap avm = linkedArgs(id);
-        sb.append("ID: '").append(id).append("'\n");
-        sb.append(argValuesMapToString(avm));
-      }
-    }
-    return sb.toString();
-  }
-
-  private static String argValuesMapToString(ArgValuesMap avm)
-  {
-    if (avm == null)
-      return null;
-    StringBuilder sb = new StringBuilder();
-    for (Arg a : avm.getArgKeys())
-    {
-      ArgValues v = avm.getArgValues(a);
-      sb.append(v.toString());
-      sb.append("\n");
-    }
-    return sb.toString();
-  }
-
-  public static SubVals getSubVals(String item)
-  {
-    return new SubVals(item);
-  }
-
-  /**
-   * A helper class to keep an index of argument position with argument values
-   */
-  public static class ArgValue
-  {
-    private int argIndex;
-
-    private String value;
-
-    private String id;
-
-    protected ArgValue(String value, int argIndex)
-    {
-      this.value = value;
-      this.argIndex = argIndex;
-    }
-
-    protected String getValue()
-    {
-      return value;
-    }
-
-    protected int getArgIndex()
-    {
-      return argIndex;
-    }
-
-    protected void setId(String i)
-    {
-      id = i;
-    }
-
-    protected String getId()
-    {
-      return id;
-    }
-  }
-
-  /**
-   * A helper class to parse a string of the possible forms "content"
-   * "[index]content", "[keyName=keyValue]content" and return the integer index,
-   * the strings keyName and keyValue, and the content after the square brackets
-   * (if present). Values not set `will be -1 or null.
-   */
-  public static class SubVals
-  {
-    private static int NOTSET = -1;
-
-    private int index = NOTSET;
-
-    private Map<String, String> subVals = null;
-
-    private static char SEPARATOR = ';';
-
-    private String content = null;
-
-    public SubVals(String item)
-    {
-      this.parseVals(item);
-    }
-
-    public void parseVals(String item)
-    {
-      if (item == null)
-        return;
-      if (item.indexOf('[') == 0 && item.indexOf(']') > 1)
-      {
-        int openBracket = item.indexOf('[');
-        int closeBracket = item.indexOf(']');
-        String subvalsString = item.substring(openBracket + 1,
-                closeBracket);
-        this.content = item.substring(closeBracket + 1);
-        boolean setIndex = false;
-        for (String subvalString : subvalsString
-                .split(Character.toString(SEPARATOR)))
-        {
-          int equals = subvalString.indexOf('=');
-          if (equals > -1)
-          {
-            if (subVals == null)
-              subVals = new HashMap<>();
-            subVals.put(subvalString.substring(0, equals),
-                    subvalString.substring(equals + 1));
-          }
-          else
-          {
-            try
-            {
-              this.index = Integer.parseInt(subvalString);
-              setIndex = true;
-            } catch (NumberFormatException e)
-            {
-              Console.warn("Failed to obtain subvalue or index from '"
-                      + item + "'. Setting index=0 and using content='"
-                      + content + "'.");
-            }
-          }
-        }
-        if (!setIndex)
-          this.index = NOTSET;
-      }
-      else
-      {
-        this.content = item;
-      }
-    }
-
-    public boolean notSet()
-    {
-      // notSet is true if content present but nonsensical
-      return index == NOTSET && subVals == null;
-    }
-
-    public String get(String key)
-    {
-      return subVals == null ? null : subVals.get(key);
-    }
-
-    public boolean has(String key)
-    {
-      return subVals == null ? false : subVals.containsKey(key);
-    }
-
-    public int getIndex()
-    {
-      return index;
-    }
-
-    public String getContent()
-    {
-      return content;
-    }
-  }
-
-  /**
-   * Helper class to allow easy extraction of information about specific
-   * argument values (without having to check for null etc all the time)
-   */
-  protected static class ArgValuesMap
-  {
-    protected Map<Arg, ArgValues> m;
-
-    protected ArgValuesMap()
-    {
-      this.newMap();
-    }
-
-    protected ArgValuesMap(Map<Arg, ArgValues> map)
-    {
-      this.m = map;
-    }
-
-    private Map<Arg, ArgValues> getMap()
-    {
-      return m;
-    }
-
-    private void newMap()
-    {
-      m = new HashMap<Arg, ArgValues>();
-    }
-
-    private void newArg(Arg a)
-    {
-      if (m == null)
-        newMap();
-      if (!containsArg(a))
-        m.put(a, new ArgValues(a));
-    }
-
-    protected void addArgValue(Arg a, ArgValue av)
-    {
-      if (getMap() == null)
-        m = new HashMap<Arg, ArgValues>();
-
-      if (!m.containsKey(a))
-        m.put(a, new ArgValues(a));
-      ArgValues avs = m.get(a);
-      avs.addArgValue(av);
-    }
-
-    protected ArgValues getArgValues(Arg a)
-    {
-      return m == null ? null : m.get(a);
-    }
-
-    protected ArgValues getOrCreateArgValues(Arg a)
-    {
-      ArgValues avs = m.get(a);
-      if (avs == null)
-        newArg(a);
-      return getArgValues(a);
-    }
-
-    protected List<ArgValue> getArgValueList(Arg a)
-    {
-      ArgValues avs = getArgValues(a);
-      return avs == null ? new ArrayList<>() : avs.getArgValueList();
-    }
-
-    protected ArgValue getArgValue(Arg a)
-    {
-      List<ArgValue> vals = getArgValueList(a);
-      return (vals == null || vals.size() == 0) ? null : vals.get(0);
-    }
-
-    protected String getValue(Arg a)
-    {
-      ArgValue av = getArgValue(a);
-      return av == null ? null : av.getValue();
-    }
-
-    protected boolean containsArg(Arg a)
-    {
-      if (m == null || !m.containsKey(a))
-        return false;
-      return a.hasOption(Opt.STRING) ? getArgValue(a) != null
-              : this.getBoolean(a);
-    }
-
-    protected boolean hasValue(Arg a, String val)
-    {
-      if (m == null || !m.containsKey(a))
-        return false;
-      for (ArgValue av : getArgValueList(a))
-      {
-        String avVal = av.getValue();
-        if ((val == null && avVal == null)
-                || (val != null && val.equals(avVal)))
-        {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    protected boolean getBoolean(Arg a)
-    {
-      ArgValues av = getArgValues(a);
-      return av == null ? false : av.getBoolean();
-    }
-
-    protected Set<Arg> getArgKeys()
-    {
-      return m.keySet();
-    }
-
-    protected ArgValue getClosestPreviousArgValueOfArg(ArgValue thisAv,
-            Arg a)
-    {
-      ArgValue closestAv = null;
-      int thisArgIndex = thisAv.getArgIndex();
-      ArgValues compareAvs = this.getArgValues(a);
-      int closestPreviousIndex = -1;
-      for (ArgValue av : compareAvs.getArgValueList())
-      {
-        int argIndex = av.getArgIndex();
-        if (argIndex < thisArgIndex && argIndex > closestPreviousIndex)
-        {
-          closestPreviousIndex = argIndex;
-          closestAv = av;
-        }
-      }
-      return closestAv;
-    }
-
-    protected ArgValue getClosestNextArgValueOfArg(ArgValue thisAv, Arg a)
-    {
-      // this looks for the *next* arg that *might* be referring back to
-      // a thisAv. Such an arg would have no subValues (if it does it should
-      // specify an id in the subValues so wouldn't need to be guessed).
-      ArgValue closestAv = null;
-      int thisArgIndex = thisAv.getArgIndex();
-      ArgValues compareAvs = this.getArgValues(a);
-      int closestNextIndex = Integer.MAX_VALUE;
-      for (ArgValue av : compareAvs.getArgValueList())
-      {
-        int argIndex = av.getArgIndex();
-        if (argIndex > thisArgIndex && argIndex < closestNextIndex)
-        {
-          closestNextIndex = argIndex;
-          closestAv = av;
-        }
-      }
-      return closestAv;
-    }
-
-    protected ArgValue[] getArgValuesReferringTo(String key, String value,
-            Arg a)
-    {
-      // this looks for the *next* arg that *might* be referring back to
-      // a thisAv. Such an arg would have no subValues (if it does it should
-      // specify an id in the subValues so wouldn't need to be guessed).
-      List<ArgValue> avList = new ArrayList<>();
-      Arg[] args = a == null ? (Arg[]) this.getMap().keySet().toArray()
-              : new Arg[]
-              { a };
-      for (Arg keyArg : args)
-      {
-        for (ArgValue av : this.getArgValueList(keyArg))
-        {
-
-        }
-      }
-      return (ArgValue[]) avList.toArray();
-    }
-
-    protected boolean hasId(Arg a, String id)
-    {
-      ArgValues avs = this.getArgValues(a);
-      return avs == null ? false : avs.hasId(id);
-    }
-
-    protected ArgValue getId(Arg a, String id)
-    {
-      ArgValues avs = this.getArgValues(a);
-      return avs == null ? null : avs.getId(id);
-    }
-  }
-
-  public static Map<Arg, String> bootstrapArgs(String[] args)
-  {
-    Map<Arg, String> bootstrapArgMap = new HashMap<>();
-    if (args == null)
-      return bootstrapArgMap;
-    Enumeration<String> argE = Collections.enumeration(Arrays.asList(args));
-    while (argE.hasMoreElements())
-    {
-      String arg = argE.nextElement();
-      String argName = null;
-      String val = null;
-      if (arg.startsWith("--"))
-      {
-        int equalPos = arg.indexOf('=');
-        if (equalPos > -1)
-        {
-          argName = arg.substring(2, equalPos);
-          val = arg.substring(equalPos + 1);
-        }
-        else
-        {
-          argName = arg.substring(2);
-        }
-        Arg a = argMap.get(argName);
-        if (a != null && bootstrapArgs.contains(a))
-          bootstrapArgMap.put(a, val);
-      }
-    }
-    return bootstrapArgMap;
-  }
-
-  public static ArgParser parseArgFile(String argFilename)
-  {
-    List<String> argsList = null;
-    File argFile = new File(argFilename);
-    if (!argFile.exists())
-    {
-      System.err.println("--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT)
-              + "=\"" + argFilename + "\": File does not exist.");
-      System.exit(2);
-    }
-    try
-    {
-      argsList = Files.readAllLines(Paths.get(argFilename));
-    } catch (IOException e)
-    {
-      System.err.println("--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT)
-              + "=\"" + argFilename + "\": File could not be read.");
-      System.exit(3);
-    }
-    return new ArgParser((String[]) argsList.toArray());
-  }
-}
\ No newline at end of file
index c927f1f..ab33542 100644 (file)
@@ -42,7 +42,7 @@ public class ArgsParser
     for (int i = 0; i < args.length; i++)
     {
       String arg = args[i].trim();
-      if (arg.charAt(0) == '-')
+      if (arg.length() > 0 && arg.charAt(0) == '-')
       {
         arg = arg.substring(1);
       }
index 698cbb8..038a5a0 100755 (executable)
@@ -42,7 +42,10 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.TreeSet;
@@ -50,6 +53,7 @@ import java.util.TreeSet;
 import javax.swing.LookAndFeel;
 import javax.swing.UIManager;
 
+import jalview.analytics.Plausible;
 import jalview.datamodel.PDBEntry;
 import jalview.gui.Preferences;
 import jalview.gui.UserDefinedColours;
@@ -125,7 +129,7 @@ import jalview.ws.sifts.SiftsSettings;
  * service</li>
  * <li>QUESTIONNAIRE last questionnaire:responder id string from questionnaire
  * service</li>
- * <li>USAGESTATS (false - user prompted) Enable google analytics tracker for
+ * <li>USAGESTATS (false - user prompted) Enable analytics tracker for
  * collecting usage statistics</li>
  * <li>SHOW_OVERVIEW boolean for overview window display</li>
  * <li>ANTI_ALIAS boolean for smooth fonts</li>
@@ -137,6 +141,9 @@ import jalview.ws.sifts.SiftsSettings;
  * <li>WRAP_ALIGNMENT</li>
  * <li>EPS_RENDERING (Prompt each time|Lineart|Text) default for EPS rendering
  * style check</li>
+ * <li>BITMAP_SCALE - scale factor for PNG export - default 0 - native resolution</li>
+ * <li>BITMAP_HEIGHT - height bound for PNG export or 0 for unbound</li>
+ * <li>BITMAP_WIDTH - width bound for PNG export or 0 for unbound</li>
  * <li>SORT_ALIGNMENT (No sort|Id|Pairwise Identity)</li>
  * <li>SEQUENCE_LINKS list of name|URL pairs for opening a url with
  * $SEQUENCE_ID$</li>
@@ -244,6 +251,9 @@ public class Cache
    */
   public static final String JALVIEWLOGLEVEL = "logs.Jalview.level";
 
+  // for tests
+  public static final String BOOTSTRAP_TEST = "BOOTSTRAP_TEST";
+
   /**
    * Sifts settings
    */
@@ -307,6 +317,24 @@ public class Cache
   // in-memory only storage of proxy password, safer to use char array
   public static char[] proxyAuthPassword = null;
 
+  /**
+   * Session properties, set by command line, try not to affect stored
+   * properties!
+   */
+  private static Map<String, String> sessionProperties = new HashMap<>();
+
+  private static boolean bypassSessionProperties = false;
+
+  public static void enableSessionProperties()
+  {
+    bypassSessionProperties = false;
+  }
+
+  public static void disableSessionProperties()
+  {
+    bypassSessionProperties = true;
+  }
+
   /** Jalview Properties */
   public static Properties applicationProperties = new Properties()
   {
@@ -380,10 +408,13 @@ public class Cache
         {
           // props file provided as URL
           fis = new URL(propertiesFile).openStream();
-          System.out.println(
-                  "Loading jalview properties from : " + propertiesFile);
-          System.out.println(
-                  "Disabling Jalview writing to user's local properties file.");
+          if (!Jalview.quiet())
+          {
+            jalview.bin.Console.outPrintln(
+                    "Loading jalview properties from : " + propertiesFile);
+            jalview.bin.Console.outPrintln(
+                    "Disabling Jalview writing to user's local properties file.");
+          }
           propsAreReadOnly = true;
         } catch (Exception ex)
         {
@@ -411,7 +442,9 @@ public class Cache
         fis.close();
       } catch (Exception ex)
       {
-        System.out.println("Error reading properties file: " + ex);
+        if (!Jalview.quiet())
+          jalview.bin.Console
+                  .outPrintln("Error reading properties file: " + ex);
       }
     }
 
@@ -467,7 +500,9 @@ public class Cache
       }
     } catch (Exception ex)
     {
-      System.out.println("Error reading author details: " + ex);
+      if (!Jalview.quiet())
+        jalview.bin.Console
+                .outPrintln("Error reading author details: " + ex);
       authorDetails = null;
     }
     if (authorDetails == null)
@@ -530,8 +565,8 @@ public class Cache
           if (orgtimeout == null)
           {
             orgtimeout = "30";
-            System.out.println("# INFO: Setting default net timeout to "
-                    + orgtimeout + " seconds.");
+            Console.debug("Setting default net timeout to " + orgtimeout
+                    + " seconds.");
           }
           String remoteVersion = null;
           if (remoteBuildPropertiesUrl.startsWith("http"))
@@ -551,10 +586,13 @@ public class Cache
               remoteVersion = remoteBuildProperties.getProperty("VERSION");
             } catch (Exception ex)
             {
-              System.out.println(
-                      "Non-fatal exception when checking version at "
-                              + remoteBuildPropertiesUrl + ":");
-              System.out.println(ex);
+              if (!Jalview.quiet())
+              {
+                jalview.bin.Console.outPrintln(
+                        "Non-fatal exception when checking version at "
+                                + remoteBuildPropertiesUrl + ":");
+                jalview.bin.Console.printStackTrace(ex);
+              }
               remoteVersion = getProperty("VERSION");
             }
           }
@@ -603,7 +641,7 @@ public class Cache
         url = Cache.class.getResource(resourcePath).toString();
       } catch (Exception ex)
       {
-        System.err.println("Failed to resolve resource " + resourcePath
+        jalview.bin.Console.errPrintln("Failed to resolve resource " + resourcePath
                 + ": " + ex.getMessage());
       }
     }
@@ -653,7 +691,9 @@ public class Cache
       }
     } catch (Exception ex)
     {
-      System.out.println("Error reading build details: " + ex);
+      if (!Jalview.quiet())
+        jalview.bin.Console
+                .outPrintln("Error reading build details: " + ex);
       applicationProperties.remove("VERSION");
     }
     String codeVersion = getProperty("VERSION");
@@ -673,8 +713,9 @@ public class Cache
     new BuildDetails(codeVersion, null, codeInstallation);
     if (printVersion && reportVersion)
     {
-      System.out.println(ChannelProperties.getProperty("app_name")
-              + " Version: " + codeVersion + codeInstallation);
+      jalview.bin.Console
+              .outPrintln(ChannelProperties.getProperty("app_name")
+                      + " version: " + codeVersion + codeInstallation);
     }
   }
 
@@ -700,7 +741,21 @@ public class Cache
    */
   public static String getProperty(String key)
   {
-    String prop = applicationProperties.getProperty(key);
+    return getProperty(key, false);
+  }
+
+  public static String getProperty(String key,
+          boolean skipSessionProperties)
+  {
+    String prop = null;
+    if (!(skipSessionProperties || bypassSessionProperties))
+    {
+      prop = getSessionProperty(key);
+    }
+    if (prop == null)
+    {
+      prop = applicationProperties.getProperty(key);
+    }
     if (prop == null && Platform.isJS())
     {
       prop = applicationProperties.getProperty(Platform.getUniqueAppletID()
@@ -735,8 +790,9 @@ public class Cache
         def = Integer.parseInt(string);
       } catch (NumberFormatException e)
       {
-        System.out.println("Error parsing int property '" + property
-                + "' with value '" + string + "'");
+        if (!Jalview.quiet())
+          jalview.bin.Console.outPrintln("Error parsing int property '"
+                  + property + "' with value '" + string + "'");
       }
     }
 
@@ -769,16 +825,25 @@ public class Cache
     try
     {
       oldValue = applicationProperties.setProperty(key, obj);
-      if (propertiesFile != null && !propsAreReadOnly)
+      if (propertiesFile != null && !propsAreReadOnly
+      // don't rewrite if new value is same as old value
+              && !((obj == null && oldValue == null)
+                      || (obj != null && obj.equals(oldValue))))
       {
+        // reset the session property too
+        if (sessionProperties.containsKey(key))
+        {
+          sessionProperties.remove(key);
+        }
         FileOutputStream out = new FileOutputStream(propertiesFile);
         applicationProperties.store(out, "---JalviewX Properties File---");
         out.close();
       }
     } catch (Exception ex)
     {
-      System.out.println(
-              "Error setting property: " + key + " " + obj + "\n" + ex);
+      if (!Jalview.quiet())
+        jalview.bin.Console.outPrintln(
+                "Error setting property: " + key + " " + obj + "\n" + ex);
     }
     return oldValue;
   }
@@ -808,7 +873,8 @@ public class Cache
         out.close();
       } catch (Exception ex)
       {
-        System.out.println("Error saving properties: " + ex);
+        if (!Jalview.quiet())
+          jalview.bin.Console.outPrintln("Error saving properties: " + ex);
       }
     }
   }
@@ -896,102 +962,42 @@ public class Cache
   }
 
   /**
-   * GA tracker object - actually JGoogleAnalyticsTracker null if tracking not
-   * enabled.
-   */
-  protected static Object tracker = null;
-
-  protected static Class trackerfocus = null;
-
-  protected static Class jgoogleanalyticstracker = null;
-
-  /**
-   * Initialise the google tracker if it is not done already.
+   * Initialise the tracker if it is not done already.
    */
-  public static void initGoogleTracker()
+  public static void initAnalytics()
   {
-    if (tracker == null)
+    Plausible.setEnabled(true);
+
+    String appName = ChannelProperties.getProperty("app_name") + " Desktop";
+    String version = Cache.getProperty("VERSION") + "_"
+            + Cache.getDefault("BUILD_DATE", "unknown");
+    String path;
+    /* we don't want to encode ':' as "%3A" for backward compatibility with the UA setup
+    try
     {
-      if (jgoogleanalyticstracker == null)
-      {
-        // try to get the tracker class
-        try
-        {
-          jgoogleanalyticstracker = Cache.class.getClassLoader().loadClass(
-                  "com.boxysystems.jgoogleanalytics.JGoogleAnalyticsTracker");
-          trackerfocus = Cache.class.getClassLoader()
-                  .loadClass("com.boxysystems.jgoogleanalytics.FocusPoint");
-        } catch (Exception e)
-        {
-          Console.debug(
-                  "com.boxysystems.jgoogleanalytics package is not present - tracking not enabled.");
-          tracker = null;
-          jgoogleanalyticstracker = null;
-          trackerfocus = null;
-          return;
-        }
-      }
-      // now initialise tracker
-      Exception re = null, ex = null;
-      Error err = null;
-      String vrs = "No Version Accessible";
-      try
-      {
-        // Google analytics tracking code for Library Finder
-        tracker = jgoogleanalyticstracker
-                .getConstructor(new Class[]
-                { String.class, String.class, String.class })
-                .newInstance(new Object[]
-                { ChannelProperties.getProperty("app_name") + " Desktop",
-                    (vrs = Cache.getProperty("VERSION") + "_"
-                            + Cache.getDefault("BUILD_DATE", "unknown")),
-                    "UA-9060947-1" });
-        jgoogleanalyticstracker
-                .getMethod("trackAsynchronously", new Class[]
-                { trackerfocus })
-                .invoke(tracker, new Object[]
-                { trackerfocus.getConstructor(new Class[] { String.class })
-                        .newInstance(new Object[]
-                        { "Application Started." }) });
-      } catch (RuntimeException e)
-      {
-        re = e;
-      } catch (Exception e)
-      {
-        ex = e;
-      } catch (Error e)
-      {
-        err = e;
-      }
-      if (re != null || ex != null || err != null)
-      {
-        if (re != null)
-        {
-          Console.debug("Caught runtime exception in googletracker init:",
-                  re);
-        }
-        if (ex != null)
-        {
-          Console.warn(
-                  "Failed to initialise GoogleTracker for Jalview Desktop with version "
-                          + vrs,
-                  ex);
-        }
-        if (err != null)
-        {
-          Console.error(
-                  "Whilst initing GoogleTracker for Jalview Desktop version "
-                          + vrs,
-                  err);
-        }
-      }
-      else
-      {
-        Console.debug("Successfully initialised tracker.");
-      }
+      path = "/" + String.join("/", URLEncoder.encode(appName, "UTF-8"),
+              URLEncoder.encode(version, "UTF-8"),
+              URLEncoder.encode(APPLICATION_STARTED, "UTF-8"));
+    } catch (UnsupportedEncodingException e)
+    {
+    */
+    List<String> pathParts = new ArrayList<>();
+    pathParts.add(appName);
+    pathParts.add(version);
+    pathParts.add(APPLICATION_STARTED);
+    path = ("/" + String.join("/", pathParts)).replace(' ', '+');
+    /*
     }
+    */
+    Plausible plausible = Plausible.getInstance();
+
+    // This will send a new "application_launch" event with parameters
+    // including the old-style "path", the channel name and version
+    plausible.sendEvent("application_launch", path, true);
   }
 
+  private static final String APPLICATION_STARTED = "Application Started";
+
   /**
    * get the user's default colour if available
    * 
@@ -1058,7 +1064,7 @@ public class Cache
         return date_format.parse(val);
       } catch (Exception ex)
       {
-        System.err.println("Invalid or corrupt date in property '"
+        jalview.bin.Console.errPrintln("Invalid or corrupt date in property '"
                 + propertyName + "' : value was '" + val + "'");
       }
     }
@@ -1082,7 +1088,7 @@ public class Cache
         return Integer.valueOf(val);
       } catch (NumberFormatException x)
       {
-        System.err.println("Invalid integer in property '" + property
+        jalview.bin.Console.errPrintln("Invalid integer in property '" + property
                 + "' (value was '" + val + "')");
       }
     }
@@ -1146,7 +1152,9 @@ public class Cache
         }
       } catch (Exception ex)
       {
-        System.out.println("Error loading User ColourFile\n" + ex);
+        if (!Jalview.quiet())
+          jalview.bin.Console
+                  .outPrintln("Error loading User ColourFile\n" + ex);
       }
     }
     if (!files.equals(coloursFound.toString()))
@@ -1622,7 +1630,8 @@ public class Cache
   }
 
   private static final Collection<String> bootstrapProperties = new ArrayList<>(
-          Arrays.asList(JALVIEWLOGLEVEL));
+          Arrays.asList(JALVIEWLOGLEVEL, BOOTSTRAP_TEST));
+
 
   public static Properties bootstrapProperties(String filename)
   {
@@ -1648,9 +1657,11 @@ public class Cache
       file = new File(releasePropertiesFilename);
     }
 
-    if (filename == null || !file.exists())
+    if (filename == null)
+      return null;
+    if (!file.exists())
     {
-      System.err.println("Could not load bootstrap preferences file '"
+      jalview.bin.Console.errPrintln("Could not load bootstrap preferences file '"
               + filename + "'");
       return null;
     }
@@ -1667,14 +1678,27 @@ public class Cache
       }
     } catch (FileNotFoundException e)
     {
-      System.err.println("Could not find bootstrap preferences file '"
+      jalview.bin.Console.errPrintln("Could not find bootstrap preferences file '"
               + file.getAbsolutePath() + "'");
     } catch (IOException e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "IOException when loading bootstrap preferences file '"
                       + file.getAbsolutePath() + "'");
     }
     return bootstrapProps;
   }
+
+  public static void setSessionProperty(String key, String val)
+  {
+    if (key != null)
+    {
+      sessionProperties.put(key, val);
+    }
+  }
+
+  public static String getSessionProperty(String key)
+  {
+    return key == null ? null : sessionProperties.get(key);
+  }
 }
index b42f08e..8164182 100644 (file)
@@ -2,6 +2,7 @@ package jalview.bin;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -12,138 +13,162 @@ import java.util.Locale;
 import java.util.Map;
 
 import jalview.analysis.AlignmentUtils;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.ArgParser.Arg;
-import jalview.bin.ArgParser.ArgValue;
-import jalview.bin.ArgParser.ArgValuesMap;
-import jalview.bin.ArgParser.SubVals;
-import jalview.datamodel.AlignmentAnnotation;
+import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.bin.argparser.Arg;
+import jalview.bin.argparser.ArgParser;
+import jalview.bin.argparser.ArgParser.Position;
+import jalview.bin.argparser.ArgValue;
+import jalview.bin.argparser.ArgValuesMap;
+import jalview.bin.argparser.SubVals;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.annotations.AlphaFoldAnnotationRowBuilder;
 import jalview.gui.AlignFrame;
 import jalview.gui.AlignmentPanel;
-import jalview.gui.AssociatePdbFileWithSeq;
+import jalview.gui.AppJmol;
 import jalview.gui.Desktop;
 import jalview.gui.Preferences;
 import jalview.gui.StructureChooser;
 import jalview.gui.StructureViewer;
+import jalview.gui.StructureViewer.ViewerType;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.BackupFiles;
+import jalview.io.BioJsHTMLOutput;
 import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
 import jalview.io.FileFormatException;
 import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
 import jalview.io.FileLoader;
 import jalview.io.HtmlSvgOutput;
 import jalview.io.IdentifyFile;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.structure.StructureImportSettings;
+import jalview.io.NewickFile;
+import jalview.io.exceptions.ImageOutputException;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
 import jalview.structure.StructureImportSettings.TFType;
 import jalview.structure.StructureSelectionManager;
+import jalview.util.FileUtils;
 import jalview.util.HttpUtils;
+import jalview.util.ImageMaker;
+import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
-import jalview.ws.dbsources.EBIAlfaFold;
-import mc_view.PDBChain;
+import jalview.util.imagemaker.BitmapImageSizing;
 
 public class Commands
 {
   Desktop desktop;
 
-  private static boolean headless;
+  private boolean headless;
 
-  private static ArgParser argParser;
+  private ArgParser argParser;
 
   private Map<String, AlignFrame> afMap;
 
-  private static boolean commandArgsProvided = false;
+  private Map<String, List<StructureViewer>> svMap;
 
-  public static boolean commandArgsProvided()
+  private boolean commandArgsProvided = false;
+
+  private boolean argsWereParsed = false;
+
+  public Commands(ArgParser argparser, boolean headless)
   {
-    return commandArgsProvided;
+    this(Desktop.instance, argparser, headless);
   }
 
-  public static boolean processArgs(ArgParser ap, boolean h)
+  public Commands(Desktop d, ArgParser argparser, boolean h)
   {
-    argParser = ap;
+    argParser = argparser;
     headless = h;
-    boolean argsWereParsed = true;
-    if (headless)
+    desktop = d;
+    afMap = new HashMap<>();
+  }
+
+  protected boolean processArgs()
+  {
+    if (argParser == null)
     {
-      System.setProperty("java.awt.headless", "true");
+      return true;
     }
 
-    if (argParser != null && argParser.linkedIds() != null)
+    boolean theseArgsWereParsed = false;
+
+    if (argParser != null && argParser.getLinkedIds() != null)
     {
-      for (String id : argParser.linkedIds())
+      for (String id : argParser.getLinkedIds())
       {
-        Commands cmds = new Commands();
-        if (id == null)
+        ArgValuesMap avm = argParser.getLinkedArgs(id);
+        theseArgsWereParsed = true;
+        boolean processLinkedOkay = processLinked(id);
+        theseArgsWereParsed &= processLinkedOkay;
+
+        processGroovyScript(id);
+
+        // wait around until alignFrame isn't busy
+        AlignFrame af = afMap.get(id);
+        while (af != null && af.getViewport().isCalcInProgress())
         {
-          cmds.processUnlinked(id);
-          argsWereParsed &= cmds.wereParsed();
+          try
+          {
+            Thread.sleep(25);
+          } catch (Exception q)
+          {
+          }
+          ;
         }
-        else
+
+        theseArgsWereParsed &= processImages(id);
+
+        if (processLinkedOkay)
+        {
+          theseArgsWereParsed &= processOutput(id);
+        }
+
+        // close ap
+        if (avm.getBoolean(Arg.CLOSE))
         {
-          cmds.processLinked(id);
-          argsWereParsed &= cmds.wereParsed();
+          af = afMap.get(id);
+          if (af != null)
+          {
+            af.closeMenuItem_actionPerformed(true);
+          }
         }
-        cmds.processImages(id);
-        argsWereParsed &= cmds.wereParsed();
+
       }
 
     }
-    if (argParser.getBool(Arg.QUIT))
+    if (argParser.getBoolean(Arg.QUIT))
     {
       Jalview.getInstance().quit();
       return true;
     }
     // carry on with jalview.bin.Jalview
+    argsWereParsed = theseArgsWereParsed;
     return argsWereParsed;
   }
 
-  boolean argsWereParsed = true; // set false as soon as an arg is found
-
-  private boolean wereParsed()
-  {
-    return argsWereParsed;
-  }
-
-  public Commands()
+  public boolean commandArgsProvided()
   {
-    this(Desktop.instance);
-  }
-
-  public Commands(Desktop d)
-  {
-    this.desktop = d;
-    afMap = new HashMap<String, AlignFrame>();
+    return commandArgsProvided;
   }
 
-  protected void processUnlinked(String id)
+  public boolean argsWereParsed()
   {
-    processLinked(id);
+    return argsWereParsed;
   }
 
-  protected void processLinked(String id)
+  protected boolean processLinked(String id)
   {
-    ArgValuesMap avm = argParser.linkedArgs(id);
+    boolean theseArgsWereParsed = false;
+    ArgValuesMap avm = argParser.getLinkedArgs(id);
     if (avm == null)
-      return;
-    else
-      argsWereParsed = false;
+      return true;
 
-    /*
-    // script to execute after all loading is completed one way or another
-    String groovyscript = m.get(Arg.GROOVY) == null ? null
-            : m.get(Arg.GROOVY).getValue();
-    String file = m.get(Arg.OPEN) == null ? null
-            : m.get(Arg.OPEN).getValue();
-    String data = null;
-    FileFormatI format = null;
-    DataSourceType protocol = null;
-    */
-    if (avm.containsArg(Arg.OPEN))
+    // set wrap scope here so it can be applied after structures are opened
+    boolean wrap = false;
+
+    if (avm.containsArg(Arg.APPEND) || avm.containsArg(Arg.OPEN))
     {
       commandArgsProvided = true;
       long progress = -1;
@@ -151,13 +176,22 @@ public class Commands
       boolean first = true;
       boolean progressBarSet = false;
       AlignFrame af;
-      for (ArgValue av : avm.getArgValueList(Arg.OPEN))
+      // Combine the APPEND and OPEN files into one list, along with whether it
+      // was APPEND or OPEN
+      List<ArgValue> openAvList = new ArrayList<>();
+      openAvList.addAll(avm.getArgValueList(Arg.OPEN));
+      openAvList.addAll(avm.getArgValueList(Arg.APPEND));
+      // sort avlist based on av.getArgIndex()
+      Collections.sort(openAvList);
+      for (ArgValue av : openAvList)
       {
+        Arg a = av.getArg();
+        SubVals sv = av.getSubVals();
         String openFile = av.getValue();
         if (openFile == null)
           continue;
 
-        argsWereParsed = true;
+        theseArgsWereParsed = true;
         if (first)
         {
           first = false;
@@ -183,6 +217,7 @@ public class Commands
             if (!(new File(openFile)).exists())
             {
               Console.warn("Can't find file '" + openFile + "'");
+              continue;
             }
           }
         }
@@ -197,109 +232,134 @@ public class Commands
         } catch (FileFormatException e1)
         {
           Console.error("Unknown file format for '" + openFile + "'");
+          continue;
         }
 
         af = afMap.get(id);
-        if (af == null)
+        // When to open a new AlignFrame
+        if (af == null || "true".equals(av.getSubVal("new"))
+                || a == Arg.OPEN || format == FileFormat.Jalview)
         {
-          /*
-           * this approach isn't working yet
-          // get default annotations before opening AlignFrame
-          if (m.get(Arg.SSANNOTATION) != null)
+          if (a == Arg.OPEN)
           {
-            Console.debug("***** SSANNOTATION="
-                    + m.get(Arg.SSANNOTATION).getBoolean());
+            Jalview.testoutput(argParser, Arg.OPEN, "examples/uniref50.fa",
+                    openFile);
           }
-          if (m.get(Arg.NOTEMPFAC) != null)
+
+          Console.debug(
+                  "Opening '" + openFile + "' in new alignment frame");
+          FileLoader fileLoader = new FileLoader(!headless);
+          boolean xception=false;
+          try {
+            af = fileLoader.LoadFileWaitTillLoaded(openFile, protocol,
+                    format);
+          } catch (Throwable thr)
           {
-            Console.debug(
-                    "***** NOTEMPFAC=" + m.get(Arg.NOTEMPFAC).getBoolean());
-          }
-          boolean showSecondaryStructure = (m.get(Arg.SSANNOTATION) != null)
-                  ? m.get(Arg.SSANNOTATION).getBoolean()
-                  : false;
-          boolean showTemperatureFactor = (m.get(Arg.NOTEMPFAC) != null)
-                  ? !m.get(Arg.NOTEMPFAC).getBoolean()
-                  : false;
-          Console.debug("***** tempfac=" + showTemperatureFactor
-                  + ", showSS=" + showSecondaryStructure);
-          StructureSelectionManager ssm = StructureSelectionManager
-                  .getStructureSelectionManager(Desktop.instance);
-          if (ssm != null)
-          {
-            ssm.setAddTempFacAnnot(showTemperatureFactor);
-            ssm.setProcessSecondaryStructure(showSecondaryStructure);
+            xception=true;
+            Console.error("Couldn't open '"+openFile+"' as "+format+" "+thr.getLocalizedMessage()+ " (Enable debug for full stack trace)");
+            Console.debug("Exception when opening '"+openFile+"'",thr);
           }
-           */
-
-          // get kind of temperature factor annotation
-          StructureImportSettings.TFType tempfacType = TFType.DEFAULT;
-          if ((!avm.getBoolean(Arg.NOTEMPFAC))
-                  && avm.containsArg(Arg.TEMPFAC))
+          finally
           {
-            try
-            {
-              tempfacType = StructureImportSettings.TFType
-                      .valueOf(avm.getArgValue(Arg.TEMPFAC).getValue()
-                              .toUpperCase(Locale.ROOT));
-              Console.debug("Obtained Temperature Factor type of '"
-                      + tempfacType + "'");
-            } catch (IllegalArgumentException e)
+            if (af==null && !xception)
             {
-              // Just an error message!
-              StringBuilder sb = new StringBuilder().append("Cannot set --")
-                      .append(Arg.TEMPFAC.getName()).append(" to '")
-                      .append(tempfacType)
-                      .append("', ignoring.  Valid values are: ");
-              Iterator<StructureImportSettings.TFType> it = Arrays
-                      .stream(StructureImportSettings.TFType.values())
-                      .iterator();
-              while (it.hasNext())
-              {
-                sb.append(it.next().toString().toLowerCase(Locale.ROOT));
-                if (it.hasNext())
-                  sb.append(", ");
-              }
-              Console.warn(sb.toString());
+              Console.info("Ignoring '"+openFile+"' - no alignment data found.");
+              continue;
             }
           }
 
-          Console.debug(
-                  "Opening '" + openFile + "' in new alignment frame");
-          FileLoader fileLoader = new FileLoader(!headless);
+          // colour alignment?
+          String colour = ArgParser.getFromSubValArgOrPref(avm, av,
+                  Arg.COLOUR, sv, null, "DEFAULT_COLOUR_PROT", "");
+          if ("" != colour)
+          {
+            ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
+                    af.getViewport(), af.getViewport().getAlignment(),
+                    colour);
 
-          StructureImportSettings.setTemperatureFactorType(tempfacType);
+            if (cs == null && !"None".equals(colour))
+            {
+              Console.warn(
+                      "Couldn't parse '" + colour + "' as a colourscheme.");
+            }
+            else
+            {
+              af.changeColour(cs);
+            }
+            Jalview.testoutput(argParser, Arg.COLOUR, "zappo", colour);
+          }
 
-          af = fileLoader.LoadFileWaitTillLoaded(openFile, protocol,
-                  format);
+          // Change alignment frame title
+          String title = ArgParser.getFromSubValArgOrPref(avm, av,
+                  Arg.TITLE, sv, null, null, null);
+          if (title != null)
+          {
+            af.setTitle(title);
+            Jalview.testoutput(argParser, Arg.TITLE, "test title", title);
+          }
 
-          // wrap alignment?
-          if (avm.getBoolean(Arg.WRAP))
+          // Add features
+          String featuresfile = ArgParser.getValueFromSubValOrArg(avm, av,
+                  Arg.FEATURES, sv);
+          if (featuresfile != null)
           {
-            af.getCurrentView().setWrapAlignment(true);
+            af.parseFeaturesFile(featuresfile,
+                    AppletFormatAdapter.checkProtocol(featuresfile));
+            Jalview.testoutput(argParser, Arg.FEATURES,
+                    "examples/testdata/plantfdx.features", featuresfile);
           }
 
-          // colour aligment?
-          if (avm.containsArg(Arg.COLOUR))
+          // Add annotations from file
+          String annotationsfile = ArgParser.getValueFromSubValOrArg(avm,
+                  av, Arg.ANNOTATIONS, sv);
+          if (annotationsfile != null)
           {
-            af.changeColour_actionPerformed(avm.getValue(Arg.COLOUR));
+            af.loadJalviewDataFile(annotationsfile, null, null, null);
+            Jalview.testoutput(argParser, Arg.ANNOTATIONS,
+                    "examples/testdata/plantfdx.annotations",
+                    annotationsfile);
           }
 
-          // change alignment frame title
-          if (avm.containsArg(Arg.TITLE))
-            af.setTitle(avm.getValue(Arg.TITLE));
+          // Set or clear the sortbytree flag
+          boolean sortbytree = ArgParser.getBoolFromSubValOrArg(avm,
+                  Arg.SORTBYTREE, sv);
+          if (sortbytree)
+          {
+            af.getViewport().setSortByTree(true);
+            Jalview.testoutput(argParser, Arg.SORTBYTREE);
+          }
 
-          /* hacky approach to hiding the annotations */
-          // show secondary structure annotations?
-          if (avm.getBoolean(Arg.SSANNOTATION))
+          // Load tree from file
+          String treefile = ArgParser.getValueFromSubValOrArg(avm, av,
+                  Arg.TREE, sv);
+          if (treefile != null)
           {
-            // do this better (annotation types?)
-            AlignmentUtils.showOrHideSequenceAnnotations(
-                    af.getCurrentView().getAlignment(),
-                    Collections.singleton("Secondary Structure"), null,
-                    false, false);
+            try
+            {
+              NewickFile nf = new NewickFile(treefile,
+                      AppletFormatAdapter.checkProtocol(treefile));
+              af.getViewport().setCurrentTree(
+                      af.showNewickTree(nf, treefile).getTree());
+              Jalview.testoutput(argParser, Arg.TREE,
+                      "examples/testdata/uniref50_test_tree", treefile);
+            } catch (IOException e)
+            {
+              Console.warn("Couldn't add tree " + treefile, e);
+            }
           }
 
+          // Show secondary structure annotations?
+          boolean showSSAnnotations = ArgParser.getFromSubValArgOrPref(avm,
+                  Arg.SHOWSSANNOTATIONS, av.getSubVals(), null,
+                  "STRUCT_FROM_PDB", true);
+          af.setAnnotationsVisibility(showSSAnnotations, true, false);
+
+          // Show sequence annotations?
+          boolean showAnnotations = ArgParser.getFromSubValArgOrPref(avm,
+                  Arg.SHOWANNOTATIONS, av.getSubVals(), null,
+                  "SHOW_ANNOTATIONS", true);
+          af.setAnnotationsVisibility(showAnnotations, false, true);
+
           // show temperature factor annotations?
           if (avm.getBoolean(Arg.NOTEMPFAC))
           {
@@ -311,30 +371,12 @@ public class Commands
                     af.getCurrentView().getAlignment(), hideThese, null,
                     false, false);
           }
-          else
-          /* comment out hacky approach up to here and add this line:
-           if (showTemperatureFactor)
-             */
-          {
-            if (avm.containsArg(Arg.TEMPFAC_LABEL))
-            {
-              AlignmentAnnotation aa = AlignmentUtils
-                      .getFirstSequenceAnnotationOfType(
-                              af.getCurrentView().getAlignment(),
-                              AlignmentAnnotation.LINE_GRAPH);
-              String label = avm.getValue(Arg.TEMPFAC_LABEL);
-              if (aa != null)
-              {
-                aa.label = label;
-              }
-              else
-              {
-                Console.info(
-                        "Could not find annotation to apply tempfac_label '"
-                                + label);
-              }
-            }
-          }
+
+          // wrap alignment? do this last for formatting reasons
+          wrap = ArgParser.getFromSubValArgOrPref(avm, Arg.WRAP, sv, null,
+                  "WRAP_ALIGNMENT", false);
+          // af.setWrapFormat(wrap) is applied after structures are opened for
+          // annotation reasons
 
           // store the AlignFrame for this id
           afMap.put(id, af);
@@ -346,25 +388,29 @@ public class Commands
                     .getStructureSelectionManager(Desktop.instance);
             SequenceI seq = af.alignPanel.getAlignment().getSequenceAt(0);
             ssm.computeMapping(false, new SequenceI[] { seq }, null,
-                    openFile, DataSourceType.FILE, null, null, null);
+                    openFile, DataSourceType.FILE, null, null, null, false);
           }
         }
         else
         {
           Console.debug(
                   "Opening '" + openFile + "' in existing alignment frame");
-          af.getCurrentView().addFile(new File(openFile), format);
+          DataSourceType dst = HttpUtils.startsWithHttpOrHttps(openFile)
+                  ? DataSourceType.URL
+                  : DataSourceType.FILE;
+          FileLoader fileLoader = new FileLoader(!headless);
+          fileLoader.LoadFile(af.getCurrentView(), openFile, dst, null,
+                  false);
         }
 
-        Console.debug("Command " + Arg.OPEN + " executed successfully!");
+        Console.debug("Command " + Arg.APPEND + " executed successfully!");
 
       }
       if (first) // first=true means nothing opened
       {
         if (headless)
         {
-          Console.error("Could not open any files in headless mode");
-          System.exit(1);
+          Jalview.exit("Could not open any files in headless mode", 1);
         }
         else
         {
@@ -386,38 +432,42 @@ public class Commands
         for (ArgValue av : avm.getArgValueList(Arg.STRUCTURE))
         {
           String val = av.getValue();
-          SubVals subId = new SubVals(val);
-          SequenceI seq = getSpecifiedSequence(af, subId);
+          SubVals subVals = av.getSubVals();
+          SequenceI seq = getSpecifiedSequence(af, avm, av);
           if (seq == null)
           {
-            Console.warn("Could not find sequence for argument --"
-                    + Arg.STRUCTURE + "=" + val);
+            // Could not find sequence from subId, let's assume the first
+            // sequence in the alignframe
+            AlignmentI al = af.getCurrentView().getAlignment();
+            seq = al.getSequenceAt(0);
+          }
+
+          if (seq == null)
+          {
+            Console.warn("Could not find sequence for argument "
+                    + Arg.STRUCTURE.argString() + "=" + val);
             // you probably want to continue here, not break
             // break;
             continue;
           }
           File structureFile = null;
-          if (subId.getContent() != null
-                  && subId.getContent().length() != 0)
+          if (subVals.getContent() != null
+                  && subVals.getContent().length() != 0)
           {
-            structureFile = new File(subId.getContent());
+            structureFile = new File(subVals.getContent());
             Console.debug("Using structure file (from argument) '"
                     + structureFile.getAbsolutePath() + "'");
           }
-
           // TRY THIS
           /*
-           PDBEntry fileEntry = new AssociatePdbFileWithSeq()
-                  .associatePdbWithSeq(selectedPdbFileName,
-                          DataSourceType.FILE, selectedSequence, true,
-                          Desktop.instance);
-                          
-           sViewer = launchStructureViewer(ssm, new PDBEntry[] { fileEntry },
-                  ap, new SequenceI[]
-                  { selectedSequence });
-          
+           * PDBEntry fileEntry = new AssociatePdbFileWithSeq()
+           * .associatePdbWithSeq(selectedPdbFileName, DataSourceType.FILE,
+           * selectedSequence, true, Desktop.instance);
+           * 
+           * sViewer = launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap, new
+           * SequenceI[] { selectedSequence });
+           * 
            */
-
           /* THIS DOESN'T WORK */
           else if (seq.getAllPDBEntries() != null
                   && seq.getAllPDBEntries().size() > 0)
@@ -444,10 +494,6 @@ public class Commands
           Console.debug("Using structure file "
                   + structureFile.getAbsolutePath());
 
-          PDBEntry fileEntry = new AssociatePdbFileWithSeq()
-                  .associatePdbWithSeq(structureFile.getAbsolutePath(),
-                          DataSourceType.FILE, seq, true, Desktop.instance);
-
           // open structure view
           AlignmentPanel ap = af.alignPanel;
           if (headless)
@@ -456,77 +502,207 @@ public class Commands
                     StructureViewer.ViewerType.JMOL.toString());
           }
 
-          // get tft, paeFilename, label?
-          /*
-          ArgValue tftAv = avm.getArgValuesReferringTo("structid", structId,
-                  Arg.TEMPFAC);
-           */
-          StructureChooser.openStructureFileForSequence(null, null, ap, seq,
-                  false, structureFile.getAbsolutePath(), null, null); // tft,
-                                                                       // paeFilename);
-        }
-      }
-    }
+          String structureFilepath = structureFile.getAbsolutePath();
 
-    // load a pAE file if given
-    if (avm.containsArg(Arg.PAEMATRIX))
-    {
-      AlignFrame af = afMap.get(id);
-      if (af != null)
-      {
-        for (ArgValue av : avm.getArgValueList(Arg.PAEMATRIX))
-        {
-          String val = av.getValue();
-          SubVals subVals = ArgParser.getSubVals(val);
-          File paeFile = new File(subVals.getContent());
-          String paePath = null;
-          try
+          // get PAEMATRIX file and label from subvals or Arg.PAEMATRIX
+          String paeFilepath = ArgParser
+                  .getFromSubValArgOrPrefWithSubstitutions(argParser, avm,
+                          Arg.PAEMATRIX, Position.AFTER, av, subVals, null,
+                          null, null);
+          if (paeFilepath != null)
           {
-            paePath = paeFile.getCanonicalPath();
-          } catch (IOException e)
+            File paeFile = new File(paeFilepath);
+
+            try
+            {
+              paeFilepath = paeFile.getCanonicalPath();
+            } catch (IOException e)
+            {
+              paeFilepath = paeFile.getAbsolutePath();
+              Console.warn("Problem with the PAE file path: '"
+                      + paeFile.getPath() + "'");
+            }
+          }
+
+          // showing annotations from structure file or not
+          boolean ssFromStructure = ArgParser.getFromSubValArgOrPref(avm,
+                  Arg.SHOWSSANNOTATIONS, subVals, null, "STRUCT_FROM_PDB",
+                  true);
+
+          // get TEMPFAC type from subvals or Arg.TEMPFAC in case user Adds
+          // reference annotations
+          String tftString = ArgParser
+                  .getFromSubValArgOrPrefWithSubstitutions(argParser, avm,
+                          Arg.TEMPFAC, Position.AFTER, av, subVals, null,
+                          null, null);
+          boolean notempfac = ArgParser.getFromSubValArgOrPref(avm,
+                  Arg.NOTEMPFAC, subVals, null, "ADD_TEMPFACT_ANN", false,
+                  true);
+          TFType tft = notempfac ? null : TFType.DEFAULT;
+          if (tftString != null && !notempfac)
           {
-            paePath = paeFile.getAbsolutePath();
-            Console.warn(
-                    "Problem with the PAE file path: '" + paePath + "'");
+            // get kind of temperature factor annotation
+            try
+            {
+              tft = TFType.valueOf(tftString.toUpperCase(Locale.ROOT));
+              Console.debug("Obtained Temperature Factor type of '" + tft
+                      + "' for structure '" + structureFilepath + "'");
+            } catch (IllegalArgumentException e)
+            {
+              // Just an error message!
+              StringBuilder sb = new StringBuilder().append("Cannot set ")
+                      .append(Arg.TEMPFAC.argString()).append(" to '")
+                      .append(tft)
+                      .append("', ignoring.  Valid values are: ");
+              Iterator<TFType> it = Arrays.stream(TFType.values())
+                      .iterator();
+              while (it.hasNext())
+              {
+                sb.append(it.next().toString().toLowerCase(Locale.ROOT));
+                if (it.hasNext())
+                  sb.append(", ");
+              }
+              Console.warn(sb.toString());
+            }
           }
-          String structId = subVals.get("structid");
-          if (subVals.notSet())
+
+          String sViewer = ArgParser.getFromSubValArgOrPref(avm,
+                  Arg.STRUCTUREVIEWER, Position.AFTER, av, subVals, null,
+                  null, "jmol");
+          ViewerType viewerType = ViewerType.getFromString(sViewer);
+
+          // TODO use ssFromStructure
+          StructureViewer sv = StructureChooser
+                  .openStructureFileForSequence(null, null, ap, seq, false,
+                          structureFilepath, tft, paeFilepath, false,
+                          ssFromStructure, false, viewerType);
+
+          if (sv == null)
           {
-            // take structid from pdbfilename
+            Console.error("Failed to import and open structure view.");
+            continue;
           }
-          if (subVals.has("structfile"))
+          try
           {
-            Console.info("***** Attaching paeFile '" + paePath + "' to "
-                    + "structfile=" + subVals.get("structfile"));
-            EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(),
-                    paeFile, subVals.getIndex(), subVals.get("structfile"),
-                    true, false);
+            long tries = 1000;
+            while (sv.isBusy() && tries > 0)
+            {
+              Thread.sleep(25);
+              if (sv.isBusy())
+              {
+                tries--;
+                Console.debug(
+                        "Waiting for viewer for " + structureFilepath);
+              }
+            }
+            if (tries == 0 && sv.isBusy())
+            {
+              Console.warn(
+                      "Gave up waiting for structure viewer to load. Something may have gone wrong.");
+            }
+          } catch (Exception x)
+          {
+            Console.warn("Exception whilst waiting for structure viewer "
+                    + structureFilepath, x);
           }
-          else if (subVals.has("structid"))
+
+          // add StructureViewer to svMap list
+          if (svMap == null)
           {
-            Console.info("***** Attaching paeFile '" + paePath + "' to "
-                    + "structid=" + subVals.get("structid"));
-            EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(),
-                    paeFile, subVals.getIndex(), subVals.get("structid"),
-                    true, true);
+            svMap = new HashMap<>();
           }
-          else
+          if (svMap.get(id) == null)
           {
-            Console.debug("***** Attaching paeFile '" + paePath
-                    + "' to sequence index " + subVals.getIndex());
-            EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(),
-                    paeFile, subVals.getIndex(), null, false, false);
-            // required to readjust the height and position of the pAE
-            // annotation
+            svMap.put(id, new ArrayList<>());
           }
-          for (AlignmentViewPanel ap : af.getAlignPanels())
+          svMap.get(id).add(sv);
+
+          Console.debug(
+                  "Successfully opened viewer for " + structureFilepath);
+          String structureImageFilename = ArgParser.getValueFromSubValOrArg(
+                  avm, av, Arg.STRUCTUREIMAGE, subVals);
+          if (sv != null && structureImageFilename != null)
           {
-            ap.adjustAnnotationHeight();
+            ArgValue siAv = avm.getClosestNextArgValueOfArg(av,
+                    Arg.STRUCTUREIMAGE);
+            SubVals sisv = null;
+            if (structureImageFilename.equals(siAv.getValue()))
+            {
+              sisv = siAv.getSubVals();
+            }
+            File structureImageFile = new File(structureImageFilename);
+            String width = ArgParser.getValueFromSubValOrArg(avm, av,
+                    Arg.STRUCTUREIMAGEWIDTH, sisv);
+            String height = ArgParser.getValueFromSubValOrArg(avm, av,
+                    Arg.STRUCTUREIMAGEHEIGHT, sisv);
+            String scale = ArgParser.getValueFromSubValOrArg(avm, av,
+                    Arg.STRUCTUREIMAGESCALE, sisv);
+            String renderer = ArgParser.getValueFromSubValOrArg(avm, av,
+                    Arg.STRUCTUREIMAGETEXTRENDERER, sisv);
+            String typeS = ArgParser.getValueFromSubValOrArg(avm, av,
+                    Arg.STRUCTUREIMAGETYPE, sisv);
+            if (typeS == null || typeS.length() == 0)
+            {
+              typeS = FileUtils.getExtension(structureImageFile);
+            }
+            TYPE imageType;
+            try
+            {
+              imageType = Enum.valueOf(TYPE.class,
+                      typeS.toUpperCase(Locale.ROOT));
+            } catch (IllegalArgumentException e)
+            {
+              Console.warn("Do not know image format '" + typeS
+                      + "', using PNG");
+              imageType = TYPE.PNG;
+            }
+            BitmapImageSizing userBis = ImageMaker
+                    .parseScaleWidthHeightStrings(scale, width, height);
+            // TODO MAKE THIS VIEWER INDEPENDENT!!
+            switch (StructureViewer.getViewerType())
+            {
+            case JMOL:
+              JalviewStructureDisplayI sview = sv
+                      .getJalviewStructureDisplay();
+              if (sview instanceof AppJmol)
+              {
+                AppJmol jmol = (AppJmol) sview;
+                try
+                {
+                  Console.debug("Rendering image to " + structureImageFile);
+                  jmol.makePDBImage(structureImageFile, imageType, renderer,
+                          userBis);
+                  Console.debug("Finished Rendering image to "
+                          + structureImageFile);
+
+                } catch (ImageOutputException ioexc)
+                {
+                  Console.warn("Unexpected error whilst exporting image to "
+                          + structureImageFile, ioexc);
+                }
+
+              }
+              break;
+            default:
+              Console.warn("Cannot export image for structure viewer "
+                      + sv.getViewerType() + " yet");
+              break;
+            }
           }
         }
       }
     }
 
+    if (wrap)
+    {
+      AlignFrame af = afMap.get(id);
+      if (af != null)
+      {
+        af.setWrapFormat(wrap, true);
+      }
+    }
+
+    /*
     boolean doShading = avm.getBoolean(Arg.TEMPFAC_SHADING);
     if (doShading)
     {
@@ -541,11 +717,14 @@ public class Commands
         Console.info("Changed colour " + acg.toString());
       }
     }
+    */
+
+    return theseArgsWereParsed;
   }
 
-  protected void processImages(String id)
+  protected void processGroovyScript(String id)
   {
-    ArgValuesMap avm = argParser.linkedArgs(id);
+    ArgValuesMap avm = argParser.getLinkedArgs(id);
     AlignFrame af = afMap.get(id);
 
     if (af == null)
@@ -554,22 +733,58 @@ public class Commands
       return;
     }
 
+    if (avm.containsArg(Arg.GROOVY))
+    {
+      String groovyscript = avm.getValue(Arg.GROOVY);
+      if (groovyscript != null)
+      {
+        // Execute the groovy script after we've done all the rendering stuff
+        // and before any images or figures are generated.
+        Console.info("Executing script " + groovyscript);
+        Jalview.getInstance().executeGroovyScript(groovyscript, af);
+      }
+    }
+  }
+
+  protected boolean processImages(String id)
+  {
+    ArgValuesMap avm = argParser.getLinkedArgs(id);
+    AlignFrame af = afMap.get(id);
+
+    if (af == null)
+    {
+      Console.warn("Did not have an alignment window for id=" + id);
+      return false;
+    }
+
     if (avm.containsArg(Arg.IMAGE))
     {
       for (ArgValue av : avm.getArgValueList(Arg.IMAGE))
       {
         String val = av.getValue();
-        SubVals subVal = new SubVals(val);
-        String type = "png"; // default
+        SubVals subVal = av.getSubVals();
         String fileName = subVal.getContent();
         File file = new File(fileName);
-        if (subVal.has("type"))
-        {
-          type = subVal.get("type");
-        }
-        else if (fileName != null)
+        String name = af.getName();
+        String renderer = ArgParser.getValueFromSubValOrArg(avm, av,
+                Arg.TEXTRENDERER, subVal);
+        if (renderer == null)
+          renderer = "text";
+        String type = "png"; // default
+
+        String scale = ArgParser.getValueFromSubValOrArg(avm, av, Arg.SCALE,
+                subVal);
+        String width = ArgParser.getValueFromSubValOrArg(avm, av, Arg.WIDTH,
+                subVal);
+        String height = ArgParser.getValueFromSubValOrArg(avm, av,
+                Arg.HEIGHT, subVal);
+        BitmapImageSizing userBis = ImageMaker
+                .parseScaleWidthHeightStrings(scale, width, height);
+
+        type = ArgParser.getValueFromSubValOrArg(avm, av, Arg.TYPE, subVal);
+        if (type == null && fileName != null)
         {
-          for (String ext : new String[] { "svg", "png", "html" })
+          for (String ext : new String[] { "svg", "png", "html", "eps" })
           {
             if (fileName.toLowerCase(Locale.ROOT).endsWith("." + ext))
             {
@@ -581,41 +796,252 @@ public class Commands
         Cache.setPropsAreReadOnly(true);
         Cache.setProperty("EXPORT_EMBBED_BIOJSON", "false");
 
-        switch (type)
+        Console.info("Writing " + file);
+        try
+        {
+          switch (type)
+          {
+
+          case "svg":
+            Console.debug("Outputting type '" + type + "' to " + fileName);
+            af.createSVG(file, renderer);
+            break;
+
+          case "png":
+            Console.debug("Outputting type '" + type + "' to " + fileName);
+            af.createPNG(file, null, userBis);
+            break;
+
+          case "html":
+            Console.debug("Outputting type '" + type + "' to " + fileName);
+            HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
+            htmlSVG.exportHTML(fileName, renderer);
+            break;
+
+          case "biojs":
+            Console.debug(
+                    "Outputting BioJS MSA Viwer HTML file: " + fileName);
+            try
+            {
+              BioJsHTMLOutput.refreshVersionInfo(
+                      BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
+            } catch (URISyntaxException e)
+            {
+              e.printStackTrace();
+            }
+            BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
+            bjs.exportHTML(fileName);
+            break;
+
+          case "eps":
+            Console.debug("Outputting EPS file: " + fileName);
+            af.createEPS(file, renderer);
+            break;
+
+          case "imagemap":
+            Console.debug("Outputting ImageMap file: " + fileName);
+            af.createImageMap(file, name);
+            break;
+
+          default:
+            Console.warn(Arg.IMAGE.argString() + " type '" + type
+                    + "' not known. Ignoring");
+            break;
+          }
+        } catch (Exception ioex)
+        {
+          Console.warn("Unexpected error during export", ioex);
+        }
+      }
+    }
+    return true;
+  }
+
+  protected boolean processOutput(String id)
+  {
+    ArgValuesMap avm = argParser.getLinkedArgs(id);
+    AlignFrame af = afMap.get(id);
+
+    if (af == null)
+    {
+      Console.warn("Did not have an alignment window for id=" + id);
+      return false;
+    }
+
+    if (avm.containsArg(Arg.OUTPUT))
+    {
+      for (ArgValue av : avm.getArgValueList(Arg.OUTPUT))
+      {
+        String val = av.getValue();
+        SubVals subVals = av.getSubVals();
+        String fileName = subVals.getContent();
+        boolean stdout = ArgParser.STDOUTFILENAME.equals(fileName);
+        File file = new File(fileName);
+        boolean overwrite = ArgParser.getFromSubValArgOrPref(avm,
+                Arg.OVERWRITE, subVals, null, "OVERWRITE_OUTPUT", false);
+        // backups. Use the Arg.BACKUPS or subval "backups" setting first,
+        // otherwise if headless assume false, if not headless use the user
+        // preference with default true.
+        boolean backups = ArgParser.getFromSubValArgOrPref(avm, Arg.BACKUPS,
+                subVals, null,
+                Platform.isHeadless() ? null : BackupFiles.ENABLED,
+                !Platform.isHeadless());
+
+        // if backups is not true then --overwrite must be specified
+        if (file.exists() && !(overwrite || backups || stdout))
+        {
+          Console.error("Won't overwrite file '" + fileName + "' without "
+                  + Arg.OVERWRITE.argString() + " or "
+                  + Arg.BACKUPS.argString() + " set");
+          return false;
+        }
+
+        String name = af.getName();
+        String format = ArgParser.getValueFromSubValOrArg(avm, av,
+                Arg.FORMAT, subVals);
+        FileFormats ffs = FileFormats.getInstance();
+        List<String> validFormats = ffs.getWritableFormats(false);
+
+        FileFormatI ff = null;
+        if (format == null && fileName != null)
+        {
+          FORMAT: for (String fname : validFormats)
+          {
+            FileFormatI tff = ffs.forName(fname);
+            String[] extensions = tff.getExtensions().split(",");
+            for (String ext : extensions)
+            {
+              if (fileName.toLowerCase(Locale.ROOT).endsWith("." + ext))
+              {
+                ff = tff;
+                format = ff.getName();
+                break FORMAT;
+              }
+            }
+          }
+        }
+        if (ff == null && format != null)
         {
-        case "svg":
-          Console.debug("Outputting type '" + type + "' to " + fileName);
-          af.createSVG(file);
-          break;
-        case "png":
-          Console.debug("Outputting type '" + type + "' to " + fileName);
-          af.createPNG(file);
-          break;
-        case "html":
-          Console.debug("Outputting type '" + type + "' to " + fileName);
-          HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
-          htmlSVG.exportHTML(fileName);
-          break;
-        default:
-          Console.warn("--image type '" + type + "' not known. Ignoring");
-          break;
+          ff = ffs.forName(format);
         }
+        if (ff == null)
+        {
+          if (stdout)
+          {
+            ff = FileFormat.Fasta;
+          }
+          else
+          {
+            StringBuilder validSB = new StringBuilder();
+            for (String f : validFormats)
+            {
+              if (validSB.length() > 0)
+                validSB.append(", ");
+              validSB.append(f);
+              FileFormatI tff = ffs.forName(f);
+              validSB.append(" (");
+              validSB.append(tff.getExtensions());
+              validSB.append(")");
+            }
+
+            Jalview.exit("No valid format specified for "
+                    + Arg.OUTPUT.argString() + ". Valid formats are "
+                    + validSB.toString() + ".", 1);
+            // this return really shouldn't happen
+            return false;
+          }
+        }
+
+        String savedBackupsPreference = Cache
+                .getDefault(BackupFiles.ENABLED, null);
+        Console.debug("Setting backups to " + backups);
+        Cache.applicationProperties.put(BackupFiles.ENABLED,
+                Boolean.toString(backups));
+
+        Console.info("Writing " + fileName);
+
+        af.saveAlignment(fileName, ff, stdout);
+        Console.debug("Returning backups to " + savedBackupsPreference);
+        if (savedBackupsPreference != null)
+          Cache.applicationProperties.put(BackupFiles.ENABLED,
+                  savedBackupsPreference);
+        if (af.isSaveAlignmentSuccessful())
+        {
+          Console.debug("Written alignment '" + name + "' in "
+                  + ff.getName() + " format to " + file);
+        }
+        else
+        {
+          Console.warn("Error writing file " + file + " in " + ff.getName()
+                  + " format!");
+        }
+
       }
     }
+    return true;
   }
 
-  private SequenceI getSpecifiedSequence(AlignFrame af, SubVals subId)
+  private SequenceI getSpecifiedSequence(AlignFrame af, ArgValuesMap avm,
+          ArgValue av)
   {
+    SubVals subVals = av.getSubVals();
+    ArgValue idAv = avm.getClosestNextArgValueOfArg(av, Arg.SEQID);
+    SequenceI seq = null;
+    if (subVals == null && idAv == null)
+      return null;
+    if (af == null || af.getCurrentView() == null)
+    {
+      return null;
+    }
     AlignmentI al = af.getCurrentView().getAlignment();
-    if (-1 < subId.getIndex()
-            && subId.getIndex() < al.getSequences().size())
+    if (al == null)
     {
-      return al.getSequenceAt(subId.getIndex());
+      return null;
     }
-    else if (subId.has("seqid"))
+    if (subVals != null)
     {
-      return al.findName(subId.get("seqid"));
+      if (subVals.has(Arg.SEQID.getName()))
+      {
+        seq = al.findName(subVals.get(Arg.SEQID.getName()));
+      }
+      else if (-1 < subVals.getIndex()
+              && subVals.getIndex() < al.getSequences().size())
+      {
+        seq = al.getSequenceAt(subVals.getIndex());
+      }
+    }
+    if (seq == null && idAv != null)
+    {
+      seq = al.findName(idAv.getValue());
+    }
+    return seq;
+  }
+
+  public AlignFrame[] getAlignFrames()
+  {
+    AlignFrame[] afs = null;
+    if (afMap != null)
+    {
+      afs = (AlignFrame[]) afMap.values().toArray();
+    }
+
+    return afs;
+  }
+
+  public List<StructureViewer> getStructureViewers()
+  {
+    List<StructureViewer> svs = null;
+    if (svMap != null)
+    {
+      for (List<StructureViewer> svList : svMap.values())
+      {
+        if (svs == null)
+        {
+          svs = new ArrayList<>();
+        }
+        svs.addAll(svList);
+      }
     }
-    return null;
+    return svs;
   }
 }
index b868e7b..1b230ec 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.bin;
 
+import java.io.PrintStream;
 import java.util.Locale;
 
 import jalview.log.JLogger;
@@ -43,8 +44,8 @@ public class Console
     }
     else
     {
-      System.out.println(message);
-      t.printStackTrace();
+      outPrintln(message);
+      Console.printStackTrace(t);
     }
 
   }
@@ -57,7 +58,7 @@ public class Console
     }
     else
     {
-      System.out.println(message);
+      outPrintln(message);
     }
 
   }
@@ -70,8 +71,8 @@ public class Console
     }
     else
     {
-      System.out.println(message);
-      t.printStackTrace();
+      outPrintln(message);
+      Console.printStackTrace(t);
     }
   }
 
@@ -83,7 +84,7 @@ public class Console
     }
     else
     {
-      System.out.println(message);
+      outPrintln(message);
     }
 
   }
@@ -96,8 +97,8 @@ public class Console
     }
     else
     {
-      System.out.println(message);
-      t.printStackTrace();
+      outPrintln(message);
+      Console.printStackTrace(t);
     }
 
   }
@@ -110,7 +111,7 @@ public class Console
     }
     else
     {
-      System.out.println(message);
+      outPrintln(message);
     }
 
   }
@@ -123,7 +124,7 @@ public class Console
     }
     else
     {
-      System.out.println(message);
+      outPrintln(message);
     }
   }
 
@@ -135,8 +136,8 @@ public class Console
     }
     else
     {
-      System.out.println(message);
-      t.printStackTrace();
+      outPrintln(message);
+      Console.printStackTrace(t);
     }
 
   }
@@ -149,7 +150,7 @@ public class Console
     }
     else
     {
-      System.err.println(message);
+      jalview.bin.Console.errPrintln(message);
     }
 
   }
@@ -162,8 +163,8 @@ public class Console
     }
     else
     {
-      System.err.println(message);
-      t.printStackTrace(System.err);
+      jalview.bin.Console.errPrintln(message);
+      Console.printStackTrace(t);
     }
 
   }
@@ -176,7 +177,7 @@ public class Console
     }
     else
     {
-      System.err.println(message);
+      jalview.bin.Console.errPrintln(message);
     }
 
   }
@@ -189,8 +190,8 @@ public class Console
     }
     else
     {
-      System.err.println(message);
-      t.printStackTrace(System.err);
+      jalview.bin.Console.errPrintln(message);
+      Console.printStackTrace(t);
     }
 
   }
@@ -220,6 +221,11 @@ public class Console
     return JLogger.toLevel(level);
   }
 
+  public static JLogger getLogger()
+  {
+    return log;
+  }
+
   public static boolean initLogger()
   {
     return initLogger(null);
@@ -236,14 +242,21 @@ public class Console
       JLogger.LogLevel logLevel = JLogger.LogLevel.INFO;
 
       if (JLogger.isLevel(providedLogLevel))
+      {
         logLevel = Console.getLogLevel(providedLogLevel);
+      }
       else
+      {
         logLevel = getCachedLogLevel();
+      }
 
       if (!Platform.isJS())
       {
-        System.err
-                .println("Setting initial log level to " + logLevel.name());
+        if (!Jalview.quiet())
+        {
+          jalview.bin.Console.errPrintln(
+                  "Setting initial log level to " + logLevel.name());
+        }
         Log4j.init(logLevel);
       }
       // log output
@@ -255,8 +268,9 @@ public class Console
       log = JLoggerLog4j.getLogger(Cache.JALVIEW_LOGGER_NAME, logLevel);
     } catch (NoClassDefFoundError e)
     {
-      System.err.println("Could not initialise the logger framework");
-      e.printStackTrace();
+      jalview.bin.Console
+              .errPrintln("Could not initialise the logger framework");
+      Console.printStackTrace(e);
     }
 
     // Test message
@@ -294,6 +308,96 @@ public class Console
     }
   }
 
+  public static void outPrint()
+  {
+    outPrint("");
+  }
+
+  public static void outPrintln()
+  {
+    outPrintln("");
+  }
+
+  public static void outPrint(Object message)
+  {
+    outPrintMessage(message, false, false);
+  }
+
+  public static void outPrint(Object message, boolean forceStdout)
+  {
+    outPrintMessage(message, false, forceStdout);
+  }
+
+  public static void outPrintln(Object message)
+  {
+    outPrintMessage(message, true, false);
+  }
+
+  public static PrintStream outputStream(boolean forceStdout)
+  {
+    // send message to stderr if an output file to stdout is expected
+    if (!forceStdout && Jalview.getInstance() != null
+            && Jalview.getInstance().getBootstrapArgs() != null
+            && Jalview.getInstance().getBootstrapArgs().outputToStdout())
+    {
+      return System.err;
+    }
+    else
+    {
+      return System.out;
+    }
+  }
+
+  public static void outPrintMessage(Object message, boolean newline,
+          boolean forceStdout)
+  {
+    PrintStream ps = outputStream(forceStdout);
+    if (newline)
+    {
+      ps.println(message);
+    }
+    else
+    {
+      ps.print(message);
+    }
+  }
+
+  public static void errPrint()
+  {
+    errPrint("");
+  }
+
+  public static void errPrintln()
+  {
+    errPrintln("");
+  }
+
+  public static void errPrint(Object message)
+  {
+    System.err.print(message);
+  }
+
+  public static void errPrintln(Object message)
+  {
+    System.err.println(message);
+  }
+
+  public static void debugPrintStackTrace(Throwable t)
+  {
+    if (!isDebugEnabled())
+    {
+      return;
+    }
+    // send message to stderr if output to stdout is expected
+    printStackTrace(t);
+  }
+
+  public static void printStackTrace(Throwable t)
+  {
+    // send message to stderr if output to stdout is expected
+    t.printStackTrace(System.err);
+  }
+
   public final static String LOGGING_TEST_MESSAGE = "Logging to STDERR";
 
-}
+}
\ No newline at end of file
index b01dfb8..5332704 100644 (file)
@@ -61,7 +61,7 @@ class GetMemory
     } catch (NoClassDefFoundError e)
     {
       // com.sun.management.OperatingSystemMXBean doesn't exist in this JVM
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "No com.sun.management.OperatingSystemMXBean: cannot get total physical memory size");
     }
 
index 2bce673..e14c032 100644 (file)
@@ -20,9 +20,8 @@
  */
 package jalview.bin;
 
-import java.util.Locale;
-
 import java.awt.HeadlessException;
+import java.util.Locale;
 
 public class HiDPISetting
 {
@@ -117,8 +116,9 @@ public class HiDPISetting
         }
       } catch (NumberFormatException e)
       {
-        System.err.println(setHiDPIScalePropertyName + " property give ("
-                + setHiDPIScaleProperty + ") but not parseable as integer");
+        jalview.bin.Console.errPrintln(setHiDPIScalePropertyName
+                + " property give (" + setHiDPIScaleProperty
+                + ") but not parseable as integer");
       }
     }
     if (setHiDPI && setHiDPIScale > 0)
@@ -135,8 +135,8 @@ public class HiDPISetting
       try
       {
         int existingPropertyVal = Integer.parseInt(existingProperty);
-        System.out.println("Existing " + scalePropertyName + " is "
-                + existingPropertyVal);
+        jalview.bin.Console.outPrintln("Existing " + scalePropertyName
+                + " is " + existingPropertyVal);
         if (existingPropertyVal > 1)
         {
           setHiDPIScale(existingPropertyVal);
@@ -144,8 +144,9 @@ public class HiDPISetting
         }
       } catch (NumberFormatException e)
       {
-        System.out.println("Could not convert property " + scalePropertyName
-                + " vale '" + existingProperty + "' to number");
+        jalview.bin.Console.outPrintln(
+                "Could not convert property " + scalePropertyName
+                        + " vale '" + existingProperty + "' to number");
       }
     }
 
@@ -159,7 +160,11 @@ public class HiDPISetting
       dpi = screenInfo.getScreenResolution();
     } catch (HeadlessException e)
     {
-      System.err.println("Cannot get screen resolution: " + e.getMessage());
+      if (isLinux)
+      {
+        jalview.bin.Console.errPrintln(
+                "Cannot get screen resolution: " + e.getMessage());
+      }
     }
 
     // try and get screen size height and width
@@ -171,8 +176,12 @@ public class HiDPISetting
       mindimension = Math.min(height, width);
     } catch (HeadlessException e)
     {
-      System.err.println(
-              "Cannot get screen size height and width:" + e.getMessage());
+      if (isLinux)
+      {
+        jalview.bin.Console
+                .errPrintln("Cannot get screen size height and width:"
+                        + e.getMessage());
+      }
     }
 
     // attempt at a formula for scaling based on screen dpi and mindimension.
index c792a96..eabad91 100755 (executable)
@@ -26,7 +26,9 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
 import java.io.OutputStreamWriter;
+import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.net.MalformedURLException;
 import java.net.URI;
@@ -37,7 +39,9 @@ import java.security.CodeSource;
 import java.security.PermissionCollection;
 import java.security.Permissions;
 import java.security.Policy;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
@@ -45,9 +49,11 @@ import java.util.Vector;
 import java.util.logging.ConsoleHandler;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.stream.Collectors;
 
 import javax.swing.JDialog;
 import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
 import javax.swing.JOptionPane;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
@@ -62,13 +68,18 @@ import com.threerings.getdown.util.LaunchUtil;
 //import edu.stanford.ejalbert.launching.IBrowserLaunching;
 import groovy.lang.Binding;
 import groovy.util.GroovyScriptEngine;
-import jalview.bin.ArgParser.Arg;
+import jalview.bin.argparser.Arg;
+import jalview.bin.argparser.Arg.Opt;
+import jalview.bin.argparser.Arg.Type;
+import jalview.bin.argparser.ArgParser;
+import jalview.bin.argparser.BootstrapArgs;
 import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
 import jalview.gui.PromptUserConfig;
 import jalview.gui.QuitHandler;
 import jalview.gui.QuitHandler.QResponse;
+import jalview.gui.StructureViewerBase;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
 import jalview.io.DataSourceType;
@@ -80,6 +91,7 @@ import jalview.io.FileLoader;
 import jalview.io.HtmlSvgOutput;
 import jalview.io.IdentifyFile;
 import jalview.io.NewickFile;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.io.gff.SequenceOntologyFactory;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
@@ -123,8 +135,21 @@ public class Jalview
 
   private Desktop desktop;
 
+  protected Commands cmds;
+
   public static AlignFrame currentAlignFrame;
 
+  private ArgParser argparser = null;
+
+  private BootstrapArgs bootstrapArgs = null;
+
+  private boolean QUIET = false;
+
+  public static boolean quiet()
+  {
+    return Jalview.getInstance() != null && Jalview.getInstance().QUIET;
+  }
+
   static
   {
     if (!Platform.isJS())
@@ -249,7 +274,7 @@ public class Jalview
      * 
      */
     {
-      System.out.println("not in js");
+      Console.outPrintln("not in js");
     }
 
     // BH - for event debugging in JavaScript (Java mode only)
@@ -275,37 +300,114 @@ public class Jalview
    */
   void doMain(String[] args)
   {
-
     if (!Platform.isJS())
     {
       System.setSecurityManager(null);
     }
 
+    if (args == null || args.length == 0 || (args.length == 1
+            && (args[0] == null || args[0].length() == 0)))
+    {
+      args = new String[] {};
+    }
+
     // get args needed before proper ArgParser
-    Map<ArgParser.Arg, String> bootstrapArgs = ArgParser
-            .bootstrapArgs(args);
+    bootstrapArgs = BootstrapArgs.getBootstrapArgs(args);
 
-    System.out
-            .println("Java version: " + System.getProperty("java.version"));
-    System.out.println("Java Home: " + System.getProperty("java.home"));
-    System.out.println(System.getProperty("os.arch") + " "
-            + System.getProperty("os.name") + " "
-            + System.getProperty("os.version"));
+    if (!Platform.isJS())
+    {
+      // are we being --quiet ?
+      if (bootstrapArgs.contains(Arg.QUIET))
+      {
+        QUIET = true;
+        OutputStream devNull = new OutputStream()
+        {
 
-    String val = System.getProperty("sys.install4jVersion");
-    if (val != null)
+          @Override
+          public void write(int b)
+          {
+            // DO NOTHING
+          }
+        };
+        System.setOut(new PrintStream(devNull));
+        // redirecting stderr not working
+        if (bootstrapArgs.getList(Arg.QUIET).size() > 1)
+        {
+          System.setErr(new PrintStream(devNull));
+        }
+      }
+
+      if (bootstrapArgs.contains(Arg.HELP)
+              || bootstrapArgs.contains(Arg.VERSION))
+      {
+        QUIET = true;
+      }
+    }
+
+    // set individual session preferences
+    if (bootstrapArgs.contains(Arg.P))
     {
-      System.out.println("Install4j version: " + val);
+      for (String kev : bootstrapArgs.getValueList(Arg.P))
+      {
+        if (kev == null)
+        {
+          continue;
+        }
+        int equalsIndex = kev.indexOf(ArgParser.EQUALS);
+        if (equalsIndex > -1)
+        {
+          String key = kev.substring(0, equalsIndex);
+          String val = kev.substring(equalsIndex + 1);
+          Cache.setSessionProperty(key, val);
+        }
+      }
     }
-    val = System.getProperty("installer_template_version");
-    if (val != null)
+
+    // Move any new getdown-launcher-new.jar into place over old
+    // getdown-launcher.jar
+    String appdirString = System.getProperty("getdownappdir");
+    if (appdirString != null && appdirString.length() > 0)
     {
-      System.out.println("Install4j template version: " + val);
+      final File appdir = new File(appdirString);
+      new Thread()
+      {
+
+        @Override
+        public void run()
+        {
+          LaunchUtil.upgradeGetdown(
+                  new File(appdir, "getdown-launcher-old.jar"),
+                  new File(appdir, "getdown-launcher.jar"),
+                  new File(appdir, "getdown-launcher-new.jar"));
+        }
+      }.start();
     }
-    val = System.getProperty("launcher_version");
-    if (val != null)
+
+    if (!quiet() || !bootstrapArgs.outputToStdout()
+            || bootstrapArgs.contains(Arg.VERSION))
     {
-      System.out.println("Launcher version: " + val);
+      Console.outPrintln(
+              "Java version: " + System.getProperty("java.version"));
+      Console.outPrintln("Java home: " + System.getProperty("java.home"));
+      Console.outPrintln("Java arch: " + System.getProperty("os.arch") + " "
+              + System.getProperty("os.name") + " "
+              + System.getProperty("os.version"));
+
+      String val = System.getProperty("sys.install4jVersion");
+      if (val != null)
+      {
+        Console.outPrintln("Install4j version: " + val);
+      }
+      val = System.getProperty("installer_template_version");
+      if (val != null)
+      {
+        Console.outPrintln("Install4j template version: " + val);
+      }
+      val = System.getProperty("launcher_version");
+      if (val != null)
+      {
+        Console.outPrintln("Launcher version: " + val);
+      }
     }
 
     if (Platform.isLinux() && LaunchUtils.getJavaVersion() < 11)
@@ -315,10 +417,17 @@ public class Jalview
 
     // get bootstrap properties (mainly for the logger level)
     Properties bootstrapProperties = Cache
-            .bootstrapProperties(bootstrapArgs.get(Arg.PROPS));
+            .bootstrapProperties(bootstrapArgs.getValue(Arg.PROPS));
 
     // report Jalview version
-    Cache.loadBuildProperties(true);
+    Cache.loadBuildProperties(
+            !quiet() || bootstrapArgs.contains(Arg.VERSION));
+
+    // stop now if only after --version
+    if (bootstrapArgs.contains(Arg.VERSION))
+    {
+      Jalview.exit(null, 0);
+    }
 
     // old ArgsParser
     ArgsParser aparser = new ArgsParser(args);
@@ -330,8 +439,15 @@ public class Jalview
 
     try
     {
-      String logLevel = bootstrapArgs.containsKey(Arg.DEBUG) ? "DEBUG"
-              : null;
+      String logLevel = null;
+      if (bootstrapArgs.contains(Arg.TRACE))
+      {
+        logLevel = "TRACE";
+      }
+      else if (bootstrapArgs.contains(Arg.DEBUG))
+      {
+        logLevel = "DEBUG";
+      }
       if (logLevel == null && !(bootstrapProperties == null))
       {
         logLevel = bootstrapProperties.getProperty(Cache.JALVIEWLOGLEVEL);
@@ -340,22 +456,41 @@ public class Jalview
     } catch (NoClassDefFoundError error)
     {
       error.printStackTrace();
-      System.out.println("\nEssential logging libraries not found."
-              + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
-      System.exit(0);
+      String message = "\nEssential logging libraries not found."
+              + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview";
+      Jalview.exit(message, 0);
     }
 
     // register SIGTERM listener
     Runtime.getRuntime().addShutdownHook(new Thread()
     {
+      @Override
       public void run()
       {
         Console.debug("Running shutdown hook");
+        QuitHandler.startForceQuit();
+        boolean closeExternal = Cache
+                .getDefault("DEFAULT_CLOSE_EXTERNAL_VIEWERS", false)
+                || Cache.getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", false);
+        StructureViewerBase.setQuitClose(closeExternal);
+        if (desktop != null)
+        {
+          for (JInternalFrame frame : Desktop.desktop.getAllFrames())
+          {
+            if (frame instanceof StructureViewerBase)
+            {
+              ((StructureViewerBase) frame).closeViewer(closeExternal);
+            }
+          }
+        }
+
         if (QuitHandler.gotQuitResponse() == QResponse.CANCEL_QUIT)
         {
           // Got to here by a SIGTERM signal.
           // Note we will not actually cancel the quit from here -- it's too
-          // late -- but we can wait for saving files.
+          // late -- but we can wait for saving files and close external viewers
+          // if configured.
+          // Close viewers/Leave viewers open
           Console.debug("Checking for saving files");
           QuitHandler.getQuitResponse(false);
         }
@@ -368,26 +503,33 @@ public class Jalview
       }
     });
 
-    String usrPropsFile = bootstrapArgs.containsKey(Arg.PROPS)
-            ? bootstrapArgs.get(Arg.PROPS)
+    String usrPropsFile = bootstrapArgs.contains(Arg.PROPS)
+            ? bootstrapArgs.getValue(Arg.PROPS)
             : aparser.getValue("props");
+    // if usrPropsFile == null, loadProperties will use the Channel
+    // preferences.file
     Cache.loadProperties(usrPropsFile);
     if (usrPropsFile != null)
     {
-      System.out.println(
+      Console.outPrintln(
               "CMD [-props " + usrPropsFile + "] executed successfully!");
+      testoutput(bootstrapArgs, Arg.PROPS,
+              "test/jalview/bin/testProps.jvprops", usrPropsFile);
     }
 
-    // new ArgParser
-    ArgParser argparser;
     // --argfile=... -- OVERRIDES ALL NON-BOOTSTRAP ARGS
-    if (bootstrapArgs.containsKey(Arg.ARGFILE))
+    if (bootstrapArgs.contains(Arg.ARGFILE))
     {
-      argparser = ArgParser.parseArgFile(bootstrapArgs.get(Arg.ARGFILE));
+      argparser = ArgParser.parseArgFiles(
+              bootstrapArgs.getValueList(Arg.ARGFILE),
+              bootstrapArgs.getBoolean(Arg.INITSUBSTITUTIONS),
+              bootstrapArgs);
     }
     else
     {
-      argparser = new ArgParser(args);
+      argparser = new ArgParser(args,
+              bootstrapArgs.getBoolean(Arg.INITSUBSTITUTIONS),
+              bootstrapArgs);
     }
 
     if (!Platform.isJS())
@@ -397,24 +539,35 @@ public class Jalview
      * @j2sIgnore
      */
     {
-      if (aparser.contains("help") || aparser.contains("h")
-              || argparser.getBool(Arg.HELP))
+      if (bootstrapArgs.contains(Arg.HELP))
       {
+        List<Map.Entry<Type, String>> helpArgs = bootstrapArgs
+                .getList(Arg.HELP);
+        Console.outPrintln(Arg.usage(helpArgs.stream().map(e -> e.getKey())
+                .collect(Collectors.toList())));
+        Jalview.exit(null, 0);
+      }
+      if (aparser.contains("help") || aparser.contains("h"))
+      {
+        /*
+         * Now using new usage statement.
         showUsage();
-        System.exit(0);
+        */
+        Console.outPrintln(Arg.usage());
+        Jalview.exit(null, 0);
       }
 
-      if (argparser.isSet(Arg.HEADLESS))
+      // new CLI
+      headlessArg = bootstrapArgs.isHeadless();
+      if (headlessArg)
       {
         System.setProperty("java.awt.headless", "true");
-        // new
-        headlessArg = argparser.getBool(Arg.HEADLESS);
       }
+      // old CLI
       if (aparser.contains("nodisplay") || aparser.contains("nogui")
               || aparser.contains("headless"))
       {
         System.setProperty("java.awt.headless", "true");
-        // old
         headless = true;
       }
       // anything else!
@@ -422,50 +575,68 @@ public class Jalview
       // allow https handshakes to download intermediate certs if necessary
       System.setProperty("com.sun.security.enableAIAcaIssuers", "true");
 
-      final String jabawsUrl = aparser.getValue("jabaws");
+      String jabawsUrl = bootstrapArgs.getValue(Arg.JABAWS);
+      if (jabawsUrl == null)
+        jabawsUrl = aparser.getValue("jabaws");
       if (jabawsUrl != null)
       {
         try
         {
           Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
-          System.out.println(
+          Console.outPrintln(
                   "CMD [-jabaws " + jabawsUrl + "] executed successfully!");
+          testoutput(bootstrapArgs, Arg.JABAWS,
+                  "http://www.compbio.dundee.ac.uk/jabaws", jabawsUrl);
         } catch (MalformedURLException e)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Invalid jabaws parameter: " + jabawsUrl + " ignored");
         }
       }
     }
 
-    String defs = aparser.getValue("setprop");
-    while (defs != null)
+    List<String> setprops = new ArrayList<>();
+    if (bootstrapArgs.contains(Arg.SETPROP))
     {
-      int p = defs.indexOf('=');
+      setprops = bootstrapArgs.getValueList(Arg.SETPROP);
+    }
+    else
+    {
+      String sp = aparser.getValue("setprop");
+      while (sp != null)
+      {
+        setprops.add(sp);
+        sp = aparser.getValue("setprop");
+      }
+    }
+    for (String setprop : setprops)
+    {
+      int p = setprop.indexOf('=');
       if (p == -1)
       {
-        System.err.println("Ignoring invalid setprop argument : " + defs);
+        System.err
+                .println("Ignoring invalid setprop argument : " + setprop);
       }
       else
       {
-        System.out.println("Executing setprop argument: " + defs);
+        jalview.bin.Console
+                .errPrintln("Executing setprop argument: " + setprop);
         if (Platform.isJS())
         {
-          Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
+          Cache.setProperty(setprop.substring(0, p),
+                  setprop.substring(p + 1));
         }
         // DISABLED FOR SECURITY REASONS
         // TODO: add a property to allow properties to be overriden by cli args
-        // Cache.setProperty(defs.substring(0,p), defs.substring(p+1));
+        // Cache.setProperty(setprop.substring(0,p), setprop.substring(p+1));
       }
-      defs = aparser.getValue("setprop");
     }
     if (System.getProperty("java.awt.headless") != null
             && System.getProperty("java.awt.headless").equals("true"))
     {
       headless = true;
     }
-    System.setProperty("http.agent",
-            "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
+    System.setProperty("http.agent", HttpUtils.getUserAgent());
 
     try
     {
@@ -475,9 +646,9 @@ public class Jalview
     NoClassDefFoundError error)
     {
       error.printStackTrace();
-      System.out.println("\nEssential logging libraries not found."
-              + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview");
-      System.exit(0);
+      String message = "\nEssential logging libraries not found."
+              + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview";
+      Jalview.exit(message, 0);
     }
     desktop = null;
 
@@ -496,7 +667,9 @@ public class Jalview
 
     if (!(headless || headlessArg))
     {
-      Desktop.nosplash = aparser.contains("nosplash");
+      Desktop.nosplash = "false".equals(bootstrapArgs.getValue(Arg.SPLASH))
+              || aparser.contains("nosplash")
+              || Cache.getDefault("SPLASH", "true").equals("false");
       desktop = new Desktop();
       desktop.setInBatchMode(true); // indicate we are starting up
 
@@ -556,20 +729,37 @@ public class Jalview
           }
         }
 
-        if (!aparser.contains("nowebservicediscovery"))
+        boolean webservicediscovery = bootstrapArgs
+                .getBoolean(Arg.WEBSERVICEDISCOVERY);
+        if (aparser.contains("nowebservicediscovery"))
+          webservicediscovery = false;
+        if (webservicediscovery)
         {
           desktop.startServiceDiscovery();
         }
-        if (!aparser.contains("nousagestats"))
+        else
+        {
+          testoutput(argparser, Arg.WEBSERVICEDISCOVERY);
+        }
+
+        boolean usagestats = !bootstrapArgs.getBoolean(Arg.NOUSAGESTATS);
+        if (aparser.contains("nousagestats"))
+          usagestats = false;
+        if (usagestats)
         {
           startUsageStats(desktop);
+          testoutput(argparser, Arg.NOUSAGESTATS);
         }
         else
         {
-          System.err.println("CMD [-nousagestats] executed successfully!");
+          Console.outPrintln("CMD [-nousagestats] executed successfully!");
+          testoutput(argparser, Arg.NOUSAGESTATS);
         }
 
-        if (!aparser.contains("noquestionnaire"))
+        boolean questionnaire = bootstrapArgs.getBoolean(Arg.QUESTIONNAIRE);
+        if (aparser.contains("noquestionnaire"))
+          questionnaire = false;
+        if (questionnaire)
         {
           String url = aparser.getValue("questionnaire");
           if (url != null)
@@ -578,7 +768,7 @@ public class Jalview
             // questionnaire
             Console.debug("Starting questionnaire url at " + url);
             desktop.checkForQuestionnaire(url);
-            System.out.println("CMD questionnaire[-" + url
+            Console.outPrintln("CMD questionnaire[-" + url
                     + "] executed successfully!");
           }
           else
@@ -599,36 +789,56 @@ public class Jalview
         }
         else
         {
-          System.err
-                  .println("CMD [-noquestionnaire] executed successfully!");
+          Console.outPrintln(
+                  "CMD [-noquestionnaire] executed successfully!");
+          testoutput(argparser, Arg.QUESTIONNAIRE);
         }
 
-        if (!aparser.contains("nonews")
-                || Cache.getProperty("NONEWS") == null)
+        if ((!aparser.contains("nonews")
+                && Cache.getProperty("NONEWS") == null
+                && !"false".equals(bootstrapArgs.getValue(Arg.NEWS)))
+                || "true".equals(bootstrapArgs.getValue(Arg.NEWS)))
         {
           desktop.checkForNews();
         }
 
         if (!aparser.contains("nohtmltemplates")
-                || Cache.getProperty("NOHTMLTEMPLATES") == null)
+                && Cache.getProperty("NOHTMLTEMPLATES") == null)
         {
           BioJsHTMLOutput.updateBioJS();
         }
       }
     }
     // Run Commands from cli
-    boolean commandsSuccess = Commands.processArgs(argparser, headlessArg);
+    cmds = new Commands(argparser, headlessArg);
+    cmds.processArgs();
+    boolean commandsSuccess = cmds.argsWereParsed();
+
     if (commandsSuccess)
     {
-      Console.info("Successfully completed commands");
       if (headlessArg)
-        System.exit(0);
+      {
+        if (argparser.getBoolean(Arg.NOQUIT))
+        {
+          Console.warn(
+                  "Completed " + Arg.HEADLESS.getName() + " commands, but "
+                          + Arg.NOQUIT + " is set so not quitting!");
+        }
+        else
+        {
+          Jalview.exit("Successfully completed commands in headless mode",
+                  0);
+        }
+      }
+      Console.info("Successfully completed commands");
     }
     else
     {
-      Console.warn("Error when running commands");
       if (headlessArg)
-        System.exit(1);
+      {
+        Jalview.exit("Error when running Commands in headless mode", 1);
+      }
+      Console.warn("Error when running commands");
     }
 
     // Check if JVM and compile version might cause problems and log if it
@@ -641,25 +851,6 @@ public class Jalview
               + LaunchUtils.getJavaCompileVersion() + ".");
     }
 
-    // Move any new getdown-launcher-new.jar into place over old
-    // getdown-launcher.jar
-    String appdirString = System.getProperty("getdownappdir");
-    if (appdirString != null && appdirString.length() > 0)
-    {
-      final File appdir = new File(appdirString);
-      new Thread()
-      {
-        @Override
-        public void run()
-        {
-          LaunchUtil.upgradeGetdown(
-                  new File(appdir, "getdown-launcher-old.jar"),
-                  new File(appdir, "getdown-launcher.jar"),
-                  new File(appdir, "getdown-launcher-new.jar"));
-        }
-      }.start();
-    }
-
     String file = null, data = null;
 
     FileFormatI format = null;
@@ -674,10 +865,9 @@ public class Jalview
     groovyscript = aparser.getValue("groovy", true);
     file = aparser.getValue("open", true);
 
-    if (file == null && desktop == null)
+    if (file == null && desktop == null && !commandsSuccess)
     {
-      System.out.println("No files to open!");
-      System.exit(1);
+      Jalview.exit("No files to open!", 1);
     }
 
     long progress = -1;
@@ -691,7 +881,7 @@ public class Jalview
                         .getString("status.processing_commandline_args"),
                 progress = System.currentTimeMillis());
       }
-      System.out.println("CMD [-open " + file + "] executed successfully!");
+      Console.outPrintln("CMD [-open " + file + "] executed successfully!");
 
       if (!Platform.isJS())
       /**
@@ -704,11 +894,12 @@ public class Jalview
         {
           if (!(new File(file)).exists())
           {
-            System.out.println("Can't find " + file);
             if (headless)
             {
-              System.exit(1);
+              Jalview.exit(
+                      "Can't find file '" + file + "' in headless mode", 1);
             }
+            Console.warn("Can't find file'" + file + "'");
           }
         }
       }
@@ -727,7 +918,7 @@ public class Jalview
               format);
       if (af == null)
       {
-        System.out.println("error");
+        Console.outPrintln("error");
       }
       else
       {
@@ -742,7 +933,7 @@ public class Jalview
 
           if (cs != null)
           {
-            System.out.println(
+            Console.outPrintln(
                     "CMD [-colour " + data + "] executed successfully!");
           }
           af.changeColour(cs);
@@ -754,8 +945,8 @@ public class Jalview
         {
           af.parseFeaturesFile(data,
                   AppletFormatAdapter.checkProtocol(data));
-          // System.out.println("Added " + data);
-          System.out.println(
+          // Console.outPrintln("Added " + data);
+          Console.outPrintln(
                   "CMD groups[-" + data + "]  executed successfully!");
         }
         data = aparser.getValue("features", true);
@@ -763,8 +954,8 @@ public class Jalview
         {
           af.parseFeaturesFile(data,
                   AppletFormatAdapter.checkProtocol(data));
-          // System.out.println("Added " + data);
-          System.out.println(
+          // Console.outPrintln("Added " + data);
+          Console.outPrintln(
                   "CMD [-features " + data + "]  executed successfully!");
         }
 
@@ -772,8 +963,8 @@ public class Jalview
         if (data != null)
         {
           af.loadJalviewDataFile(data, null, null, null);
-          // System.out.println("Added " + data);
-          System.out.println(
+          // Console.outPrintln("Added " + data);
+          Console.outPrintln(
                   "CMD [-annotations " + data + "] executed successfully!");
         }
         // set or clear the sortbytree flag.
@@ -782,7 +973,7 @@ public class Jalview
           af.getViewport().setSortByTree(true);
           if (af.getViewport().getSortByTree())
           {
-            System.out.println("CMD [-sortbytree] executed successfully!");
+            Console.outPrintln("CMD [-sortbytree] executed successfully!");
           }
         }
         if (aparser.contains("no-annotation"))
@@ -790,7 +981,7 @@ public class Jalview
           af.getViewport().setShowAnnotation(false);
           if (!af.getViewport().isShowAnnotation())
           {
-            System.out.println("CMD no-annotation executed successfully!");
+            Console.outPrintln("CMD no-annotation executed successfully!");
           }
         }
         if (aparser.contains("nosortbytree"))
@@ -798,8 +989,8 @@ public class Jalview
           af.getViewport().setSortByTree(false);
           if (!af.getViewport().getSortByTree())
           {
-            System.out
-                    .println("CMD [-nosortbytree] executed successfully!");
+            Console.outPrintln(
+                    "CMD [-nosortbytree] executed successfully!");
           }
         }
         data = aparser.getValue("tree", true);
@@ -807,7 +998,7 @@ public class Jalview
         {
           try
           {
-            System.out.println(
+            Console.outPrintln(
                     "CMD [-tree " + data + "] executed successfully!");
             NewickFile nf = new NewickFile(data,
                     AppletFormatAdapter.checkProtocol(data));
@@ -815,127 +1006,135 @@ public class Jalview
                     .setCurrentTree(af.showNewickTree(nf, data).getTree());
           } catch (IOException ex)
           {
-            System.err.println("Couldn't add tree " + data);
+            jalview.bin.Console.errPrintln("Couldn't add tree " + data);
             ex.printStackTrace(System.err);
           }
         }
-        // TODO - load PDB structure(s) to alignment JAL-629
-        // (associate with identical sequence in alignment, or a specified
-        // sequence)
+
         if (groovyscript != null)
         {
           // Execute the groovy script after we've done all the rendering stuff
           // and before any images or figures are generated.
-          System.out.println("Executing script " + groovyscript);
+          Console.outPrintln("Executing script " + groovyscript);
           executeGroovyScript(groovyscript, af);
-          System.out.println("CMD groovy[" + groovyscript
+          Console.outPrintln("CMD groovy[" + groovyscript
                   + "] executed successfully!");
           groovyscript = null;
         }
         String imageName = "unnamed.png";
         while (aparser.getSize() > 1)
         {
-          String outputFormat = aparser.nextValue();
-          file = aparser.nextValue();
-
-          if (outputFormat.equalsIgnoreCase("png"))
-          {
-            af.createPNG(new File(file));
-            imageName = (new File(file)).getName();
-            System.out.println("Creating PNG image: " + file);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("svg"))
-          {
-            File imageFile = new File(file);
-            imageName = imageFile.getName();
-            af.createSVG(imageFile);
-            System.out.println("Creating SVG image: " + file);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("html"))
+          try
           {
-            File imageFile = new File(file);
-            imageName = imageFile.getName();
-            HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
-            htmlSVG.exportHTML(file);
+            String outputFormat = aparser.nextValue();
+            file = aparser.nextValue();
 
-            System.out.println("Creating HTML image: " + file);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("biojsmsa"))
-          {
-            if (file == null)
+            if (outputFormat.equalsIgnoreCase("png"))
             {
-              System.err.println("The output html file must not be null");
-              return;
+              Console.outPrintln("Creating PNG image: " + file);
+              af.createPNG(new File(file));
+              imageName = (new File(file)).getName();
+              continue;
             }
-            try
+            else if (outputFormat.equalsIgnoreCase("svg"))
+            {
+              Console.outPrintln("Creating SVG image: " + file);
+              File imageFile = new File(file);
+              imageName = imageFile.getName();
+              af.createSVG(imageFile);
+              continue;
+            }
+            else if (outputFormat.equalsIgnoreCase("html"))
             {
-              BioJsHTMLOutput.refreshVersionInfo(
-                      BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
-            } catch (URISyntaxException e)
+              File imageFile = new File(file);
+              imageName = imageFile.getName();
+              HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
+
+              Console.outPrintln("Creating HTML image: " + file);
+              htmlSVG.exportHTML(file);
+              continue;
+            }
+            else if (outputFormat.equalsIgnoreCase("biojsmsa"))
             {
-              e.printStackTrace();
+              if (file == null)
+              {
+                jalview.bin.Console.errPrintln(
+                        "The output html file must not be null");
+                return;
+              }
+              try
+              {
+                BioJsHTMLOutput.refreshVersionInfo(
+                        BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
+              } catch (URISyntaxException e)
+              {
+                e.printStackTrace();
+              }
+              BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
+              Console.outPrintln(
+                      "Creating BioJS MSA Viwer HTML file: " + file);
+              bjs.exportHTML(file);
+              continue;
             }
-            BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
-            bjs.exportHTML(file);
-            System.out
-                    .println("Creating BioJS MSA Viwer HTML file: " + file);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("imgMap"))
-          {
-            af.createImageMap(new File(file), imageName);
-            System.out.println("Creating image map: " + file);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("eps"))
-          {
-            File outputFile = new File(file);
-            System.out.println(
-                    "Creating EPS file: " + outputFile.getAbsolutePath());
-            af.createEPS(outputFile);
-            continue;
-          }
-          FileFormatI outFormat = null;
-          try
-          {
-            outFormat = FileFormats.getInstance().forName(outputFormat);
-          } catch (Exception formatP)
-          {
-            System.out.println("Couldn't parse " + outFormat
-                    + " as a valid Jalview format string.");
-          }
-          if (outFormat != null)
-          {
-            if (!outFormat.isWritable())
+            else if (outputFormat.equalsIgnoreCase("imgMap"))
+            {
+              Console.outPrintln("Creating image map: " + file);
+              af.createImageMap(new File(file), imageName);
+              continue;
+            }
+            else if (outputFormat.equalsIgnoreCase("eps"))
+            {
+              File outputFile = new File(file);
+              Console.outPrintln(
+                      "Creating EPS file: " + outputFile.getAbsolutePath());
+              af.createEPS(outputFile);
+              continue;
+            }
+
+            FileFormatI outFormat = null;
+            try
             {
-              System.out.println(
-                      "This version of Jalview does not support alignment export as "
-                              + outputFormat);
+              outFormat = FileFormats.getInstance().forName(outputFormat);
+            } catch (Exception formatP)
+            {
+              Console.outPrintln("Couldn't parse " + outFormat
+                      + " as a valid Jalview format string.");
             }
-            else
+            if (outFormat != null)
             {
-              af.saveAlignment(file, outFormat);
-              if (af.isSaveAlignmentSuccessful())
+              if (!outFormat.isWritable())
               {
-                System.out.println("Written alignment in "
-                        + outFormat.getName() + " format to " + file);
+                Console.outPrintln(
+                        "This version of Jalview does not support alignment export as "
+                                + outputFormat);
               }
               else
               {
-                System.out.println("Error writing file " + file + " in "
-                        + outFormat.getName() + " format!!");
+                af.saveAlignment(file, outFormat);
+                if (af.isSaveAlignmentSuccessful())
+                {
+                  Console.outPrintln("Written alignment in "
+                          + outFormat.getName() + " format to " + file);
+                }
+                else
+                {
+                  Console.outPrintln("Error writing file " + file + " in "
+                          + outFormat.getName() + " format!!");
+                }
               }
             }
+          } catch (ImageOutputException ioexc)
+          {
+            Console.outPrintln(
+                    "Unexpected error whilst exporting image to " + file);
+            ioexc.printStackTrace();
           }
 
         }
 
         while (aparser.getSize() > 0)
         {
-          System.out.println("Unknown arg: " + aparser.nextValue());
+          Console.outPrintln("Unknown arg: " + aparser.nextValue());
         }
       }
     }
@@ -947,7 +1146,8 @@ public class Jalview
 
     if (!Platform.isJS() && !headless && file == null
             && Cache.getDefault("SHOW_STARTUP_FILE", true)
-            && !Commands.commandArgsProvided())
+            && !cmds.commandArgsProvided()
+            && !bootstrapArgs.getBoolean(Arg.NOSTARTUPFILE))
     // don't open the startup file if command line args have been processed
     // (&& !Commands.commandArgsProvided())
     /**
@@ -1002,12 +1202,12 @@ public class Jalview
     {
       if (Cache.groovyJarsPresent())
       {
-        System.out.println("Executing script " + groovyscript);
+        Console.outPrintln("Executing script " + groovyscript);
         executeGroovyScript(groovyscript, startUpAlframe);
       }
       else
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
                         + groovyscript);
       }
@@ -1025,88 +1225,102 @@ public class Jalview
 
   private static void setLookAndFeel()
   {
-    // property laf = "crossplatform", "system", "gtk", "metal", "nimbus",
-    // "mac" or "flat"
-    // If not set (or chosen laf fails), use the normal SystemLaF and if on Mac,
-    // try Quaqua/Vaqua.
-    String lafProp = System.getProperty("laf");
-    String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
-    String laf = "none";
-    if (lafProp != null)
-    {
-      laf = lafProp;
-    }
-    else if (lafSetting != null)
-    {
-      laf = lafSetting;
-    }
-    boolean lafSet = false;
-    switch (laf)
+    if (!Platform.isJS())
+    /**
+     * Java only
+     * 
+     * @j2sIgnore
+     */
     {
-    case "crossplatform":
-      lafSet = setCrossPlatformLookAndFeel();
-      if (!lafSet)
+      // property laf = "crossplatform", "system", "gtk", "metal", "nimbus",
+      // "mac" or "flat"
+      // If not set (or chosen laf fails), use the normal SystemLaF and if on
+      // Mac,
+      // try Quaqua/Vaqua.
+      String lafProp = System.getProperty("laf");
+      String lafSetting = Cache.getDefault("PREFERRED_LAF", null);
+      String laf = "none";
+      if (lafProp != null)
       {
-        Console.error("Could not set requested laf=" + laf);
+        laf = lafProp;
       }
-      break;
-    case "system":
-      lafSet = setSystemLookAndFeel();
-      if (!lafSet)
+      else if (lafSetting != null)
       {
-        Console.error("Could not set requested laf=" + laf);
+        laf = lafSetting;
       }
-      break;
-    case "gtk":
-      lafSet = setGtkLookAndFeel();
-      if (!lafSet)
+      boolean lafSet = false;
+      switch (laf)
       {
-        Console.error("Could not set requested laf=" + laf);
-      }
-      break;
-    case "metal":
-      lafSet = setMetalLookAndFeel();
-      if (!lafSet)
-      {
-        Console.error("Could not set requested laf=" + laf);
-      }
-      break;
-    case "nimbus":
-      lafSet = setNimbusLookAndFeel();
-      if (!lafSet)
-      {
-        Console.error("Could not set requested laf=" + laf);
-      }
-      break;
-    case "flat":
-      lafSet = setFlatLookAndFeel();
-      if (!lafSet)
-      {
-        Console.error("Could not set requested laf=" + laf);
+      case "crossplatform":
+        lafSet = setCrossPlatformLookAndFeel();
+        if (!lafSet)
+        {
+          Console.error("Could not set requested laf=" + laf);
+        }
+        break;
+      case "system":
+        lafSet = setSystemLookAndFeel();
+        if (!lafSet)
+        {
+          Console.error("Could not set requested laf=" + laf);
+        }
+        break;
+      case "gtk":
+        lafSet = setGtkLookAndFeel();
+        if (!lafSet)
+        {
+          Console.error("Could not set requested laf=" + laf);
+        }
+        break;
+      case "metal":
+        lafSet = setMetalLookAndFeel();
+        if (!lafSet)
+        {
+          Console.error("Could not set requested laf=" + laf);
+        }
+        break;
+      case "nimbus":
+        lafSet = setNimbusLookAndFeel();
+        if (!lafSet)
+        {
+          Console.error("Could not set requested laf=" + laf);
+        }
+        break;
+      case "flat":
+        lafSet = setFlatLookAndFeel();
+        if (!lafSet)
+        {
+          Console.error("Could not set requested laf=" + laf);
+        }
+        break;
+      case "mac":
+        lafSet = setMacLookAndFeel();
+        if (!lafSet)
+        {
+          Console.error("Could not set requested laf=" + laf);
+        }
+        break;
+      case "none":
+        break;
+      default:
+        Console.error("Requested laf=" + laf + " not implemented");
       }
-      break;
-    case "mac":
-      lafSet = setMacLookAndFeel();
       if (!lafSet)
       {
-        Console.error("Could not set requested laf=" + laf);
-      }
-      break;
-    case "none":
-      break;
-    default:
-      Console.error("Requested laf=" + laf + " not implemented");
-    }
-    if (!lafSet)
-    {
-      setSystemLookAndFeel();
-      if (Platform.isLinux())
-      {
-        setLinuxLookAndFeel();
-      }
-      if (Platform.isMac())
-      {
-        setMacLookAndFeel();
+        // Flatlaf default for everyone!
+        lafSet = setFlatLookAndFeel();
+        if (!lafSet)
+        {
+          setSystemLookAndFeel();
+        }
+        if (Platform.isLinux())
+        {
+          setLinuxLookAndFeel();
+        }
+        if (Platform.isMac())
+        {
+          setMacLookAndFeel();
+        }
       }
     }
   }
@@ -1288,7 +1502,7 @@ public class Jalview
       UIManager.put("TabbedPane.tabType", "card");
       UIManager.put("TabbedPane.showTabSeparators", true);
       UIManager.put("TabbedPane.showContentSeparator", true);
-      UIManager.put("TabbedPane.tabSeparatorsFullHeight", true);
+      // UIManager.put("TabbedPane.tabSeparatorsFullHeight", true);
       UIManager.put("TabbedPane.tabsOverlapBorder", true);
       UIManager.put("TabbedPane.hasFullBorder", true);
       UIManager.put("TabbedPane.tabLayoutPolicy", "scroll");
@@ -1296,6 +1510,8 @@ public class Jalview
       UIManager.put("TabbedPane.smoothScrolling", true);
       UIManager.put("TabbedPane.tabWidthMode", "compact");
       UIManager.put("TabbedPane.selectedBackground", Color.white);
+      UIManager.put("TabbedPane.background", new Color(236, 236, 236));
+      UIManager.put("TabbedPane.hoverColor", Color.lightGray);
     }
 
     Desktop.setLiveDragMode(Cache.getDefault("FLAT_LIVE_DRAG_MODE", true));
@@ -1333,9 +1549,10 @@ public class Jalview
     return set;
   }
 
+  /*
   private static void showUsage()
   {
-    System.out.println(
+    jalview.bin.Console.outPrintln(
             "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
                     + "-nodisplay\tRun Jalview without User Interface.\n"
                     + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
@@ -1361,7 +1578,7 @@ public class Jalview
                     + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
                     + "-noquestionnaire\tTurn off questionnaire check.\n"
                     + "-nonews\tTurn off check for Jalview news.\n"
-                    + "-nousagestats\tTurn off google analytics tracking for this session.\n"
+                    + "-nousagestats\tTurn off analytics tracking for this session.\n"
                     + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
                     // +
                     // "-setprop PROPERTY=VALUE\tSet the given Jalview property,
@@ -1375,6 +1592,7 @@ public class Jalview
                     + "-jvmmemmax=MAXMEMORY\tOnly available with standalone executable jar or jalview.bin.Launcher. Limit maximum heap size (memory) to MAXMEMORY. MAXMEMORY can be specified in bytes, kilobytes(k), megabytes(m), gigabytes(g) or if you're lucky enough, terabytes(t). This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected. See https://www.jalview.org/help/html/memory.html for more details.\n"
                     + "\n~Read documentation in Application or visit https://www.jalview.org for description of Features and Annotations file~\n\n");
   }
+  */
 
   private static void startUsageStats(final Desktop desktop)
   {
@@ -1382,18 +1600,16 @@ public class Jalview
      * start a User Config prompt asking if we can log usage statistics.
      */
     PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
-            "USAGESTATS", "Jalview Usage Statistics",
-            "Do you want to help make Jalview better by enabling "
-                    + "the collection of usage statistics with Google Analytics ?"
-                    + "\n\n(you can enable or disable usage tracking in the preferences)",
+            "USAGESTATS",
+            MessageManager.getString("prompt.plausible_analytics_title"),
+            MessageManager.getString("prompt.plausible_analytics"),
             new Runnable()
             {
               @Override
               public void run()
               {
-                Console.debug(
-                        "Initialising googletracker for usage stats.");
-                Cache.initGoogleTracker();
+                Console.debug("Initialising analytics for usage stats.");
+                Cache.initAnalytics();
                 Console.debug("Tracking enabled.");
               }
             }, new Runnable()
@@ -1401,7 +1617,7 @@ public class Jalview
               @Override
               public void run()
               {
-                Console.debug("Not enabling Google Tracking.");
+                Console.debug("Not enabling analytics.");
               }
             }, null, true);
     desktop.addDialogThread(prompter);
@@ -1416,7 +1632,7 @@ public class Jalview
    *          the Jalview Desktop object passed in to the groovy binding as the
    *          'Jalview' object.
    */
-  private void executeGroovyScript(String groovyscript, AlignFrame af)
+  protected void executeGroovyScript(String groovyscript, AlignFrame af)
   {
     /**
      * for scripts contained in files
@@ -1447,9 +1663,10 @@ public class Jalview
 
       } catch (Exception ex)
       {
-        System.err.println("Failed to read from STDIN into tempfile "
-                + ((tfile == null) ? "(tempfile wasn't created)"
-                        : tfile.toString()));
+        jalview.bin.Console
+                .errPrintln("Failed to read from STDIN into tempfile "
+                        + ((tfile == null) ? "(tempfile wasn't created)"
+                                : tfile.toString()));
         ex.printStackTrace();
         return;
       }
@@ -1458,7 +1675,7 @@ public class Jalview
         sfile = tfile.toURI().toURL();
       } catch (Exception x)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Unexpected Malformed URL Exception for temporary file created from STDIN: "
                         + tfile.toURI());
         x.printStackTrace();
@@ -1475,17 +1692,20 @@ public class Jalview
         tfile = new File(groovyscript);
         if (!tfile.exists())
         {
-          System.err.println("File '" + groovyscript + "' does not exist.");
+          jalview.bin.Console.errPrintln(
+                  "File '" + groovyscript + "' does not exist.");
           return;
         }
         if (!tfile.canRead())
         {
-          System.err.println("File '" + groovyscript + "' cannot be read.");
+          jalview.bin.Console.errPrintln(
+                  "File '" + groovyscript + "' cannot be read.");
           return;
         }
         if (tfile.length() < 1)
         {
-          System.err.println("File '" + groovyscript + "' is empty.");
+          jalview.bin.Console
+                  .errPrintln("File '" + groovyscript + "' is empty.");
           return;
         }
         try
@@ -1493,7 +1713,7 @@ public class Jalview
           sfile = tfile.getAbsoluteFile().toURI().toURL();
         } catch (Exception ex)
         {
-          System.err.println("Failed to create a file URL for "
+          jalview.bin.Console.errPrintln("Failed to create a file URL for "
                   + tfile.getAbsoluteFile());
           return;
         }
@@ -1518,8 +1738,9 @@ public class Jalview
       }
     } catch (Exception e)
     {
-      System.err.println("Exception Whilst trying to execute file " + sfile
-              + " as a groovy script.");
+      jalview.bin.Console
+              .errPrintln("Exception Whilst trying to execute file " + sfile
+                      + " as a groovy script.");
       e.printStackTrace(System.err);
 
     }
@@ -1548,7 +1769,7 @@ public class Jalview
   public void quit()
   {
     // System.exit will run the shutdownHook first
-    System.exit(0);
+    Jalview.exit("Quitting now. Bye!", 0);
   }
 
   public static AlignFrame getCurrentAlignFrame()
@@ -1560,4 +1781,206 @@ public class Jalview
   {
     Jalview.currentAlignFrame = currentAlignFrame;
   }
+
+  public Commands getCommands()
+  {
+    return cmds;
+  }
+
+  public static void exit(String message, int exitcode)
+  {
+    if (Console.log == null)
+    {
+      // Don't start the logger just to exit!
+      if (message != null)
+      {
+        if (exitcode == 0)
+        {
+          Console.outPrintln(message);
+        }
+        else
+        {
+          jalview.bin.Console.errPrintln(message);
+        }
+      }
+    }
+    else
+    {
+      Console.debug("Using Jalview.exit");
+      if (message != null)
+      {
+        if (exitcode == 0)
+        {
+          Console.info(message);
+        }
+        else
+        {
+          Console.error(message);
+        }
+      }
+    }
+    if (exitcode > -1)
+    {
+      System.exit(exitcode);
+    }
+  }
+
+  /******************************
+   * 
+   * TEST OUTPUT METHODS
+   * 
+   * these operate only when Arg.TESTOUTPUT has been passed, and variously check
+   * if an expected value / arg was set and report it to the test framework.
+   * 
+   ******************************/
+  /**
+   * report string values parsed/processed during tests When the Bootstrap
+   * argument Arg.TESTOUTPUT is present - reports on debug if given s1 is not
+   * null and not equals s2, warns if given argument is not set, and calls
+   * testoutput(true,a,s1,s2) to report processing progress.
+   * 
+   * @param ap
+   *          - ArgParser handling parsing
+   * @param a
+   *          - Arg currently being processed
+   * @param s1
+   *          - expected 
+   * @param s2
+   */
+  protected static void testoutput(ArgParser ap, Arg a, String s1,
+          String s2)
+  {
+    BootstrapArgs bsa = ap.getBootstrapArgs();
+    if (!bsa.getBoolean(Arg.TESTOUTPUT))
+      return;
+    if (!((s1 == null && s2 == null) || (s1 != null && s1.equals(s2))))
+    {
+      Console.debug("testoutput with unmatching values '" + s1 + "' and '"
+              + s2 + "' for arg " + a.argString());
+      return;
+    }
+    boolean isset = a.hasOption(Opt.BOOTSTRAP) ? bsa.contains(a)
+            : ap.isSet(a);
+    if (!isset)
+    {
+      Console.warn("Arg '" + a.getName() + "' not set at all");
+      return;
+    }
+    testoutput(true, a, s1, s2);
+  }
+
+  /**
+   * report values passed via bootstrap arguments
+   * 
+   * TODO: significant code duplication with testouput(Argparser...) - move it
+   */
+
+  protected static void testoutput(BootstrapArgs bsa, Arg a, String s1,
+          String s2)
+  {
+    if (!bsa.getBoolean(Arg.TESTOUTPUT))
+      return;
+    if (!((s1 == null && s2 == null) || (s1 != null && s1.equals(s2))))
+    {
+      Console.debug("testoutput with unmatching values '" + s1 + "' and '"
+              + s2 + "' for arg " + a.argString());
+      return;
+    }
+    if (!a.hasOption(Opt.BOOTSTRAP))
+    {
+      Console.error("Non-bootstrap Arg '" + a.getName()
+              + "' given to testoutput(BootstrapArgs bsa, Arg a, String s1, String s2) with only BootstrapArgs");
+    }
+    if (!bsa.contains(a))
+    {
+      Console.warn("Arg '" + a.getName() + "' not set at all");
+      return;
+    }
+    testoutput(true, a, s1, s2);
+  }
+
+  /**
+   * conditionally (on @param yes) report that expected value s1 was set during CommandsTest tests
+   */
+  private static void testoutput(boolean yes, Arg a, String s1, String s2)
+  {
+    if (yes && ((s1 == null && s2 == null)
+            || (s1 != null && s1.equals(s2))))
+    {
+      Console.outPrintln("[TESTOUTPUT] arg " + a.argString() + "='" + s1
+              + "' was set");
+    }
+  }
+
+  /*
+   * testoutput for boolean and unary values
+   */
+  protected static void testoutput(ArgParser ap, Arg a)
+  {
+    if (ap == null)
+      return;
+    BootstrapArgs bsa = ap.getBootstrapArgs();
+    if (bsa == null)
+      return;
+    if (!bsa.getBoolean(Arg.TESTOUTPUT))
+      return;
+    boolean val = a.hasOption(Opt.BOOTSTRAP) ? bsa.getBoolean(a)
+            : ap.getBoolean(a);
+    boolean isset = a.hasOption(Opt.BOOTSTRAP) ? bsa.contains(a)
+            : ap.isSet(a);
+    if (!isset)
+    {
+      Console.warn("Arg '" + a.getName() + "' not set at all");
+      return;
+    }
+    testoutput(val, a);
+  }
+
+  protected static void testoutput(BootstrapArgs bsa, Arg a)
+  {
+    if (!bsa.getBoolean(Arg.TESTOUTPUT))
+      return;
+    if (!a.hasOption(Opt.BOOTSTRAP))
+    {
+      Console.warn("Non-bootstrap Arg '" + a.getName()
+              + "' given to testoutput(BootstrapArgs bsa, Arg a) with only BootstrapArgs");
+
+    }
+    if (!bsa.contains(a))
+    {
+      Console.warn("Arg '" + a.getName() + "' not set at all");
+      return;
+    }
+    testoutput(bsa.getBoolean(a), a);
+  }
+
+  private static void testoutput(boolean yes, Arg a)
+  {
+    String message = null;
+    if (a.hasOption(Opt.BOOLEAN))
+    {
+      message = (yes ? a.argString() : a.negateArgString()) + " was set";
+    }
+    else if (a.hasOption(Opt.UNARY))
+    {
+      message = a.argString() + (yes ? " was set" : " was not set");
+    }
+    Console.outPrintln("[TESTOUTPUT] arg " + message);
+  }
+
+  public ArgParser getArgParser()
+  {
+    return argparser;
+  }
+
+  public BootstrapArgs getBootstrapArgs()
+  {
+    return bootstrapArgs;
+  }
+
+  public static boolean isBatchMode()
+  {
+    return getInstance()!=null && (getInstance().desktop == null || getInstance().desktop.isInBatchMode());
+  }
+
 }
index 7d66f6d..e8be95f 100644 (file)
@@ -292,7 +292,7 @@ public class JalviewLite extends Applet
     {
       if (debug)
       {
-        System.err.println("Selecting region using separator string '"
+        jalview.bin.Console.errPrintln("Selecting region using separator string '"
                 + separator + "'");
       }
     }
@@ -344,7 +344,7 @@ public class JalviewLite extends Applet
             from--;
           } catch (NumberFormatException ex)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "ERROR: Couldn't parse first integer in range element column selection string '"
                             + cl + "' - format is 'from-to'");
             return;
@@ -355,7 +355,7 @@ public class JalviewLite extends Applet
             to--;
           } catch (NumberFormatException ex)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "ERROR: Couldn't parse second integer in range element column selection string '"
                             + cl + "' - format is 'from-to'");
             return;
@@ -396,13 +396,13 @@ public class JalviewLite extends Applet
             }
             if (debug)
             {
-              System.err.println("Range '" + cl + "' deparsed as [" + from
+              jalview.bin.Console.errPrintln("Range '" + cl + "' deparsed as [" + from
                       + "," + to + "]");
             }
           }
           else
           {
-            System.err.println("ERROR: Invalid Range '" + cl
+            jalview.bin.Console.errPrintln("ERROR: Invalid Range '" + cl
                     + "' deparsed as [" + from + "," + to + "]");
           }
         }
@@ -422,7 +422,7 @@ public class JalviewLite extends Applet
             }
             else
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "ERROR: Couldn't parse integer from point selection element of column selection string '"
                               + cl + "'");
               return;
@@ -451,13 +451,13 @@ public class JalviewLite extends Applet
             csel.addElement(r);
             if (debug)
             {
-              System.err.println("Point selection '" + cl
+              jalview.bin.Console.errPrintln("Point selection '" + cl
                       + "' deparsed as [" + r + "]");
             }
           }
           else
           {
-            System.err.println("ERROR: Invalid Point selection '" + cl
+            jalview.bin.Console.errPrintln("ERROR: Invalid Point selection '" + cl
                     + "' deparsed as [" + r + "]");
           }
         }
@@ -940,7 +940,7 @@ public class JalviewLite extends Applet
       listener = listener.trim();
       if (listener.length() == 0)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "jalview Javascript error: Ignoring empty function for mouseover listener.");
         return;
       }
@@ -952,11 +952,11 @@ public class JalviewLite extends Applet
             .addStructureViewerListener(mol);
     if (debug)
     {
-      System.err.println("Added a mouseover listener for "
+      jalview.bin.Console.errPrintln("Added a mouseover listener for "
               + ((af == null) ? "All frames"
                       : "Just views for "
                               + af.getAlignViewport().getSequenceSetId()));
-      System.err.println("There are now " + javascriptListeners.size()
+      jalview.bin.Console.errPrintln("There are now " + javascriptListeners.size()
               + " listeners in total.");
     }
   }
@@ -987,7 +987,7 @@ public class JalviewLite extends Applet
       listener = listener.trim();
       if (listener.length() == 0)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "jalview Javascript error: Ignoring empty function for selection listener.");
         return;
       }
@@ -999,11 +999,11 @@ public class JalviewLite extends Applet
             .addSelectionListener(mol);
     if (debug)
     {
-      System.err.println("Added a selection listener for "
+      jalview.bin.Console.errPrintln("Added a selection listener for "
               + ((af == null) ? "All frames"
                       : "Just views for "
                               + af.getAlignViewport().getSequenceSetId()));
-      System.err.println("There are now " + javascriptListeners.size()
+      jalview.bin.Console.errPrintln("There are now " + javascriptListeners.size()
               + " listeners in total.");
     }
   }
@@ -1027,7 +1027,7 @@ public class JalviewLite extends Applet
       listener = listener.trim();
       if (listener.length() == 0)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "jalview Javascript error: Ignoring empty function for selection listener.");
         return;
       }
@@ -1039,9 +1039,9 @@ public class JalviewLite extends Applet
             .addStructureViewerListener(mol);
     if (debug)
     {
-      System.err.println("Added a javascript structure viewer listener '"
+      jalview.bin.Console.errPrintln("Added a javascript structure viewer listener '"
               + listener + "'");
-      System.err.println("There are now " + javascriptListeners.size()
+      jalview.bin.Console.errPrintln("There are now " + javascriptListeners.size()
               + " listeners in total.");
     }
   }
@@ -1087,7 +1087,7 @@ public class JalviewLite extends Applet
         rprt = debug;
         if (debug)
         {
-          System.err.println("Removed listener '" + listener + "'");
+          jalview.bin.Console.errPrintln("Removed listener '" + listener + "'");
         }
       }
       else
@@ -1097,7 +1097,7 @@ public class JalviewLite extends Applet
     }
     if (rprt)
     {
-      System.err.println("There are now " + javascriptListeners.size()
+      jalview.bin.Console.errPrintln("There are now " + javascriptListeners.size()
               + " listeners in total.");
     }
   }
@@ -1105,14 +1105,14 @@ public class JalviewLite extends Applet
   @Override
   public void stop()
   {
-    System.err.println("Applet " + getName() + " stop().");
+    jalview.bin.Console.errPrintln("Applet " + getName() + " stop().");
     tidyUp();
   }
 
   @Override
   public void destroy()
   {
-    System.err.println("Applet " + getName() + " destroy().");
+    jalview.bin.Console.errPrintln("Applet " + getName() + " destroy().");
     tidyUp();
   }
 
@@ -1189,7 +1189,7 @@ public class JalviewLite extends Applet
           }
         } catch (NumberFormatException e)
         {
-          System.err.println("Ignoring invalid residue number string '"
+          jalview.bin.Console.errPrintln("Ignoring invalid residue number string '"
                   + pdbResNum + "'");
         }
 
@@ -1220,7 +1220,7 @@ public class JalviewLite extends Applet
 
         } catch (Exception ex)
         {
-          System.err.println("Couldn't parse integer arguments (topRow='"
+          jalview.bin.Console.errPrintln("Couldn't parse integer arguments (topRow='"
                   + topRow + "' and leftHandColumn='" + leftHandColumn
                   + "')");
           ex.printStackTrace();
@@ -1251,7 +1251,7 @@ public class JalviewLite extends Applet
 
         } catch (Exception ex)
         {
-          System.err.println("Couldn't parse integer arguments (topRow='"
+          jalview.bin.Console.errPrintln("Couldn't parse integer arguments (topRow='"
                   + topRow + "')");
           ex.printStackTrace();
         }
@@ -1283,7 +1283,7 @@ public class JalviewLite extends Applet
 
         } catch (Exception ex)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Couldn't parse integer arguments (leftHandColumn='"
                           + leftHandColumn + "')");
           ex.printStackTrace();
@@ -1415,18 +1415,18 @@ public class JalviewLite extends Applet
     {
       if (debug)
       {
-        System.err.println("Applet context is '"
+        jalview.bin.Console.errPrintln("Applet context is '"
                 + getAppletContext().getClass().toString() + "'");
       }
       JSObject scriptObject = JSObject.getWindow(this);
       if (debug && scriptObject != null)
       {
-        System.err.println("Applet has Javascript callback support.");
+        jalview.bin.Console.errPrintln("Applet has Javascript callback support.");
       }
 
     } catch (Exception ex)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Warning: No JalviewLite javascript callbacks available.");
       if (debug)
       {
@@ -1436,9 +1436,9 @@ public class JalviewLite extends Applet
 
     if (debug)
     {
-      System.err.println("JalviewLite Version " + getVersion());
-      System.err.println("Build Date : " + getBuildDate());
-      System.err.println("Installation : " + getInstallation());
+      jalview.bin.Console.errPrintln("JalviewLite Version " + getVersion());
+      jalview.bin.Console.errPrintln("Build Date : " + getBuildDate());
+      jalview.bin.Console.errPrintln("Installation : " + getInstallation());
     }
     String externalsviewer = getParameter("externalstructureviewer");
     if (externalsviewer != null)
@@ -1465,7 +1465,7 @@ public class JalviewLite extends Applet
         separator = sep;
         if (debug)
         {
-          System.err.println("Separator set to '" + separator + "'");
+          jalview.bin.Console.errPrintln("Separator set to '" + separator + "'");
         }
       }
       else
@@ -1573,7 +1573,7 @@ public class JalviewLite extends Applet
     {
       if (tries > 0)
       {
-        System.err.println("LiveConnect request thread going to sleep.");
+        jalview.bin.Console.errPrintln("LiveConnect request thread going to sleep.");
       }
       try
       {
@@ -1584,7 +1584,7 @@ public class JalviewLite extends Applet
       ;
       if (tries++ > 0)
       {
-        System.err.println("LiveConnect request thread woken up.");
+        jalview.bin.Console.errPrintln("LiveConnect request thread woken up.");
       }
       try
       {
@@ -1595,7 +1595,7 @@ public class JalviewLite extends Applet
         }
       } catch (Exception jsex)
       {
-        System.err.println("Attempt " + tries
+        jalview.bin.Console.errPrintln("Attempt " + tries
                 + " to access LiveConnect javascript failed.");
       }
     }
@@ -1632,14 +1632,14 @@ public class JalviewLite extends Applet
                   "Calling oninit callback '" + initjscallback + "'.");
         } catch (Exception e)
         {
-          System.err.println("Exception when executing _oninit callback '"
+          jalview.bin.Console.errPrintln("Exception when executing _oninit callback '"
                   + initjscallback + "'.");
           e.printStackTrace();
         }
       }
       else
       {
-        System.err.println("Not executing _oninit callback '"
+        jalview.bin.Console.errPrintln("Not executing _oninit callback '"
                 + initjscallback + "' - no scripting allowed.");
       }
     }
@@ -1700,7 +1700,7 @@ public class JalviewLite extends Applet
           ((AlignFrame) frame).viewport.applet.currentAlignFrame = (AlignFrame) frame;
           if (debug)
           {
-            System.err.println("Activated window " + frame);
+            jalview.bin.Console.errPrintln("Activated window " + frame);
           }
         }
         // be good.
@@ -1715,7 +1715,7 @@ public class JalviewLite extends Applet
        * 
        * public void windowDeactivated(WindowEvent e) { if (currentAlignFrame ==
        * frame) { currentAlignFrame = null; if (debug) {
-       * System.err.println("Deactivated window "+frame); } }
+       * jalview.bin.Console.errPrintln("Deactivated window "+frame); } }
        * super.windowDeactivated(e); }
        */
     });
@@ -1801,7 +1801,7 @@ public class JalviewLite extends Applet
           }
           if (!jmolAvailable)
           {
-            System.out.println(
+            jalview.bin.Console.outPrintln(
                     "Jmol not available - Using mc_view for structures");
           }
         } catch (java.lang.ClassNotFoundException ex)
@@ -1813,7 +1813,7 @@ public class JalviewLite extends Applet
         jmolAvailable = false;
         if (debug)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Skipping Jmol check. Will use mc_view (probably)");
         }
       }
@@ -1844,7 +1844,7 @@ public class JalviewLite extends Applet
     {
       if (JalviewLite.debug)
       {
-        System.err.println(msg);
+        jalview.bin.Console.errPrintln(msg);
       }
     }
 
@@ -1884,7 +1884,7 @@ public class JalviewLite extends Applet
       {
         if (debug)
         {
-          System.err.println("Prepended document base '" + documentBase
+          jalview.bin.Console.errPrintln("Prepended document base '" + documentBase
                   + "' to make: '" + withDocBase + "'");
         }
         protocol = DataSourceType.URL;
@@ -1903,7 +1903,7 @@ public class JalviewLite extends Applet
         protocol = DataSourceType.URL;
         if (debug)
         {
-          System.err.println("Prepended codebase '" + codeBase
+          jalview.bin.Console.errPrintln("Prepended codebase '" + codeBase
                   + "' to make: '" + withCodeBase + "'");
         }
         return withCodeBase;
@@ -2010,7 +2010,7 @@ public class JalviewLite extends Applet
                   + " as "
                   + (al1.isNucleotide() ? "protein product" : "cDNA")
                   + " for " + af.getTitle();
-          System.err.println(msg);
+          jalview.bin.Console.errPrintln(msg);
         }
       }
 
@@ -2084,7 +2084,7 @@ public class JalviewLite extends Applet
             dbgMsg(">>>Dump finished.");
           } catch (Exception e)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Exception when trying to dump the content of the file parameter.");
             e.printStackTrace();
           }
@@ -2214,7 +2214,7 @@ public class JalviewLite extends Applet
                 {
                   // this may not really be a problem but we give a warning
                   // anyway
-                  System.err.println(
+                  jalview.bin.Console.errPrintln(
                           "Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence "
                                   + i + ")");
                 }
@@ -2320,7 +2320,7 @@ public class JalviewLite extends Applet
         }
         else
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Annotations were not added from annotation file '"
                           + param + "'");
         }
@@ -2392,13 +2392,13 @@ public class JalviewLite extends Applet
         {
           if (debug)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Attempting to load T-COFFEE score file from the scoreFile parameter");
           }
           result = alignFrame.loadScoreFile(sScoreFile);
           if (!result)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Failed to parse T-COFFEE parameter as a valid score file ('"
                             + sScoreFile + "')");
           }
@@ -2469,13 +2469,13 @@ public class JalviewLite extends Applet
         boolean rtn = (getClass().getResourceAsStream("/" + f) != null);
         if (debug)
         {
-          System.err.println("Resource '" + f + "' was "
+          jalview.bin.Console.errPrintln("Resource '" + f + "' was "
                   + (rtn ? "" : "not ") + "located by classloader.");
         }
         return rtn;
       } catch (Exception ex)
       {
-        System.out.println("Exception checking resources: " + f + " " + ex);
+        jalview.bin.Console.outPrintln("Exception checking resources: " + f + " " + ex);
         return false;
       }
     }
@@ -2496,7 +2496,7 @@ public class JalviewLite extends Applet
     {
       return initialAlignFrame;
     }
-    System.err.println(
+    jalview.bin.Console.errPrintln(
             "Implementation error: Jalview Applet API cannot work out which AlignFrame to use.");
     return null;
   }
@@ -2564,18 +2564,18 @@ public class JalviewLite extends Applet
       jv.removeAllElements();
       if (debug)
       {
-        System.err.println("Array from '" + separator
+        jalview.bin.Console.errPrintln("Array from '" + separator
                 + "' separated List:\n" + v.length);
         for (int i = 0; i < v.length; i++)
         {
-          System.err.println("item " + i + " '" + v[i] + "'");
+          jalview.bin.Console.errPrintln("item " + i + " '" + v[i] + "'");
         }
       }
       return v;
     }
     if (debug)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Empty Array from '" + separator + "' separated List");
     }
     return null;
@@ -2620,13 +2620,13 @@ public class JalviewLite extends Applet
       {
         System.err
                 .println("Returning '" + separator + "' separated List:\n");
-        System.err.println(v);
+        jalview.bin.Console.errPrintln(v);
       }
       return v.toString();
     }
     if (debug)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Returning empty '" + separator + "' separated List\n");
     }
     return "" + separator;
@@ -2745,7 +2745,7 @@ public class JalviewLite extends Applet
     this.separator = separator;
     if (debug)
     {
-      System.err.println("Default Separator now: '" + separator + "'");
+      jalview.bin.Console.errPrintln("Default Separator now: '" + separator + "'");
     }
   }
 
@@ -2901,7 +2901,7 @@ public class JalviewLite extends Applet
     Color col = ColorUtils.parseColourString(colprop);
     if (col == null)
     {
-      System.err.println("Couldn't parse '" + colprop + "' as a colour for "
+      jalview.bin.Console.errPrintln("Couldn't parse '" + colprop + "' as a colour for "
               + colparam);
     }
     return (col == null) ? defcolour : col;
@@ -2971,7 +2971,7 @@ public class JalviewLite extends Applet
     }
     if (debug)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "resolveUrlForLocalOrAbsolute returning " + resolvedPath);
     }
     return resolvedPath;
@@ -3000,7 +3000,7 @@ public class JalviewLite extends Applet
                         : getDocumentBase());
         if (debug)
         {
-          System.err.println("Show url (prepended " + prepend
+          jalview.bin.Console.errPrintln("Show url (prepended " + prepend
                   + " - toggle resolvetocodebase if code/docbase resolution is wrong): "
                   + url);
         }
@@ -3009,7 +3009,7 @@ public class JalviewLite extends Applet
       {
         if (debug)
         {
-          System.err.println("Show url: " + url);
+          jalview.bin.Console.errPrintln("Show url: " + url);
         }
       }
       if (url.indexOf("javascript:") == 0)
index f2ffda5..d38892a 100644 (file)
@@ -64,7 +64,7 @@ public class JalviewLiteURLRetrieve extends Applet
     DataSourceType protocol = null;
     try
     {
-      System.out.println("Loading thread started with:\n>>file\n" + file
+      jalview.bin.Console.outPrintln("Loading thread started with:\n>>file\n" + file
               + ">>endfile");
       // This might throw a security exception in certain browsers
       // Netscape Communicator for instance.
@@ -77,7 +77,7 @@ public class JalviewLiteURLRetrieve extends Applet
           rtn = true;
           is.close();
         }
-        System.err.println("Resource '" + file + "' was "
+        jalview.bin.Console.errPrintln("Resource '" + file + "' was "
                 + (rtn ? "" : "not") + " located by classloader.");
         if (rtn)
         {
@@ -86,7 +86,7 @@ public class JalviewLiteURLRetrieve extends Applet
 
       } catch (Exception ex)
       {
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "Exception checking resources: " + file + " " + ex);
       }
       if (file.indexOf("://") > -1)
@@ -99,7 +99,7 @@ public class JalviewLiteURLRetrieve extends Applet
         protocol = DataSourceType.FILE;
       }
 
-      System.out.println("Trying to get contents of resource:");
+      jalview.bin.Console.outPrintln("Trying to get contents of resource:");
       FileParse fp = new FileParse(file, protocol);
       if (fp.isValid())
       {
@@ -112,7 +112,7 @@ public class JalviewLiteURLRetrieve extends Applet
       }
       else
       {
-        System.out.println("Resource at " + file
+        jalview.bin.Console.outPrintln("Resource at " + file
                 + " cannot be read with protocol==" + protocol);
         return;
       }
@@ -121,11 +121,11 @@ public class JalviewLiteURLRetrieve extends Applet
       if (format == null)
       {
         format = new IdentifyFile().identify(file, protocol);
-        System.out.println("Format is " + format);
+        jalview.bin.Console.outPrintln("Format is " + format);
       }
       else
       {
-        System.out.println("User specified Format is " + format);
+        jalview.bin.Console.outPrintln("User specified Format is " + format);
       }
       AlignmentI al = null;
       try
@@ -133,17 +133,17 @@ public class JalviewLiteURLRetrieve extends Applet
         al = new AppletFormatAdapter().readFile(file, protocol, format);
       } catch (java.io.IOException ex)
       {
-        System.err.println("Failed to open the file.");
+        jalview.bin.Console.errPrintln("Failed to open the file.");
         ex.printStackTrace();
       }
       if (al != null)
       {
-        System.out.println(new AppletFormatAdapter()
+        jalview.bin.Console.outPrintln(new AppletFormatAdapter()
                 .formatSequences(FileFormat.Fasta, al, false));
       }
     } catch (Exception e)
     {
-      System.err.println("bailing out : Unexpected exception:");
+      jalview.bin.Console.errPrintln("bailing out : Unexpected exception:");
       e.printStackTrace();
     }
   }
index c7ababa..e04c04f 100644 (file)
@@ -46,7 +46,7 @@ public class JalviewTaskbar
         }
         else
         {
-          System.out.println("Unable to setIconImage()");
+          Console.outPrintln("Unable to setIconImage()");
         }
       }
     }
index a55146d..e1415be 100644 (file)
@@ -26,6 +26,7 @@ import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 
 import jalview.util.ChannelProperties;
 import jalview.util.LaunchUtils;
@@ -49,8 +50,7 @@ public class Launcher
 {
   private final static String startClass = "jalview.bin.Jalview";
 
-  private final static String dockIconPath = ChannelProperties
-          .getProperty("logo.512");
+  private final static String headlessProperty = "java.awt.headless";
 
   /**
    * main method for jalview.bin.Launcher. This restarts the same JRE's JVM with
@@ -64,35 +64,73 @@ public class Launcher
   {
     if (!LaunchUtils.checkJavaVersion())
     {
-      System.err.println("WARNING - The Java version being used (Java "
-              + LaunchUtils.getJavaVersion()
-              + ") may lead to problems. This installation of Jalview should be used with Java "
-              + LaunchUtils.getJavaCompileVersion() + ".");
+      jalview.bin.Console
+              .errPrintln("WARNING - The Java version being used (Java "
+                      + LaunchUtils.getJavaVersion()
+                      + ") may lead to problems. This installation of Jalview should be used with Java "
+                      + LaunchUtils.getJavaCompileVersion() + ".");
     }
 
-    final String javaBin = System.getProperty("java.home") + File.separator
-            + "bin" + File.separator + "java";
-
-    List<String> command = new ArrayList<>();
-    command.add(javaBin);
-
-    String memSetting = null;
-
-    boolean isAMac = System.getProperty("os.name").indexOf("Mac") > -1;
-
-    for (String jvmArg : ManagementFactory.getRuntimeMXBean()
-            .getInputArguments())
-    {
-      command.add(jvmArg);
-    }
-    command.add("-cp");
-    command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
-
     String jvmmempc = null;
     String jvmmemmax = null;
+    boolean debug = false;
+    boolean wait = true;
+    boolean quiet = false;
+    boolean headless = false;
+    boolean gui = false;
+    boolean stdout = false;
+    // must set --debug before --launcher...
+    boolean launcherstop = false;
+    boolean launcherprint = false;
+    boolean launcherwait = false;
     ArrayList<String> arguments = new ArrayList<>();
+    String previousArg = null;
     for (String arg : args)
     {
+      if (arg.equals("--debug"))
+      {
+        debug = true;
+      }
+      if (arg.equals("--quiet"))
+      {
+        quiet = true;
+      }
+      if (arg.equals("--headless"))
+      {
+        headless = true;
+      }
+      if (arg.equals("--gui"))
+      {
+        gui = true;
+      }
+      if (arg.equals("--output=-")
+              || (arg.equals("-") && "--output".equals(previousArg)))
+      {
+        stdout = true;
+      }
+      if (debug && arg.equals("--launcherprint"))
+      {
+        launcherprint = true;
+      }
+      if (debug && arg.equals("--launcherstop"))
+      {
+        launcherstop = true;
+      }
+      if (debug && arg.equals("--launcherwait"))
+      {
+        launcherwait = true;
+      }
+      // this ends the launcher immediately
+      if (debug && arg.equals("--launchernowait"))
+      {
+        wait = false;
+      }
+      previousArg = arg;
+      // Don't add the --launcher... args to Jalview launch
+      if (arg.startsWith("--launcher"))
+      {
+        continue;
+      }
       // jvmmempc and jvmmemmax args used to set memory and are not passed on to
       // startClass
       if (arg.startsWith(
@@ -108,11 +146,49 @@ public class Launcher
         jvmmemmax = arg.substring(
                 MemorySetting.MAX_HEAPSIZE_PROPERTY_NAME.length() + 2);
       }
+      // --doubledash versions
+      else if (arg.startsWith("--"
+              + MemorySetting.MAX_HEAPSIZE_PERCENT_PROPERTY_NAME + "="))
+      {
+        jvmmempc = arg.substring(
+                MemorySetting.MAX_HEAPSIZE_PERCENT_PROPERTY_NAME.length()
+                        + 3);
+      }
+      else if (arg.startsWith(
+              "--" + MemorySetting.MAX_HEAPSIZE_PROPERTY_NAME + "="))
+      {
+        jvmmemmax = arg.substring(
+                MemorySetting.MAX_HEAPSIZE_PROPERTY_NAME.length() + 3);
+      }
+      // retain arg
       else
       {
         arguments.add(arg);
       }
     }
+    if (gui)
+    {
+      // --gui takes precedence over --headless
+      headless = false;
+    }
+
+    final String appName = ChannelProperties.getProperty("app_name");
+
+    // if we're using jalview.bin.Launcher we always assume a console is in use
+    final String javaBin = LaunchUtils.findJavaBin(true);
+
+    List<String> command = new ArrayList<>();
+    command.add(javaBin);
+
+    String memSetting = null;
+
+    for (String jvmArg : ManagementFactory.getRuntimeMXBean()
+            .getInputArguments())
+    {
+      command.add(jvmArg);
+    }
+    command.add("-cp");
+    command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
 
     // use saved preferences if no cmdline args
     boolean useCustomisedSettings = LaunchUtils
@@ -131,10 +207,11 @@ public class Launcher
       }
     }
 
-    // add memory setting if not specified
+    // add these settings if not already specified
     boolean memSet = false;
     boolean dockIcon = false;
     boolean dockName = false;
+    boolean headlessProp = false;
     for (int i = 0; i < command.size(); i++)
     {
       String arg = command.get(i);
@@ -155,6 +232,10 @@ public class Launcher
       {
         dockName = true;
       }
+      else if (arg.startsWith("-D" + headlessProperty + "="))
+      {
+        headlessProp = true;
+      }
     }
 
     if (!memSet)
@@ -169,25 +250,37 @@ public class Launcher
       }
     }
 
-    if (isAMac)
+    if (LaunchUtils.isMac)
     {
       if (!dockIcon)
       {
+        String dockIconPath = System.getProperty("getdownappdir", ".")
+                + File.separator + "resource/jalview_logo.png";
         command.add("-Xdock:icon=" + dockIconPath);
       }
       if (!dockName)
       {
         // -Xdock:name=... doesn't actually work :(
         // Leaving it in in case it gets fixed
-        command.add(
-                "-Xdock:name=" + ChannelProperties.getProperty("app_name"));
+        command.add("-Xdock:name=" + appName);
+        // this launches WITHOUT an icon in the macOS dock. Could be useful for
+        // getdown?
+        // command.add("-Dapple.awt.UIElement=false");
+        // This also does not work for the dock
+        command.add("-Dcom.apple.mrj.application.apple.menu.about.name="
+                + appName);
       }
     }
+    if (headless && !headlessProp)
+    {
+      System.setProperty(headlessProperty, "true");
+      command.add("-D" + headlessProperty + "=true");
+    }
 
     String scalePropertyArg = HiDPISetting.getScalePropertyArg();
     if (scalePropertyArg != null)
     {
-      System.out.println("Running " + startClass + " with scale setting "
+      syserr(debug, quiet, "Running " + startClass + " with scale setting "
               + scalePropertyArg);
       command.add(scalePropertyArg);
     }
@@ -197,29 +290,47 @@ public class Launcher
 
     final ProcessBuilder builder = new ProcessBuilder(command);
 
-    if (Boolean.parseBoolean(System.getProperty("launcherprint", "false")))
+    if ((Boolean.parseBoolean(System.getProperty("launcherprint", "false"))
+            || launcherprint))
     {
-      System.out.println(
+      syserr(debug, quiet,
               "LAUNCHER COMMAND: " + String.join(" ", builder.command()));
     }
-    System.out.println("Running " + startClass + " with "
-            + (memSetting == null ? "no memory setting"
-                    : ("memory setting " + memSetting)));
+    syserr(debug, quiet,
+            "Running " + startClass + " with "
+                    + (memSetting == null ? "no memory setting"
+                            : ("memory setting " + memSetting)));
 
-    if (Boolean.parseBoolean(System.getProperty("launcherstop", "false")))
+    if (Boolean.parseBoolean(System.getProperty("launcherstop", "false"))
+            || (debug && launcherstop))
     {
+      syserr(debug, quiet,
+              "System property 'launcherstop' is set and not 'false'. Exiting.");
       System.exit(0);
     }
     try
     {
       builder.inheritIO();
       Process process = builder.start();
-      process.waitFor();
+      if (wait || launcherwait)
+      {
+        syserr(debug, quiet, "Launching application process");
+        process.waitFor();
+      }
+      else
+      {
+        int waitInt = 0;
+        syserr(debug, quiet,
+                "Wait time for application process is " + waitInt + "ms");
+        process.waitFor(waitInt, TimeUnit.MILLISECONDS);
+      }
+      syserr(debug, quiet, "Launcher process ending");
     } catch (IOException e)
     {
       if (e.getMessage().toLowerCase(Locale.ROOT).contains("memory"))
       {
-        System.out.println("Caught a memory exception: " + e.getMessage());
+        jalview.bin.Console
+                .errPrintln("Caught a memory exception: " + e.getMessage());
         // Probably the "Cannot allocate memory" error, try without the memory
         // setting
         ArrayList<String> commandNoMem = new ArrayList<>();
@@ -232,7 +343,7 @@ public class Launcher
         }
         final ProcessBuilder builderNoMem = new ProcessBuilder(
                 commandNoMem);
-        System.out.println("Command without memory setting: "
+        jalview.bin.Console.errPrintln("Command without memory setting: "
                 + String.join(" ", builderNoMem.command()));
         try
         {
@@ -252,7 +363,14 @@ public class Launcher
     {
       e.printStackTrace();
     }
-    // System.exit(0);
+  }
+
+  private static void syserr(boolean debug, boolean quiet, String message)
+  {
+    if (debug && !quiet)
+    {
+      jalview.bin.Console.errPrintln("LAUNCHERDEBUG - " + message);
+    }
   }
 
 }
index bb545cb..7458d55 100644 (file)
@@ -354,7 +354,7 @@ public class MemorySetting
     else
     {
       // number too big for a Long. Limit to Long.MAX_VALUE
-      System.out.println("Memory parsing of '" + memString
+      jalview.bin.Console.outPrintln("Memory parsing of '" + memString
               + "' produces number too big.  Limiting to Long.MAX_VALUE="
               + Long.MAX_VALUE);
       return Long.MAX_VALUE;
@@ -395,7 +395,7 @@ public class MemorySetting
     ADJUSTMENT_MESSAGE = reason;
     if (!quiet)
     {
-      System.out.println(reason);
+      jalview.bin.Console.outPrintln(reason);
     }
   }
 
diff --git a/src/jalview/bin/argparser/Arg.java b/src/jalview/bin/argparser/Arg.java
new file mode 100644 (file)
index 0000000..7882d7b
--- /dev/null
@@ -0,0 +1,992 @@
+package jalview.bin.argparser;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
+
+import jalview.bin.argparser.Arg.Opt;
+import jalview.util.ChannelProperties;
+import jalview.util.Platform;
+
+public enum Arg
+{
+
+  // Initialising arguments (BOOTSTRAP)
+  HELP(Type.HELP, "h", "Display basic help", Opt.UNARY, Opt.BOOTSTRAP,
+          Opt.HASTYPE, Opt.MULTI),
+  /*
+   * Other --help-type Args will be added by the static block.
+   */
+  VERSION(Type.CONFIG, "v",
+          "Display the version of "
+                  + ChannelProperties.getProperty("app_name"),
+          Opt.UNARY, Opt.BOOTSTRAP),
+  HEADLESS(Type.CONFIG,
+          "Run Jalview in headless mode. No GUI interface will be created and Jalview will quit after all arguments have been processed. "
+                  + "Headless mode is assumed if an output file is to be generated, this can be overridden with --gui.",
+          Opt.UNARY, Opt.BOOTSTRAP),
+  GUI(Type.CONFIG,
+          "Do not run Jalview in headless mode.  This overrides the assumption of headless mode when an output file is to be generated.",
+          Opt.UNARY, Opt.BOOTSTRAP),
+  JABAWS(Type.CONFIG, "Set a different URL to connect to a JABAWS server.",
+          Opt.STRING, Opt.BOOTSTRAP),
+  NEWS(Type.CONFIG, "Show (or don't show) the news feed.", true,
+          Opt.BOOLEAN, Opt.BOOTSTRAP),
+  SPLASH(Type.CONFIG,
+          "Show (or don't show) the About Jalview splash screen.", true,
+          Opt.BOOLEAN, Opt.BOOTSTRAP),
+  QUESTIONNAIRE(Type.CONFIG,
+          "Show (or don't show) the questionnaire if one is available.",
+          true, Opt.BOOLEAN, Opt.BOOTSTRAP),
+  NOUSAGESTATS(Type.CONFIG, "Don't send initial launch usage stats.",
+          Opt.UNARY, Opt.BOOTSTRAP),
+  NOSTARTUPFILE(Type.CONFIG, "Don't show the default startup file.",
+          Opt.UNARY, Opt.BOOTSTRAP),
+  WEBSERVICEDISCOVERY(Type.CONFIG,
+          "Attempt (or don't attempt) to connect to JABAWS web services.",
+          true, Opt.BOOLEAN, Opt.BOOTSTRAP),
+  PROPS(Type.CONFIG,
+          "Use a file as the preferences file instead of the usual ~/"
+                  + ChannelProperties.getProperty("preferences.filename")
+                  + " file.",
+          Opt.STRING, Opt.BOOTSTRAP),
+  DEBUG(Type.CONFIG, "d", "Start Jalview in debug log level.", Opt.BOOLEAN,
+          Opt.BOOTSTRAP),
+  TRACE(Type.CONFIG, "Start Jalview in trace log level.", Opt.BOOLEAN,
+          Opt.BOOTSTRAP, Opt.SECRET),
+  QUIET(Type.CONFIG, "q",
+          "Stop all output to STDOUT (after the Java Virtual Machine has started). Use ‑‑quiet a second time to stop all output to STDERR.",
+          Opt.UNARY, Opt.MULTI, Opt.BOOTSTRAP),
+  INITSUBSTITUTIONS(Type.CONFIG,
+          "Set ‑‑substitutions to be initially enabled (or initially disabled).",
+          true, Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION, Opt.SECRET),
+  P(Type.CONFIG, "Set a Jalview preference value for this session.",
+          Opt.PREFIXKEV, Opt.PRESERVECASE, Opt.STRING, Opt.BOOTSTRAP,
+          Opt.MULTI, Opt.NOACTION, Opt.SECRET), // keep this secret for now.
+
+  // Opening an alignment
+  OPEN(Type.OPENING,
+          "Opens one or more alignment files or URLs in new alignment windows.",
+          Opt.STRING, Opt.LINKED, Opt.INCREMENTDEFAULTCOUNTER, Opt.MULTI,
+          Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT, Opt.STORED,
+          Opt.PRIMARY),
+  APPEND(Type.OPENING,
+          "Appends one or more alignment files or URLs to the open alignment window (or opens a new alignment if none already open).",
+          Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
+          Opt.ALLOWSUBSTITUTIONS, Opt.INPUT, Opt.PRIMARY),
+  TITLE(Type.OPENING,
+          "Specifies the title for the open alignment window as string.",
+          Opt.STRING, Opt.LINKED),
+  COLOUR(Type.OPENING, "color", // being a bit soft on the Americans!
+          "Applies the colour scheme to the open alignment window. Valid values include:\n"
+                  + "clustal,\n" + "blosum62,\n" + "pc-identity,\n"
+                  + "zappo,\n" + "taylor,\n" + "gecos-flower,\n"
+                  + "gecos-blossom,\n" + "gecos-sunset,\n"
+                  + "gecos-ocean,\n" + "hydrophobic,\n"
+                  + "helix-propensity,\n" + "strand-propensity,\n"
+                  + "turn-propensity,\n" + "buried-index,\n"
+                  + "nucleotide,\n" + "nucleotide-ambiguity,\n"
+                  + "purine-pyrimidine,\n" + "rna-helices,\n"
+                  + "t-coffee-scores,\n" + "sequence-id.\n" + "\n"
+                  + "Names of user defined colourschemes will also work,\n"
+                  + "and jalview colourscheme specifications like\n"
+                  + "--colour=\"D,E=red; K,R,H=0022FF; C,c=yellow\"",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  FEATURES(Type.OPENING, "Add a feature file or URL to the open alignment.",
+          Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS),
+  TREE(Type.OPENING, "Add a tree file or URL to the open alignment.",
+          Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS),
+  SORTBYTREE(Type.OPENING,
+          "Enforces sorting (or not sorting) the open alignment in the order of an attached phylogenetic tree.",
+          true, Opt.LINKED, Opt.BOOLEAN, Opt.ALLOWALL),
+  ANNOTATIONS(Type.OPENING,
+          "Add an annotations file or URL to the open alignment.",
+          Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS),
+  SHOWANNOTATIONS(Type.OPENING,
+          "Enforces showing (or not showing) alignment annotations.",
+          Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL),
+  WRAP(Type.OPENING,
+          "Enforces wrapped (or not wrapped) alignment formatting.",
+          Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL),
+  NOSTRUCTURE(Type.OPENING,
+          "Do not open or process any 3D structure in the ‑‑open or ‑‑append files.",
+          Opt.UNARY, Opt.LINKED, Opt.ALLOWALL),
+
+  // Adding a 3D structure
+  STRUCTURE(Type.STRUCTURE,
+          "Load a structure file or URL associated with a sequence in the open alignment.\n"
+                  + "The sequence to be associated with can be specified with a following --seqid argument, or the subval modifier seqid=ID can be used. A subval INDEX can also be used to specify the INDEX-th sequence in the open alignment.",
+          Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS,
+          Opt.PRIMARY),
+  SEQID(Type.STRUCTURE,
+          "Specify the sequence name for the preceding --structure to be associated with.",
+          Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS),
+  PAEMATRIX(Type.STRUCTURE,
+          "Add a PAE json matrix file to the preceding --structure.",
+          Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS),
+  TEMPFAC(Type.STRUCTURE,
+          "Set the type of temperature factor. Possible values are:\n"
+                  + "default,\n" + "plddt.",
+          Opt.STRING, Opt.LINKED),
+  STRUCTUREVIEWER(Type.STRUCTURE,
+          "Set the structure viewer to use to open the 3D structure file specified in previous --structure to name. Possible values of name are:\n"
+                  + "none,\n" + "jmol,\n" + "chimera,\n" + "chimerax,\n"
+                  + "pymol.",
+          Opt.STRING, Opt.LINKED, Opt.MULTI),
+  NOTEMPFAC(Type.STRUCTURE,
+          "Do not show the temperature factor annotation for the preceding --structure.",
+          Opt.UNARY, Opt.LINKED, Opt.ALLOWALL, Opt.SECRET), // keep this secret
+                                                            // until it works!
+  SHOWSSANNOTATIONS(Type.STRUCTURE, null, Opt.BOOLEAN, Opt.LINKED,
+          Opt.ALLOWALL),
+
+  // Outputting files
+  IMAGE(Type.IMAGE,
+          "Output an image of the open alignment window. Format is specified by the subval modifier, a following --type argument or guessed from the file extension. Valid formats/extensions are:\n"
+                  + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.ALLOWALL,
+          Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.PRIMARY),
+  TYPE(Type.IMAGE,
+          "Set the image format for the preceding --image. Valid values are:\n"
+                  + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  TEXTRENDERER(Type.IMAGE,
+          "Sets whether text in a vector image format (SVG, HTML, EPS) should be rendered as text or vector line-art. Possible values are:\n"
+                  + "text,\n" + "lineart.",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  SCALE(Type.IMAGE,
+          "Sets a scaling for bitmap image format (PNG). Should be given as a floating point number. If used in conjunction with --width and --height then the smallest scaling will be used (scale, width and height provide bounds for the image).",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  WIDTH(Type.IMAGE,
+          "Sets a width for bitmap image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --scale and --height then the smallest scaling will be used (scale, width and height provide bounds for the image).",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  HEIGHT(Type.IMAGE,
+          "Sets a height for bitmap image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --scale and --width then the smallest scaling will be used (scale, width and height provide bounds for the image).",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  STRUCTUREIMAGE(Type.STRUCTUREIMAGE,
+          "Export an image of a 3D structure opened in JMOL", Opt.STRING,
+          Opt.LINKED, Opt.MULTI, Opt.OUTPUTFILE),
+  STRUCTUREIMAGETYPE(Type.STRUCTUREIMAGE,
+          "Set the structure image format for the preceding --structureimage. Valid values are:\n"
+                  + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  STRUCTUREIMAGETEXTRENDERER(Type.STRUCTUREIMAGE,
+          "Sets whether text in a vector structure image format (SVG, EPS) should be rendered as text or vector line-art. Possible values are:\n"
+                  + "text,\n" + "lineart.",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  STRUCTUREIMAGESCALE(Type.STRUCTUREIMAGE,
+          "Sets a scaling for bitmap structure image format (PNG). Should be given as a floating point number. If used in conjunction with --structureimagewidth and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  STRUCTUREIMAGEWIDTH(Type.STRUCTUREIMAGE,
+          "Sets a width for bitmap structure image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  STRUCTUREIMAGEHEIGHT(Type.STRUCTUREIMAGE,
+          "Sets a height for bitmap structure image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimagewidth then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+
+  OUTPUT(Type.OUTPUT,
+          "Export the open alignment to file filename. The format name is specified by the subval modifier format=name, a following --format name argument or guessed from the file extension. Valid format names (and file extensions) are:\n"
+                  + "fasta (fa, fasta, mfa, fastq),\n" + "pfam (pfam),\n"
+                  + "stockholm (sto, stk),\n" + "pir (pir),\n"
+                  + "blc (blc),\n" + "amsa (amsa),\n" + "json (json),\n"
+                  + "pileup (pileup),\n" + "msf (msf),\n"
+                  + "clustal (aln),\n" + "phylip (phy),\n"
+                  + "jalview (jvp, jar).",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.ALLOWALL,
+          Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.STDOUT, Opt.PRIMARY),
+  FORMAT(Type.OUTPUT,
+          "Sets the format for the preceding --output file. Valid formats are:\n"
+                  + "fasta,\n" + "pfam,\n" + "stockholm,\n" + "pir,\n"
+                  + "blc,\n" + "amsa,\n" + "json,\n" + "pileup,\n"
+                  + "msf,\n" + "clustal,\n" + "phylip,\n" + "jalview.",
+          Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
+  GROOVY(Type.PROCESS,
+          "Process a groovy script in the file for the open alignment.",
+          Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS,
+          Opt.ALLOWALL),
+  BACKUPS(Type.OUTPUT,
+          "Enable (or disable) writing backup files when saving an ‑‑output file. This applies to the current open alignment.  To apply to all ‑‑output and ‑‑image files, use after ‑‑all.",
+          true, Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL),
+  OVERWRITE(Type.OUTPUT,
+          "Enable (or disable) overwriting of output files without backups enabled. This applies to the current open alignment.  To apply to all ‑‑output and ‑‑image files, use after ‑‑all.",
+          Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL),
+  CLOSE(Type.OPENING,
+          "Close the current open alignment window. This occurs after other output arguments. This applies to the current open alignment.  To apply to all ‑‑output and ‑‑image files, use after ‑‑all.",
+          Opt.UNARY, Opt.LINKED, Opt.ALLOWALL),
+
+  // controlling flow of arguments
+  NEW(Type.FLOW,
+          "Move on to a new alignment window. This will ensure --append will start a new alignment window and other linked arguments will apply to the new alignment window.",
+          Opt.UNARY, Opt.MULTI, Opt.NOACTION, Opt.INCREMENTDEFAULTCOUNTER),
+  SUBSTITUTIONS(Type.FLOW,
+          "The following argument values allow (or don't allow) subsituting filename parts. This is initially true. Valid substitutions are:\n"
+                  + "{basename} - the filename-without-extension of the currently --opened file (or first --appended file),\n"
+                  + "{dirname} - the directory (folder) name of the currently --opened file (or first --appended file),\n"
+                  + "{argfilebasename} - the filename-without-extension of the current --argfile,\n"
+                  + "{argfiledirname} - the directory (folder) name of the current --argfile,\n"
+                  + "{n} - the value of the index counter (starting at 0).\n"
+                  + "{++n} - increase and substitute the value of the index counter,\n"
+                  + "{} - the value of the current alignment window default index.",
+          true, Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION),
+  ARGFILE(Type.FLOW,
+          "Open one or more files filename and read, line-by-line, as arguments to Jalview.\n"
+                  + "Values in an argfile should be given with an equals sign (\"=\") separator with no spaces.\n"
+                  + "Note that if you use one or more --argfile arguments then all other non-initialising arguments will be ignored.",
+          Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.GLOB,
+          Opt.ALLOWSUBSTITUTIONS),
+  NPP(Type.FLOW, "n++",
+          "Increase the index counter used in argument value substitutions.",
+          Opt.UNARY, Opt.MULTI, Opt.NOACTION),
+  ALL(Type.FLOW,
+          "Apply the following output arguments to all sets of linked arguments.",
+          Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION),
+  OPENED(Type.FLOW,
+          "Apply the following output arguments to all of the last --open'ed set of linked arguments.",
+          Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION),
+  QUIT(Type.FLOW,
+          "After all files have been opened, appended and output, quit Jalview. In ‑‑headless mode this already happens.",
+          Opt.UNARY),
+  NOQUIT(Type.FLOW,
+          "Secret arg to not quit after --headless mode for tests",
+          Opt.UNARY, Opt.SECRET),
+  ALLSTRUCTURES(Type.FLOW,
+          "Apply the following 3D structure formatting arguments to all structures within the open alignment.",
+          Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION),
+
+  // secret options
+  TESTOUTPUT(Type.CONFIG,
+          "Allow specific stdout information.  For testing purposes only.",
+          Opt.UNARY, Opt.BOOTSTRAP, Opt.SECRET), // do not show this to the user
+  SETPROP(Type.CONFIG, "Set an individual Java System property.",
+          Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.SECRET), // not in use yet
+  NIL(Type.FLOW,
+          "This argument does nothing on its own, but can be used with linkedIds.",
+          Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.NOACTION, Opt.SECRET),
+
+  // private options (inserted during arg processing)
+  SETARGFILE(Type.FLOW,
+          "Sets the current value of the argfilename.  Inserted before argfilecontents.",
+          Opt.UNARY, Opt.LINKED, Opt.STRING, Opt.MULTI, Opt.PRIVATE,
+          Opt.NOACTION),
+  UNSETARGFILE(Type.FLOW,
+          "Unsets the current value of the argfilename.  Inserted after argfile contents.",
+          Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.PRIVATE, Opt.NOACTION),
+
+  // these last two have no purpose in the normal Jalview application but are
+  // used by jalview.bin.Launcher to set memory settings. They are not used by
+  // argparser but are here for Usage statement reasons.
+  JVMMEMPC(Type.CONFIG,
+          "Limit maximum heap size (memory) to PERCENT% of total physical memory detected. This defaults to 90 if total physical memory can be detected.\n"
+                  + "The equals sign (\"=\") separator must be used with no spaces.",
+          Opt.NOACTION, Opt.BOOTSTRAP, Opt.STRING, Opt.LAST),
+  JVMMEMMAX(Type.CONFIG,
+          "Limit maximum heap size (memory) to MAXMEMORY. MAXMEMORY can be specified in bytes, kilobytes(k), megabytes(m), gigabytes(g) or if you're lucky enough, terabytes(t). This defaults to 32g if total physical memory can be detected, or to 8g if total physical memory cannot be detected.\n"
+                  + "The equals sign (\"=\") separator must be used with no spaces.",
+          Opt.NOACTION, Opt.BOOTSTRAP, Opt.STRING, Opt.LAST),
+
+  ;
+
+  public static enum Opt
+  {
+    /*
+     * A BOOLEAN Arg can be specified as --arg or --noarg to give true or false.
+     * A default can be given with setOptions(bool, Opt....).
+     * Use ArgParser.isSet(Arg) to see if this arg was not specified.
+     */
+    BOOLEAN("can be negated with " + ArgParser.DOUBLEDASH
+            + ArgParser.NEGATESTRING + "..."),
+
+    /*
+     * A STRING Arg will take a value either through --arg=value or --arg value.
+     */
+    STRING("expects a value"),
+    /*
+     * A UNARY Arg is a boolean value, true if present, false if not.
+     * Like BOOLEAN but without the --noarg option.
+     */
+    UNARY(null),
+    /*
+     * A MULTI Arg can be specified multiple times.
+     * Multiple values are stored in the ArgValuesMap (along with their positional index) for each linkedId.
+     */
+    MULTI("can be specified multiple times"),
+    /*
+     * A Linked Arg can be linked to others through a --arg[linkedId] or --arg[linkedId]=value.
+     * If no linkedId is specified then the current default linkedId will be used.
+     */
+    LINKED("is linked to an alignment"),
+    /*
+     * A NODUPLICATES Arg can only have one value (per linkedId).
+     * The first value will be used and subsequent values ignored with a warning.
+     */
+    NODUPLICATEVALUES("cannot have the same value more than once"),
+    /*
+     * A BOOTSTRAP Arg value(s) can be determined at an earlier stage than non-BOOTSTRAP Args.
+     * Substitutions do not happen in BOOTSTRAP Args and they cannot be linked or contain SubVals.
+     * See jalview.bin.argparser.BootstrapArgs.
+     */
+    BOOTSTRAP("a configuration argument"),
+    /*
+     * A GLOB Arg can expand wildcard filename "globs" (e.g. path/* /filename*).
+     * If the Arg value is given as --arg filename* then the shell will have expanded the glob already,
+     * but if specified as --arg=filename* then the Java glob expansion method will be used
+     * (see FileUtils.getFilenamesFromGlob()).
+     * Note that this might be different from the shell expansion rules.
+     */
+    GLOB("can take multiple filenames with wildcards"),
+    /*
+     * A NOACTION Arg does not perform a data task,
+     * usually used to control flow in ArgParser.parse(args).
+     */
+    NOACTION(null),
+    /*
+     * An ALLOWSUBSTITUTIONS Arg allows substitutions in its linkedId,
+     * SubVals and values.
+     */
+    ALLOWSUBSTITUTIONS("values can use substitutions"),
+    /*
+     * A PRIVATE Arg is used internally, and cannot be specified by the user.
+     */
+    PRIVATE(null),
+    /*
+     * A SECRET Arg is used by development processes and although it can be set by the user,
+     * it is not displayed to the user.
+     */
+    SECRET(null),
+    /*
+     * An ALLOWALL Arg can use the '*' linkedId to apply to all known linkedIds
+     */
+    ALLOWALL("can be used with " + ArgParser.DOUBLEDASH + "all"),
+    /*
+     * If an Arg has the INCREMENTDEFAULTCOUNTER option and the default linkedId is used,
+     * the defaultLinkedIdCounter is incremented *first*.
+     */
+    INCREMENTDEFAULTCOUNTER("starts a new default alignment"),
+    /*
+     * An INPUT Arg counts as an input for REQUIREINPUT
+     */
+    INPUT(null),
+    /*
+     * A REQUIREINPUT Arg can only be applied via --all if there is an input
+     * (i.e. --open or --append)
+     */
+    REQUIREINPUT(null),
+    /*
+     * An OUTPUTFILE Arg provides an output filename. With Opt.ALLOWALL *.ext is shorthand for
+     * --all --output={basename}.ext
+     */
+    OUTPUTFILE("output file --headless will be assumed unless --gui used"),
+    /*
+     * A STDOUT Arg can take an output filename that can be '-' to mean print to STDOUT.
+     */
+    STDOUT("allows the output filename '" + ArgParser.STDOUTFILENAME
+            + "' to mean output to STDOUT"),
+    /*
+     * A STORED Arg resets and creates a new set of "opened" linkedIds
+     */
+    STORED(null),
+    /*
+     * A HELP Arg is a --help type arg
+     */
+    HELP("provides a help statement"),
+    /*
+     * A PRIMARY Arg is the main Arg for its type
+     */
+    PRIMARY("is a primary argument for its type"),
+    /*
+     * A HASTYPE Arg can have an Arg.Type assigned to its ArgValue
+     */
+    HASTYPE(null),
+    /*
+     * A FIRST arg gets moved to appear first in the usage statement (within type)
+     */
+    FIRST(null),
+    /*
+     * A LAST arg gets moved to appear last in the usage statement (within type)
+     */
+    LAST(null),
+    /*
+     * After other args are checked, the following args can prefix a KEY=VALUE argument
+     */
+    PREFIXKEV("prefixes key=value"),
+    /*
+     * do not lowercase the name when getting the arg name or arg string
+     */
+    PRESERVECASE(null),
+    //
+    ;
+
+    private String description;
+
+    private Opt()
+    {
+      description = null;
+    }
+
+    private Opt(String description)
+    {
+      this.description = description;
+    }
+
+    public String description()
+    {
+      return description;
+    }
+
+  }
+
+  public static enum Type
+  {
+    // Type restricts argument to certain usage output
+    HELP, // --help
+    CONFIG("arguments used to configure "
+            + ChannelProperties.getProperty("app_name") + " from startup"),
+    OPENING("arguments used to open and format alignments"),
+    STRUCTURE("arguments used to add and format 3D structure data"),
+    PROCESS("arguments used to process an alignment once opened"),
+    OUTPUT("arguments used to save data from a processed alignment"),
+    IMAGE("arguments used to export an image of an alignment"),
+    STRUCTUREIMAGE("arguments used to export an image of an structure"),
+    FLOW("arguments that control processing of the other arguments"), //
+    ALL("all arguments"), // mostly just a place-holder for --help-all
+    NONE, // mostly a place-holder for --help
+    INVALID;
+
+    private String description;
+
+    private Type()
+    {
+      description = null;
+    }
+
+    private Type(String description)
+    {
+      this.description = description;
+    }
+
+    public String description()
+    {
+      return description;
+    }
+  }
+
+  private final String[] argNames;
+
+  private Opt[] argOptions;
+
+  private boolean defaultBoolValue;
+
+  private String description;
+
+  private Type type;
+
+  private Arg(Type type, String description, Opt... options)
+  {
+    this(type, null, description, false, options);
+  }
+
+  private Arg(Type type, String description, boolean defaultBoolean,
+          Opt... options)
+  {
+    this(type, null, description, defaultBoolean, options);
+  }
+
+  private Arg(Type type, String alternativeName, String description,
+          Opt... options)
+  {
+    this(type, alternativeName, description, false, options);
+  }
+
+  private Arg(Type type, String alternativeName, String description,
+          boolean defaultBoolean, Opt... options)
+  {
+    this.type = type;
+    this.description = description;
+    this.defaultBoolValue = defaultBoolean;
+    this.setOptions(options);
+    this.argNames = alternativeName != null
+            ? new String[]
+            { this.getName(), alternativeName }
+            : new String[]
+            { this.getName() };
+  }
+
+  public String argString()
+  {
+    return argString(false);
+  }
+
+  public String negateArgString()
+  {
+    return argString(true);
+  }
+
+  private String argString(boolean negate)
+  {
+    StringBuilder sb = new StringBuilder(ArgParser.DOUBLEDASH);
+    if (negate && hasOption(Opt.BOOLEAN))
+      sb.append(ArgParser.NEGATESTRING);
+    sb.append(getName());
+    return sb.toString();
+  }
+
+  public String toLongString()
+  {
+    StringBuilder sb = new StringBuilder();
+    sb.append(this.getClass().getName()).append('.').append(this.name());
+    sb.append('(');
+    if (getNames().length > 0)
+      sb.append('"');
+    sb.append(String.join("\", \"", getNames()));
+    if (getNames().length > 0)
+      sb.append('"');
+    sb.append(")\n");
+    sb.append("\nType: " + type.name());
+    sb.append("\nOpt: ");
+    // map List<Opt> to List<String> for the String.join
+    List<String> optList = Arrays.asList(argOptions).stream()
+            .map(opt -> opt.name()).collect(Collectors.toList());
+    sb.append(String.join(", ", optList));
+    sb.append("\n");
+    return sb.toString();
+  }
+
+  public String[] getNames()
+  {
+    return argNames;
+  }
+
+  public String getName()
+  {
+    String name = hasOption(Opt.PRESERVECASE) ? this.name()
+            : this.name().toLowerCase(Locale.ROOT);
+    return name.replace('_', '-');
+  }
+
+  @Override
+  public final String toString()
+  {
+    return getName();
+  }
+
+  public boolean hasOption(Opt o)
+  {
+    if (argOptions == null)
+      return false;
+    for (Opt option : argOptions)
+    {
+      if (o == option)
+        return true;
+    }
+    return false;
+  }
+
+  public boolean hasAllOptions(Opt... opts)
+  {
+    for (Opt o : opts)
+    {
+      if (!this.hasOption(o))
+        return false;
+    }
+    return true;
+  }
+
+  protected Opt[] getOptions()
+  {
+    return argOptions;
+  }
+
+  protected void setOptions(Opt... options)
+  {
+    this.argOptions = options;
+  }
+
+  protected boolean getDefaultBoolValue()
+  {
+    return defaultBoolValue;
+  }
+
+  public Type getType()
+  {
+    return this.type;
+  }
+
+  protected String getDescription()
+  {
+    return description;
+  }
+
+  public static String booleanArgString(Arg a)
+  {
+    StringBuilder sb = new StringBuilder(a.argString());
+    if (a.hasOption(Opt.BOOLEAN))
+    {
+      sb.append('/');
+      sb.append(a.negateArgString());
+    }
+    return sb.toString();
+  }
+
+  public static final String usage()
+  {
+    return usage(null);
+  }
+
+  public static final void appendUsageGeneral(StringBuilder sb,
+          int maxArgLength)
+  {
+    for (Type t : EnumSet.allOf(Type.class))
+    {
+      if (t.description() != null)
+      {
+        StringBuilder argSb = new StringBuilder();
+        argSb.append(Arg.HELP.argString()).append(ArgParser.SINGLEDASH)
+                .append(t.name().toLowerCase(Locale.ROOT));
+        appendArgAndDescription(sb, argSb.toString(),
+                "Help for " + t.description(), null, maxArgLength);
+        sb.append(System.lineSeparator());
+      }
+    }
+  }
+
+  public static final String usage(List<Type> types)
+  {
+    StringBuilder sb = new StringBuilder();
+
+    sb.append("usage: jalview [" + Arg.HEADLESS.argString() + "] [["
+            + Arg.OPEN.argString() + "/" + Arg.APPEND.argString()
+            + "] file(s)] [args]");
+    sb.append(System.lineSeparator());
+    sb.append(System.lineSeparator());
+
+    if (types == null || types.contains(null))
+    {
+      // always show --help
+      appendArgAndDescription(sb, null, "Display this basic help", Arg.HELP,
+              DESCRIPTIONINDENT);
+      sb.append(System.lineSeparator());
+
+      appendUsageGeneral(sb, DESCRIPTIONINDENT);
+    }
+    else
+    {
+      List<Arg> args = argsSortedForDisplay(types);
+
+      /*
+       * just use a set maxArgLength of DESCRIPTIONINDENT
+       
+      int maxArgLength = 0;
+      for (Arg a : args)
+      {
+        if (a.hasOption(Opt.PRIVATE) || a.hasOption(Opt.SECRET))
+          continue;
+      
+        String argS = argDisplayString(a);
+        if (argS.length() > maxArgLength)
+          maxArgLength = argS.length();
+      }
+      */
+      int maxArgLength = DESCRIPTIONINDENT;
+
+      // always show --help
+      appendArgAndDescription(sb, null, null, Arg.HELP, maxArgLength);
+      sb.append(System.lineSeparator());
+
+      if ((args.contains(Arg.HELP) && types.contains(Type.ALL)))
+      {
+        appendUsageGeneral(sb, maxArgLength);
+      }
+
+      Iterator<Arg> argsI = args.iterator();
+      Type typeSection = null;
+      while (argsI.hasNext())
+      {
+        Arg a = argsI.next();
+
+        if (a.hasOption(Opt.PRIVATE) || a.hasOption(Opt.SECRET)
+                || a == Arg.HELP)
+        {
+          continue;
+        }
+
+        if (a.getType() != typeSection)
+        {
+          typeSection = a.getType();
+          String typeDescription = a.getType().description();
+          if (typeDescription != null && typeDescription.length() > 0)
+          {
+            // typeDescription = typeDescription.substring(0,
+            // 1).toUpperCase(Locale.ROOT) + typeDescription.substring(1);
+            typeDescription = typeDescription.toUpperCase(Locale.ROOT);
+            sb.append(typeDescription);
+            sb.append(System.lineSeparator());
+            sb.append(System.lineSeparator());
+          }
+        }
+
+        appendArgUsage(sb, a, maxArgLength, Platform.consoleWidth());
+
+        if (argsI.hasNext())
+        {
+          sb.append(System.lineSeparator());
+        }
+      }
+    }
+    return sb.toString();
+  }
+
+  private static void appendArgUsage(StringBuilder sb, Arg a,
+          int maxArgLength, int maxWidth)
+  {
+    boolean first = appendArgAndDescription(sb, null, null, a,
+            maxArgLength);
+    List<String> options = new ArrayList<>();
+
+    for (Opt o : EnumSet.allOf(Opt.class))
+    {
+      if (a.hasOption(o) && o.description() != null)
+      {
+        options.add(o.description());
+      }
+    }
+
+    final String optDisplaySeparator = "; ";
+    if (options.size() > 0)
+    {
+      int linelength = 0;
+      String spacing = String.format("%-"
+              + (maxArgLength + ARGDESCRIPTIONSEPARATOR.length()) + "s",
+              "");
+      if (first)
+      {
+        sb.append(ARGDESCRIPTIONSEPARATOR);
+        linelength += maxArgLength + ARGDESCRIPTIONSEPARATOR.length();
+      }
+      else
+      {
+        sb.append(spacing);
+        linelength += spacing.length();
+      }
+      if (options.size() > 0)
+      {
+        boolean optFirst = true;
+        Iterator<String> optionsI = options.listIterator();
+        while (optionsI.hasNext())
+        {
+          String desc = optionsI.next();
+          if (optFirst)
+          {
+            sb.append("(");
+            linelength += 1;
+          }
+          int descLength = desc.length()
+                  + (optionsI.hasNext() ? optDisplaySeparator.length() : 0);
+          if (linelength + descLength > maxWidth)
+          {
+            sb.append(System.lineSeparator());
+            linelength = 0;
+            sb.append(spacing);
+            linelength += spacing.length();
+          }
+          // sb.append(linelength + "+" + desc.length() + " ");
+          sb.append(desc);
+          linelength += desc.length();
+          if (optionsI.hasNext())
+          {
+            sb.append(optDisplaySeparator);
+            linelength += optDisplaySeparator.length();
+          }
+          optFirst = false;
+        }
+        sb.append(')');
+        sb.append(System.lineSeparator());
+      }
+    }
+  }
+
+  public static String argDisplayString(Arg a)
+  {
+    StringBuilder argSb = new StringBuilder();
+    argSb.append(
+            a.hasOption(Opt.BOOLEAN) ? booleanArgString(a) : a.argString());
+    if (a.hasOption(Opt.STRING))
+    {
+      if (a.hasOption(Opt.PREFIXKEV))
+      {
+        argSb.append("key=value");
+      }
+      else
+      {
+        argSb.append("=value");
+      }
+    }
+    return argSb.toString();
+  }
+
+  public static boolean appendArgAndDescription(StringBuilder sb,
+          String aString, String description, Arg a, int maxArgLength)
+  {
+    return appendArgAndDescription(sb, aString, description, a,
+            maxArgLength, Platform.consoleWidth());
+  }
+
+  public static boolean appendArgAndDescription(StringBuilder sb,
+          String aString, String description, Arg a, int maxArgLength,
+          int maxLength)
+  {
+    if (aString == null && a != null)
+    {
+      aString = argDisplayString(a);
+    }
+    if (description == null && a != null)
+    {
+      description = a.getDescription();
+    }
+    sb.append(String.format("%-" + maxArgLength + "s", aString));
+    if (aString.length() > maxArgLength)
+    {
+      sb.append(System.lineSeparator());
+      sb.append(String.format("%-" + maxArgLength + "s", ""));
+    }
+
+    int descLength = maxLength - maxArgLength
+            - ARGDESCRIPTIONSEPARATOR.length();
+    // reformat the descriptions lines to the right width
+    Iterator<String> descLines = null;
+    if (description != null)
+    {
+      descLines = Arrays.stream(description.split("\\n")).iterator();
+    }
+    List<String> splitDescLinesList = new ArrayList<>();
+    while (descLines != null && descLines.hasNext())
+    {
+      String line = descLines.next();
+      while (line.length() > descLength)
+      {
+        int splitIndex = line.lastIndexOf(" ", descLength);
+        splitDescLinesList.add(line.substring(0, splitIndex));
+        line = line.substring(splitIndex + 1);
+      }
+      splitDescLinesList.add(line);
+    }
+
+    Iterator<String> splitDescLines = splitDescLinesList.iterator();
+    boolean first = true;
+    if (splitDescLines != null)
+    {
+      while (splitDescLines.hasNext())
+      {
+        if (first)
+        {
+          sb.append(ARGDESCRIPTIONSEPARATOR);
+        }
+        else
+        {
+          sb.append(String.format("%-"
+                  + (maxArgLength + ARGDESCRIPTIONSEPARATOR.length()) + "s",
+                  ""));
+        }
+        sb.append(splitDescLines.next());
+        sb.append(System.lineSeparator());
+        first = false;
+      }
+    }
+    return first;
+  }
+
+  protected static Iterator<Arg> getAllOfType(Type type)
+  {
+    return getAllOfType(type, new Opt[] {});
+  }
+
+  protected static Iterator<Arg> getAllOfType(Type type, Opt... options)
+  {
+    Opt[] opts = options == null ? new Opt[] {} : options;
+    return EnumSet.allOf(Arg.class).stream().filter(a -> {
+      if (a.getType() != type)
+        return false;
+      for (Opt o : opts)
+      {
+        if (!a.hasOption(o))
+          return false;
+      }
+      return true;
+    }).iterator();
+  }
+
+  private static List<Arg> argsSortedForDisplay(List<Type> types)
+  {
+    List<Arg> argsToSort;
+    // if no types provided, do all
+    if (types == null || types.size() == 0 || types.contains(Type.ALL))
+    {
+      argsToSort = Arrays
+              .asList(EnumSet.allOf(Arg.class).toArray(new Arg[] {}));
+    }
+    else
+    {
+      argsToSort = new ArrayList<>();
+      for (Type type : types)
+      {
+        if (type == null)
+          continue;
+        Arg.getAllOfType(type).forEachRemaining(a -> argsToSort.add(a));
+      }
+    }
+
+    Collections.sort(argsToSort, new ArgDisplayComparator());
+    return argsToSort;
+  }
+
+  private static final String ARGDESCRIPTIONSEPARATOR = " - ";
+
+  private static final int DESCRIPTIONINDENT = 20;
+
+}
+
+class ArgDisplayComparator implements Comparator<Arg>
+{
+  private int compareArgOpts(Arg a, Arg b, Opt o)
+  {
+    int i = a.hasOption(o) ? (b.hasOption(o) ? 0 : -1)
+            : (b.hasOption(o) ? 1 : 0);
+    return i;
+  }
+
+  private int compareForDisplay(Arg a, Arg b)
+  {
+    if (b == null)
+      return -1;
+    // first compare types (in enum order)
+    int i = a.getType().compareTo(b.getType());
+    if (i != 0)
+      return i;
+    // do Opt.LAST next (oddly). Reversed args important!
+    i = compareArgOpts(b, a, Opt.LAST);
+    if (i != 0)
+      return i;
+    // priority order
+    Opt[] optOrder = { Opt.HELP, Opt.FIRST, Opt.PRIMARY, Opt.STRING,
+        Opt.BOOLEAN };
+    for (Opt o : optOrder)
+    {
+      i = compareArgOpts(a, b, o);
+      if (i != 0)
+        return i;
+    }
+    // finally order of appearance in enum declarations
+    return a.compareTo(b);
+  }
+
+  @Override
+  public int compare(Arg a, Arg b)
+  {
+    return compareForDisplay(a, b);
+  }
+}
\ No newline at end of file
diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java
new file mode 100644 (file)
index 0000000..3862375
--- /dev/null
@@ -0,0 +1,1344 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.bin.argparser;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import jalview.bin.Cache;
+import jalview.bin.Console;
+import jalview.bin.Jalview;
+import jalview.bin.argparser.Arg.Opt;
+import jalview.bin.argparser.Arg.Type;
+import jalview.util.FileUtils;
+import jalview.util.HttpUtils;
+
+public class ArgParser
+{
+  protected static final String SINGLEDASH = "-";
+
+  protected static final String DOUBLEDASH = "--";
+
+  public static final char EQUALS = '=';
+
+  public static final String STDOUTFILENAME = "-";
+
+  protected static final String NEGATESTRING = "no";
+
+  /**
+   * the default linked id prefix used for no id (ie when not even square braces
+   * are provided)
+   */
+  protected static final String DEFAULTLINKEDIDPREFIX = "JALVIEW:";
+
+  /**
+   * the linkedId string used to match all linkedIds seen so far
+   */
+  protected static final String MATCHALLLINKEDIDS = "*";
+
+  /**
+   * the linkedId string used to match all of the last --open'ed linkedIds
+   */
+  protected static final String MATCHOPENEDLINKEDIDS = "open*";
+
+  /**
+   * the counter added to the default linked id prefix
+   */
+  private int defaultLinkedIdCounter = 0;
+
+  /**
+   * the substitution string used to use the defaultLinkedIdCounter
+   */
+  private static final String DEFAULTLINKEDIDCOUNTER = "{}";
+
+  /**
+   * the linked id prefix used for --open files. NOW the same as DEFAULT
+   */
+  protected static final String OPENLINKEDIDPREFIX = DEFAULTLINKEDIDPREFIX;
+
+  /**
+   * the counter used for {n} substitutions
+   */
+  private int linkedIdAutoCounter = 0;
+
+  /**
+   * the linked id substitution string used to increment the idCounter (and use
+   * the incremented value)
+   */
+  private static final String INCREMENTLINKEDIDAUTOCOUNTER = "{++n}";
+
+  /**
+   * the linked id substitution string used to use the idCounter
+   */
+  private static final String LINKEDIDAUTOCOUNTER = "{n}";
+
+  /**
+   * the linked id substitution string used to use the filename extension of
+   * --append or --open
+   */
+  private static final String LINKEDIDEXTENSION = "{extension}";
+
+  /**
+   * the linked id substitution string used to use the base filename of --append
+   */
+  /** or --open */
+  private static final String LINKEDIDBASENAME = "{basename}";
+
+  /**
+   * the linked id substitution string used to use the dir path of --append or
+   * --open
+   */
+  private static final String LINKEDIDDIRNAME = "{dirname}";
+
+  /**
+   * the current argfile
+   */
+  private String argFile = null;
+
+  /**
+   * the linked id substitution string used to use the dir path of the latest
+   */
+  /** --argfile name */
+  private static final String ARGFILEBASENAME = "{argfilebasename}";
+
+  /**
+   * the linked id substitution string used to use the dir path of the latest
+   * --argfile name
+   */
+  private static final String ARGFILEDIRNAME = "{argfiledirname}";
+
+  /**
+   * flag to say whether {n} subtitutions in output filenames should be made.
+   * Turn on and off with --substitutions and --nosubstitutions Start with it on
+   */
+  private boolean substitutions = true;
+
+  /**
+   * flag to say whether the default linkedId is the current default linked id
+   *
+   * or ALL linkedIds
+   */
+  private boolean allLinkedIds = false;
+
+  /**
+   * flag to say whether the default linkedId is the current default linked id
+   * or OPENED linkedIds
+   */
+  private boolean openedLinkedIds = false;
+
+  /**
+   * flag to say whether the structure arguments should be applied to all
+   * structures with this linked id
+   */
+  private boolean allStructures = false;
+
+  protected static final Map<String, Arg> argMap;
+
+  protected Map<String, ArgValuesMap> linkedArgs = new HashMap<>();
+
+  protected List<String> linkedOrder = new ArrayList<>();
+
+  protected List<String> storedLinkedIds = new ArrayList<>();
+
+  protected List<Arg> argList = new ArrayList<>();
+
+  private static final char ARGFILECOMMENT = '#';
+
+  private int argIndex = 0;
+
+  private BootstrapArgs bootstrapArgs = null;
+
+  static
+  {
+    argMap = new HashMap<>();
+    for (Arg a : EnumSet.allOf(Arg.class))
+    {
+      for (String argName : a.getNames())
+      {
+        if (argMap.containsKey(argName))
+        {
+          Console.warn("Trying to add argument name multiple times: '"
+                  + argName + "'");
+          if (argMap.get(argName) != a)
+          {
+            Console.error(
+                    "Trying to add argument name multiple times for different Args: '"
+                            + argMap.get(argName).getName() + ":" + argName
+                            + "' and '" + a.getName() + ":" + argName
+                            + "'");
+          }
+          continue;
+        }
+        argMap.put(argName, a);
+      }
+    }
+  }
+
+  public ArgParser(String[] args)
+  {
+    this(args, false, null);
+  }
+
+  public ArgParser(String[] args, boolean initsubstitutions,
+          BootstrapArgs bsa)
+  {
+    /*
+     *  Make a mutable new ArrayList so that shell globbing parser works.
+     * (When shell file globbing is used, there are a sequence of non-Arg
+     * arguments (which are the expanded globbed filenames) that need to be
+     * consumed by the --append/--argfile/etc Arg which is most easily done
+     * by removing these filenames from the list one at a time. This can't be
+     * done with an ArrayList made with only Arrays.asList(String[] args) as
+     * that is not mutable. )
+     */
+    this(new ArrayList<>(Arrays.asList(args)), initsubstitutions, false,
+            bsa);
+  }
+
+  public ArgParser(List<String> args, boolean initsubstitutions)
+  {
+    this(args, initsubstitutions, false, null);
+  }
+
+  public ArgParser(List<String> args, boolean initsubstitutions,
+          boolean allowPrivate, BootstrapArgs bsa)
+  {
+    // do nothing if there are no "--" args and (some "-" args || >0 arg is
+    // "open")
+    boolean d = false;
+    boolean dd = false;
+    for (String arg : args)
+    {
+      if (arg.startsWith(DOUBLEDASH))
+      {
+        dd = true;
+        break;
+      }
+      else if (arg.startsWith("-") || arg.equals("open"))
+      {
+        d = true;
+      }
+    }
+    if (d && !dd)
+    {
+      // leave it to the old style -- parse an empty list
+      parse(new ArrayList<String>(), false, false);
+      return;
+    }
+    if (bsa != null)
+      this.bootstrapArgs = bsa;
+    else
+      this.bootstrapArgs = BootstrapArgs.getBootstrapArgs(args);
+    parse(args, initsubstitutions, allowPrivate);
+  }
+
+  private void parse(List<String> args, boolean initsubstitutions,
+          boolean allowPrivate)
+  {
+    this.substitutions = initsubstitutions;
+
+    /*
+     *  If the first argument does not start with "--" or "-" or is not "open",
+     *  and is a filename that exists or a URL, it is probably a file/list of
+     *  files to open so we insert an Arg.OPEN argument before it. This will
+     *  mean the list of files at the start of the arguments are all opened
+     *  separately.
+     */
+    if (args.size() > 0)
+    {
+      String arg0 = args.get(0);
+      if (arg0 != null
+              && (!arg0.startsWith(DOUBLEDASH) && !arg0.startsWith("-")
+                      && !arg0.equals("open") && (new File(arg0).exists()
+                              || HttpUtils.startsWithHttpOrHttps(arg0))))
+      {
+        // insert "--open" at the start
+        args.add(0, Arg.OPEN.argString());
+      }
+    }
+
+    for (int i = 0; i < args.size(); i++)
+    {
+      String arg = args.get(i);
+
+      // look for double-dash, e.g. --arg
+      if (arg.startsWith(DOUBLEDASH))
+      {
+        String argName = null;
+        String val = null;
+        List<String> globVals = null; // for Opt.GLOB only
+        SubVals globSubVals = null; // also for use by Opt.GLOB only
+        String linkedId = null;
+        Type type = null;
+
+        // look for equals e.g. --arg=value
+        int equalPos = arg.indexOf(EQUALS);
+        if (equalPos > -1)
+        {
+          argName = arg.substring(DOUBLEDASH.length(), equalPos);
+          val = arg.substring(equalPos + 1);
+        }
+        else
+        {
+          argName = arg.substring(DOUBLEDASH.length());
+        }
+
+        // look for linked ID e.g. --arg[linkedID]
+        int idOpen = argName.indexOf('[');
+        int idClose = argName.indexOf(']');
+        if (idOpen > -1 && idClose == argName.length() - 1)
+        {
+          linkedId = argName.substring(idOpen + 1, idClose);
+          argName = argName.substring(0, idOpen);
+        }
+
+        // look for type modification e.g. --help-opening
+        int dashPos = argName.indexOf(SINGLEDASH);
+        if (dashPos > -1)
+        {
+          String potentialArgName = argName.substring(0, dashPos);
+          Arg potentialArg = argMap.get(potentialArgName);
+          if (potentialArg != null && potentialArg.hasOption(Opt.HASTYPE))
+          {
+            String typeName = argName.substring(dashPos + 1);
+            try
+            {
+              type = Type.valueOf(typeName);
+            } catch (IllegalArgumentException e)
+            {
+              type = Type.INVALID;
+            }
+            argName = argName.substring(0, dashPos);
+          }
+        }
+
+        Arg a = argMap.get(argName);
+        // check for boolean prepended by "no" e.g. --nowrap
+        boolean negated = false;
+        if (a == null)
+        {
+          if (argName.startsWith(NEGATESTRING) && argMap
+                  .containsKey(argName.substring(NEGATESTRING.length())))
+          {
+            argName = argName.substring(NEGATESTRING.length());
+            a = argMap.get(argName);
+            negated = true;
+          }
+          else
+          {
+            // after all other args, look for Opt.PREFIXKEV args if still not
+            // found
+            for (Arg potentialArg : EnumSet.allOf(Arg.class))
+            {
+              if (potentialArg.hasOption(Opt.PREFIXKEV) && argName != null
+                      && argName.startsWith(potentialArg.getName())
+                      && equalPos > -1)
+              {
+                val = argName.substring(potentialArg.getName().length())
+                        + EQUALS + val;
+                argName = argName.substring(0,
+                        potentialArg.getName().length());
+                a = potentialArg;
+                break;
+              }
+            }
+          }
+        }
+
+        // check for config errors
+        if (a == null)
+        {
+          // arg not found
+          Console.error("Argument '" + arg + "' not recognised.  Exiting.");
+          Jalview.exit("Invalid argument used." + System.lineSeparator()
+                  + "Use" + System.lineSeparator() + "jalview "
+                  + Arg.HELP.argString() + System.lineSeparator()
+                  + "for a usage statement.", 13);
+          continue;
+        }
+        if (a.hasOption(Opt.PRIVATE) && !allowPrivate)
+        {
+          Console.error(
+                  "Argument '" + a.argString() + "' is private. Ignoring.");
+          continue;
+        }
+        if (!a.hasOption(Opt.BOOLEAN) && negated)
+        {
+          // used "no" with a non-boolean option
+          Console.error("Argument '" + DOUBLEDASH + NEGATESTRING + argName
+                  + "' not a boolean option. Ignoring.");
+          continue;
+        }
+        if (!a.hasOption(Opt.STRING) && equalPos > -1)
+        {
+          // set --argname=value when arg does not accept values
+          Console.error("Argument '" + a.argString()
+                  + "' does not expect a value (given as '" + arg
+                  + "').  Ignoring.");
+          continue;
+        }
+        if (!a.hasOption(Opt.LINKED) && linkedId != null)
+        {
+          // set --argname[linkedId] when arg does not use linkedIds
+          Console.error("Argument '" + a.argString()
+                  + "' does not expect a linked id (given as '" + arg
+                  + "'). Ignoring.");
+          continue;
+        }
+
+        // String value(s)
+        if (a.hasOption(Opt.STRING))
+        {
+          if (equalPos >= 0)
+          {
+            if (a.hasOption(Opt.GLOB))
+            {
+              // strip off and save the SubVals to be added individually later
+              globSubVals = new SubVals(val);
+              // make substitutions before looking for files
+              String fileGlob = makeSubstitutions(globSubVals.getContent(),
+                      linkedId);
+              globVals = FileUtils.getFilenamesFromGlob(fileGlob);
+            }
+            else
+            {
+              // val is already set -- will be saved in the ArgValue later in
+              // the normal way
+            }
+          }
+          else
+          {
+            // There is no "=" so value is next arg or args (possibly shell
+            // glob-expanded)
+            if (i + 1 >= args.size())
+            {
+              // no value to take for arg, which wants a value
+              Console.error("Argument '" + a.getName()
+                      + "' requires a value, none given. Ignoring.");
+              continue;
+            }
+            // deal with bash globs here (--arg val* is expanded before reaching
+            // the JVM). Note that SubVals cannot be used in this case.
+            // If using the --arg=val then the glob is preserved and Java globs
+            // will be used later. SubVals can be used.
+            if (a.hasOption(Opt.GLOB))
+            {
+              // if this is the first argument with a file list at the start of
+              // the args we add filenames from index i instead of i+1
+              globVals = getShellGlobbedFilenameValues(a, args, i + 1);
+            }
+            else
+            {
+              val = args.get(i + 1);
+            }
+          }
+        }
+
+        // make NOACTION adjustments
+        // default and auto counter increments
+        if (a == Arg.NPP)
+        {
+          linkedIdAutoCounter++;
+        }
+        else if (a == Arg.SUBSTITUTIONS)
+        {
+          substitutions = !negated;
+        }
+        else if (a == Arg.SETARGFILE)
+        {
+          argFile = val;
+        }
+        else if (a == Arg.UNSETARGFILE)
+        {
+          argFile = null;
+        }
+        else if (a == Arg.ALL)
+        {
+          allLinkedIds = !negated;
+          openedLinkedIds = false;
+        }
+        else if (a == Arg.OPENED)
+        {
+          openedLinkedIds = !negated;
+          allLinkedIds = false;
+        }
+        else if (a == Arg.ALLSTRUCTURES)
+        {
+          allStructures = !negated;
+        }
+
+        if (a.hasOption(Opt.STORED))
+        {
+          // reset the lastOpenedLinkedIds list
+          this.storedLinkedIds = new ArrayList<>();
+        }
+
+        // this is probably only Arg.NEW and Arg.OPEN
+        if (a.hasOption(Opt.INCREMENTDEFAULTCOUNTER))
+        {
+          // use the next default prefixed OPENLINKEDID
+          defaultLinkedId(true);
+        }
+
+        String autoCounterString = null;
+        String defaultLinkedId = defaultLinkedId(false);
+        boolean usingDefaultLinkedId = false;
+        if (a.hasOption(Opt.LINKED))
+        {
+          if (linkedId == null)
+          {
+            if (a.hasOption(Opt.OUTPUTFILE) && a.hasOption(Opt.ALLOWALL)
+                    && val.startsWith(MATCHALLLINKEDIDS))
+            {
+              // --output=*.ext is shorthand for --all --output {basename}.ext
+              // (or --image=*.ext)
+              allLinkedIds = true;
+              openedLinkedIds = false;
+              linkedId = MATCHALLLINKEDIDS;
+              val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME
+                      + val.substring(MATCHALLLINKEDIDS.length());
+            }
+            else if (a.hasOption(Opt.OUTPUTFILE)
+                    && a.hasOption(Opt.ALLOWALL)
+                    && val.startsWith(MATCHOPENEDLINKEDIDS))
+            {
+              // --output=open*.ext is shorthand for --opened --output
+              // {basename}.ext
+              // (or --image=open*.ext)
+              openedLinkedIds = true;
+              allLinkedIds = false;
+              linkedId = MATCHOPENEDLINKEDIDS;
+              val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME
+                      + val.substring(MATCHOPENEDLINKEDIDS.length());
+            }
+            else if (allLinkedIds && a.hasOption(Opt.ALLOWALL))
+            {
+              linkedId = MATCHALLLINKEDIDS;
+            }
+            else if (openedLinkedIds && a.hasOption(Opt.ALLOWALL))
+            {
+              linkedId = MATCHOPENEDLINKEDIDS;
+            }
+            else
+            {
+              // use default linkedId for linked arguments
+              linkedId = defaultLinkedId;
+              usingDefaultLinkedId = true;
+              Console.debug("Changing linkedId to '" + linkedId + "' from "
+                      + arg);
+            }
+          }
+          else
+          {
+            if (linkedId.contains(LINKEDIDAUTOCOUNTER))
+            {
+              // turn {n} to the autoCounter
+              autoCounterString = Integer.toString(linkedIdAutoCounter);
+              linkedId = linkedId.replace(LINKEDIDAUTOCOUNTER,
+                      autoCounterString);
+              Console.debug("Changing linkedId to '" + linkedId + "' from "
+                      + arg);
+            }
+            if (linkedId.contains(INCREMENTLINKEDIDAUTOCOUNTER))
+            {
+              // turn {++n} to the incremented autoCounter
+              autoCounterString = Integer.toString(++linkedIdAutoCounter);
+              linkedId = linkedId.replace(INCREMENTLINKEDIDAUTOCOUNTER,
+                      autoCounterString);
+              Console.debug("Changing linkedId to '" + linkedId + "' from "
+                      + arg);
+            }
+          }
+        }
+
+        // do not continue in this block for NOACTION args
+        if (a.hasOption(Opt.NOACTION))
+          continue;
+
+        ArgValuesMap avm = getOrCreateLinkedArgValuesMap(linkedId);
+
+        // not dealing with both NODUPLICATEVALUES and GLOB
+        if (a.hasOption(Opt.NODUPLICATEVALUES) && avm.hasValue(a, val))
+        {
+          Console.error("Argument '" + a.argString()
+                  + "' cannot contain a duplicate value ('" + val
+                  + "'). Ignoring this and subsequent occurrences.");
+          continue;
+        }
+
+        // check for unique id
+        SubVals subvals = new SubVals(val);
+        boolean addNewSubVals = false;
+        String id = subvals.get(ArgValues.ID);
+        if (id != null && avm.hasId(a, id))
+        {
+          Console.error("Argument '" + a.argString()
+                  + "' has a duplicate id ('" + id + "'). Ignoring.");
+          continue;
+        }
+
+        // set allstructures to all non-primary structure options in this linked
+        // id if --allstructures has been set
+        if (allStructures
+                && (a.getType() == Type.STRUCTURE
+                        || a.getType() == Type.STRUCTUREIMAGE)
+                && !a.hasOption(Opt.PRIMARY))
+        {
+          if (!subvals.has(Arg.ALLSTRUCTURES.getName()))
+          // && !subvals.has("structureid"))
+          {
+            subvals.put(Arg.ALLSTRUCTURES.getName(), "true");
+            addNewSubVals = true;
+          }
+        }
+
+        ArgValues avs = avm.getOrCreateArgValues(a);
+
+        // store appropriate String value(s)
+        if (a.hasOption(Opt.STRING))
+        {
+          if (a.hasOption(Opt.GLOB) && globVals != null
+                  && globVals.size() > 0)
+          {
+            Enumeration<String> gve = Collections.enumeration(globVals);
+            while (gve.hasMoreElements())
+            {
+              String v = gve.nextElement();
+              SubVals vsv = new SubVals(globSubVals, v);
+              addValue(linkedId, type, avs, vsv, v, argIndex++, true);
+              // if we're using defaultLinkedId and the arg increments the
+              // counter:
+              if (gve.hasMoreElements() && usingDefaultLinkedId
+                      && a.hasOption(Opt.INCREMENTDEFAULTCOUNTER))
+              {
+                // increment the default linkedId
+                linkedId = defaultLinkedId(true);
+                // get new avm and avs
+                avm = linkedArgs.get(linkedId);
+                avs = avm.getOrCreateArgValues(a);
+              }
+            }
+          }
+          else
+          {
+            // addValue(linkedId, type, avs, val, argIndex, true);
+            addValue(linkedId, type, avs, addNewSubVals ? subvals : null,
+                    val, argIndex, true);
+          }
+        }
+        else if (a.hasOption(Opt.BOOLEAN))
+        {
+          setBoolean(linkedId, type, avs, !negated, argIndex);
+          setNegated(linkedId, avs, negated);
+        }
+        else if (a.hasOption(Opt.UNARY))
+        {
+          setBoolean(linkedId, type, avs, true, argIndex);
+        }
+
+        // remove the '*' or 'open*' linkedId that should be empty if it was
+        // created
+        if ((MATCHALLLINKEDIDS.equals(linkedId)
+                && linkedArgs.containsKey(linkedId))
+                || (MATCHOPENEDLINKEDIDS.equals(linkedId)
+                        && linkedArgs.containsKey(linkedId)))
+        {
+          linkedArgs.remove(linkedId);
+        }
+      }
+    }
+  }
+
+  private void finaliseStoringArgValue(String linkedId, ArgValues avs)
+  {
+    Arg a = avs.arg();
+    incrementCount(linkedId, avs);
+    argIndex++;
+
+    // store in appropriate place
+    if (a.hasOption(Opt.LINKED))
+    {
+      // store the order of linkedIds
+      if (!linkedOrder.contains(linkedId))
+        linkedOrder.add(linkedId);
+    }
+
+    // store arg in the list of args used
+    if (!argList.contains(a))
+      argList.add(a);
+  }
+
+  private String defaultLinkedId(boolean increment)
+  {
+    String defaultLinkedId = new StringBuilder(DEFAULTLINKEDIDPREFIX)
+            .append(Integer.toString(defaultLinkedIdCounter)).toString();
+    if (increment)
+    {
+      while (linkedArgs.containsKey(defaultLinkedId))
+      {
+        defaultLinkedIdCounter++;
+        defaultLinkedId = new StringBuilder(DEFAULTLINKEDIDPREFIX)
+                .append(Integer.toString(defaultLinkedIdCounter))
+                .toString();
+      }
+    }
+    getOrCreateLinkedArgValuesMap(defaultLinkedId);
+    return defaultLinkedId;
+  }
+
+  public String makeSubstitutions(String val, String linkedId)
+  {
+    if (!this.substitutions || val == null)
+      return val;
+
+    String subvals;
+    String rest;
+    if (val.indexOf('[') == 0 && val.indexOf(']') > 1)
+    {
+      int closeBracket = val.indexOf(']');
+      if (val.length() == closeBracket)
+        return val;
+      subvals = val.substring(0, closeBracket + 1);
+      rest = val.substring(closeBracket + 1);
+    }
+    else
+    {
+      subvals = "";
+      rest = val;
+    }
+    if (rest.contains(LINKEDIDAUTOCOUNTER))
+      rest = rest.replace(LINKEDIDAUTOCOUNTER,
+              String.valueOf(linkedIdAutoCounter));
+    if (rest.contains(INCREMENTLINKEDIDAUTOCOUNTER))
+      rest = rest.replace(INCREMENTLINKEDIDAUTOCOUNTER,
+              String.valueOf(++linkedIdAutoCounter));
+    if (rest.contains(DEFAULTLINKEDIDCOUNTER))
+      rest = rest.replace(DEFAULTLINKEDIDCOUNTER,
+              String.valueOf(defaultLinkedIdCounter));
+    ArgValuesMap avm = linkedArgs.get(linkedId);
+    if (avm != null)
+    {
+      if (rest.contains(LINKEDIDBASENAME))
+      {
+        rest = rest.replace(LINKEDIDBASENAME, avm.getBasename());
+      }
+      if (rest.contains(LINKEDIDEXTENSION))
+      {
+        rest = rest.replace(LINKEDIDEXTENSION, avm.getExtension());
+      }
+      if (rest.contains(LINKEDIDDIRNAME))
+      {
+        rest = rest.replace(LINKEDIDDIRNAME, avm.getDirname());
+      }
+    }
+    if (argFile != null)
+    {
+      if (rest.contains(ARGFILEBASENAME))
+      {
+        rest = rest.replace(ARGFILEBASENAME,
+                FileUtils.getBasename(new File(argFile)));
+      }
+      if (rest.contains(ARGFILEDIRNAME))
+      {
+        rest = rest.replace(ARGFILEDIRNAME,
+                FileUtils.getDirname(new File(argFile)));
+      }
+    }
+
+    return new StringBuilder(subvals).append(rest).toString();
+  }
+
+  /*
+   * A helper method to take a list of String args where we're expecting
+   * {"--previousargs", "--arg", "file1", "file2", "file3", "--otheroptionsornot"}
+   * and the index of the globbed arg, here 1. It returns a List<String> {"file1",
+   * "file2", "file3"} *and remove these from the original list object* so that
+   * processing can continue from where it has left off, e.g. args has become
+   * {"--previousargs", "--arg", "--otheroptionsornot"} so the next increment
+   * carries on from the next --arg if available.
+   */
+  protected static List<String> getShellGlobbedFilenameValues(Arg a,
+          List<String> args, int i)
+  {
+    List<String> vals = new ArrayList<>();
+    while (i < args.size() && !args.get(i).startsWith(DOUBLEDASH))
+    {
+      vals.add(FileUtils.substituteHomeDir(args.remove(i)));
+      if (!a.hasOption(Opt.GLOB))
+        break;
+    }
+    return vals;
+  }
+
+  public BootstrapArgs getBootstrapArgs()
+  {
+    return bootstrapArgs;
+  }
+
+  public boolean isSet(Arg a)
+  {
+    return a.hasOption(Opt.LINKED) ? isSetAtAll(a) : isSet(null, a);
+  }
+
+  public boolean isSetAtAll(Arg a)
+  {
+    for (String linkedId : linkedOrder)
+    {
+      if (isSet(linkedId, a))
+        return true;
+    }
+    return false;
+  }
+
+  public boolean isSet(String linkedId, Arg a)
+  {
+    ArgValuesMap avm = linkedArgs.get(linkedId);
+    return avm == null ? false : avm.containsArg(a);
+  }
+
+  public boolean getBoolean(Arg a)
+  {
+    if (!a.hasOption(Opt.BOOLEAN) && !a.hasOption(Opt.UNARY))
+    {
+      Console.warn("Getting boolean from non boolean Arg '" + a.getName()
+              + "'.");
+    }
+    return a.hasOption(Opt.LINKED) ? getBool("", a) : getBool(null, a);
+  }
+
+  public boolean getBool(String linkedId, Arg a)
+  {
+    ArgValuesMap avm = linkedArgs.get(linkedId);
+    if (avm == null)
+      return a.getDefaultBoolValue();
+    ArgValues avs = avm.getArgValues(a);
+    return avs == null ? a.getDefaultBoolValue() : avs.getBoolean();
+  }
+
+  public List<String> getLinkedIds()
+  {
+    return linkedOrder;
+  }
+
+  public ArgValuesMap getLinkedArgs(String id)
+  {
+    return linkedArgs.get(id);
+  }
+
+  @Override
+  public String toString()
+  {
+    StringBuilder sb = new StringBuilder();
+    sb.append("UNLINKED\n");
+    sb.append(argValuesMapToString(linkedArgs.get(null)));
+    if (getLinkedIds() != null)
+    {
+      sb.append("LINKED\n");
+      for (String id : getLinkedIds())
+      {
+        // already listed these as UNLINKED args
+        if (id == null)
+          continue;
+
+        ArgValuesMap avm = getLinkedArgs(id);
+        sb.append("ID: '").append(id).append("'\n");
+        sb.append(argValuesMapToString(avm));
+      }
+    }
+    return sb.toString();
+  }
+
+  private static String argValuesMapToString(ArgValuesMap avm)
+  {
+    if (avm == null)
+      return null;
+    StringBuilder sb = new StringBuilder();
+    for (Arg a : avm.getArgKeys())
+    {
+      ArgValues v = avm.getArgValues(a);
+      sb.append(v.toString());
+      sb.append("\n");
+    }
+    return sb.toString();
+  }
+
+  public static ArgParser parseArgFiles(List<String> argFilenameGlobs,
+          boolean initsubstitutions, BootstrapArgs bsa)
+  {
+    List<File> argFiles = new ArrayList<>();
+
+    for (String pattern : argFilenameGlobs)
+    {
+      // I don't think we want to dedup files, making life easier
+      argFiles.addAll(FileUtils.getFilesFromGlob(pattern));
+    }
+
+    return parseArgFileList(argFiles, initsubstitutions, bsa);
+  }
+
+  public static ArgParser parseArgFileList(List<File> argFiles,
+          boolean initsubstitutions, BootstrapArgs bsa)
+  {
+    List<String> argsList = new ArrayList<>();
+    for (File argFile : argFiles)
+    {
+      if (!argFile.exists())
+      {
+        String message = Arg.ARGFILE.argString() + EQUALS + "\""
+                + argFile.getPath() + "\": File does not exist.";
+        Jalview.exit(message, 2);
+      }
+      try
+      {
+        String setargfile = new StringBuilder(Arg.SETARGFILE.argString())
+                .append(EQUALS).append(argFile.getCanonicalPath())
+                .toString();
+        argsList.add(setargfile);
+        argsList.addAll(readArgFile(argFile));
+        argsList.add(Arg.UNSETARGFILE.argString());
+      } catch (IOException e)
+      {
+        String message = Arg.ARGFILE.argString() + "=\"" + argFile.getPath()
+                + "\": File could not be read.";
+        Jalview.exit(message, 3);
+      }
+    }
+    // Third param "true" uses Opt.PRIVATE args --setargile=argfile and
+    // --unsetargfile
+    return new ArgParser(argsList, initsubstitutions, true, bsa);
+  }
+
+  protected static List<String> readArgFile(File argFile)
+  {
+    List<String> args = new ArrayList<>();
+    if (argFile != null && argFile.exists())
+    {
+      try
+      {
+        for (String line : Files.readAllLines(Paths.get(argFile.getPath())))
+        {
+          if (line != null && line.length() > 0
+                  && line.charAt(0) != ARGFILECOMMENT)
+            args.add(line);
+        }
+      } catch (IOException e)
+      {
+        String message = Arg.ARGFILE.argString() + "=\"" + argFile.getPath()
+                + "\": File could not be read.";
+        Console.debug(message, e);
+        Jalview.exit(message, 3);
+      }
+    }
+    return args;
+  }
+
+  public static enum Position
+  {
+    FIRST, BEFORE, AFTER
+  }
+
+  /**
+   * get from following Arg of type a or subval of same name (lowercase)
+   */
+  public static String getValueFromSubValOrArg(ArgValuesMap avm,
+          ArgValue av, Arg a, SubVals sv)
+  {
+    return getFromSubValArgOrPref(avm, av, a, sv, null, null, null);
+  }
+
+  /**
+   * get from following Arg of type a or subval key or preference pref or
+   * default def
+   */
+  public static String getFromSubValArgOrPref(ArgValuesMap avm, ArgValue av,
+          Arg a, SubVals sv, String key, String pref, String def)
+  {
+    return getFromSubValArgOrPref(avm, a, Position.AFTER, av, sv, key, pref,
+            def);
+  }
+
+  /**
+   * get from following(AFTER), first occurence of (FIRST) or previous (BEFORE)
+   * Arg of type a or subval key or preference pref or default def
+   */
+  public static String getFromSubValArgOrPref(ArgValuesMap avm, Arg a,
+          Position pos, ArgValue av, SubVals sv, String key, String pref,
+          String def)
+  {
+    return getFromSubValArgOrPrefWithSubstitutions(null, avm, a, pos, av,
+            sv, key, pref, def);
+  }
+
+  public static String getFromSubValArgOrPrefWithSubstitutions(ArgParser ap,
+          ArgValuesMap avm, Arg a, Position pos, ArgValue av, SubVals sv,
+          String key, String pref, String def)
+  {
+    if (key == null)
+      key = a.getName();
+    String value = null;
+    if (sv != null && sv.has(key) && sv.get(key) != null)
+    {
+      value = ap == null ? sv.get(key)
+              : sv.getWithSubstitutions(ap, avm.getLinkedId(), key);
+    }
+    else if (avm != null && avm.containsArg(a))
+    {
+      if (pos == Position.FIRST && avm.getValue(a) != null)
+        value = avm.getValue(a);
+      else if (pos == Position.BEFORE
+              && avm.getClosestPreviousArgValueOfArg(av, a) != null)
+        value = avm.getClosestPreviousArgValueOfArg(av, a).getValue();
+      else if (pos == Position.AFTER
+              && avm.getClosestNextArgValueOfArg(av, a) != null)
+        value = avm.getClosestNextArgValueOfArg(av, a).getValue();
+
+      // look for allstructures subval for Type.STRUCTURE*
+      Arg arg = av.getArg();
+      if (value == null && arg.hasOption(Opt.PRIMARY)
+              && arg.getType() == Type.STRUCTURE
+              && !a.hasOption(Opt.PRIMARY) && (a.getType() == Type.STRUCTURE
+                      || a.getType() == Type.STRUCTUREIMAGE))
+      {
+        ArgValue av2 = avm.getArgValueOfArgWithSubValKey(a,
+                Arg.ALLSTRUCTURES.getName());
+        if (av2 != null)
+        {
+          value = av2.getValue();
+        }
+      }
+    }
+    if (value == null)
+    {
+      value = pref != null ? Cache.getDefault(pref, def) : def;
+    }
+    return value;
+  }
+
+  public static boolean getBoolFromSubValOrArg(ArgValuesMap avm, Arg a,
+          SubVals sv)
+  {
+    return getFromSubValArgOrPref(avm, a, sv, null, null, false);
+  }
+
+  public static boolean getFromSubValArgOrPref(ArgValuesMap avm, Arg a,
+          SubVals sv, String key, String pref, boolean def)
+  {
+    return getFromSubValArgOrPref(avm, a, sv, key, pref, def, false);
+  }
+
+  public static boolean getFromSubValArgOrPref(ArgValuesMap avm, Arg a,
+          SubVals sv, String key, String pref, boolean def,
+          boolean invertPref)
+  {
+    if ((key == null && a == null) || (sv == null && a == null))
+      return false;
+
+    boolean usingArgKey = false;
+    if (key == null)
+    {
+      key = a.getName();
+      usingArgKey = true;
+    }
+
+    String nokey = ArgParser.NEGATESTRING + key;
+
+    // look for key or nokey in subvals first (if using Arg check options)
+    if (sv != null)
+    {
+      // check for true boolean
+      if (sv.has(key) && sv.get(key) != null)
+      {
+        if (usingArgKey)
+        {
+          if (!(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY)))
+          {
+            Console.debug(
+                    "Looking for boolean in subval from non-boolean/non-unary Arg "
+                            + a.getName());
+            return false;
+          }
+        }
+        return sv.get(key).toLowerCase(Locale.ROOT).equals("true");
+      }
+
+      // check for negative boolean (subval "no..." will be "true")
+      if (sv.has(nokey) && sv.get(nokey) != null)
+      {
+        if (usingArgKey)
+        {
+          if (!(a.hasOption(Opt.BOOLEAN)))
+          {
+            Console.debug(
+                    "Looking for negative boolean in subval from non-boolean Arg "
+                            + a.getName());
+            return false;
+          }
+        }
+        return !sv.get(nokey).toLowerCase(Locale.ROOT).equals("true");
+      }
+    }
+
+    // check argvalues
+    if (avm != null && avm.containsArg(a))
+      return avm.getBoolean(a);
+
+    // return preference or default
+    boolean prefVal = pref != null ? Cache.getDefault(pref, def) : false;
+    return pref != null ? (invertPref ? !prefVal : prefVal) : def;
+  }
+
+  // the following methods look for the "*" linkedId and add the argvalue to all
+  // linkedId ArgValues if it does.
+  /**
+   * This version inserts the subvals sv into all created values
+   */
+  private void addValue(String linkedId, Type type, ArgValues avs,
+          SubVals sv, String v, int argIndex, boolean doSubs)
+  {
+    this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, sv, v, false,
+            argIndex, doSubs);
+  }
+
+  private void addValue(String linkedId, Type type, ArgValues avs, String v,
+          int argIndex, boolean doSubs)
+  {
+    this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, null, v, false,
+            argIndex, doSubs);
+  }
+
+  private void setBoolean(String linkedId, Type type, ArgValues avs,
+          boolean b, int argIndex)
+  {
+    this.argValueOperation(Op.SETBOOLEAN, linkedId, type, avs, null, null,
+            b, argIndex, false);
+  }
+
+  private void setNegated(String linkedId, ArgValues avs, boolean b)
+  {
+    this.argValueOperation(Op.SETNEGATED, linkedId, null, avs, null, null,
+            b, 0, false);
+  }
+
+  private void incrementCount(String linkedId, ArgValues avs)
+  {
+    this.argValueOperation(Op.INCREMENTCOUNT, linkedId, null, avs, null,
+            null, false, 0, false);
+  }
+
+  private enum Op
+  {
+    ADDVALUE, SETBOOLEAN, SETNEGATED, INCREMENTCOUNT
+  }
+
+  private void argValueOperation(Op op, String linkedId, Type type,
+          ArgValues avs, SubVals sv, String v, boolean b, int argIndex,
+          boolean doSubs)
+  {
+    // default to merge subvals if subvals are provided
+    argValueOperation(op, linkedId, type, avs, sv, true, v, b, argIndex,
+            doSubs);
+  }
+
+  /**
+   * The following operations look for the "*" and "open*" linkedIds and add the
+   * argvalue to all appropriate linkedId ArgValues if it does. If subvals are
+   * supplied, they are inserted into all new set values.
+   * 
+   * @param op
+   *          The ArgParser.Op operation
+   * @param linkedId
+   *          The String linkedId from the ArgValuesMap
+   * @param type
+   *          The Arg.Type to attach to this ArgValue
+   * @param avs
+   *          The ArgValues for this linkedId
+   * @param sv
+   *          Use these SubVals on the ArgValue
+   * @param merge
+   *          Merge the SubVals with any existing on the value. False will
+   *          replace unless sv is null
+   * @param v
+   *          The value of the ArgValue (may contain subvals).
+   * @param b
+   *          The boolean value of the ArgValue.
+   * @param argIndex
+   *          The argIndex for the ArgValue.
+   * @param doSubs
+   *          Whether to perform substitutions on the subvals and value.
+   */
+  private void argValueOperation(Op op, String linkedId, Type type,
+          ArgValues avs, SubVals sv, boolean merge, String v, boolean b,
+          int argIndex, boolean doSubs)
+  {
+    Arg a = avs.arg();
+
+    List<String> wildcardLinkedIds = null;
+    if (a.hasOption(Opt.ALLOWALL))
+    {
+      switch (linkedId)
+      {
+      case MATCHALLLINKEDIDS:
+        wildcardLinkedIds = getLinkedIds();
+        break;
+      case MATCHOPENEDLINKEDIDS:
+        wildcardLinkedIds = this.storedLinkedIds;
+        break;
+      }
+    }
+
+    // if we're not a wildcard linkedId and the arg is marked to be stored, add
+    // to storedLinkedIds
+    if (linkedId != null && wildcardLinkedIds == null
+            && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
+    {
+      storedLinkedIds.add(linkedId);
+    }
+
+    // if we are a wildcard linkedId, apply the arg and value to all appropriate
+    // linkedIds
+    if (wildcardLinkedIds != null)
+    {
+      for (String id : wildcardLinkedIds)
+      {
+        // skip incorrectly stored wildcard ids!
+        if (id == null || MATCHALLLINKEDIDS.equals(id)
+                || MATCHOPENEDLINKEDIDS.equals(id))
+          continue;
+        ArgValuesMap avm = linkedArgs.get(id);
+        // don't set an output if there isn't an input
+        if (a.hasOption(Opt.REQUIREINPUT)
+                && !avm.hasArgWithOption(Opt.INPUT))
+          continue;
+
+        ArgValues tavs = avm.getOrCreateArgValues(a);
+        switch (op)
+        {
+
+        case ADDVALUE:
+          String val = v;
+          if (sv != null)
+          {
+            if (doSubs)
+            {
+              sv = new SubVals(sv, val, merge);
+              val = makeSubstitutions(sv.getContent(), id);
+            }
+            tavs.addValue(sv, type, val, argIndex, true);
+          }
+          else
+          {
+            if (doSubs)
+            {
+              val = makeSubstitutions(v, id);
+            }
+            tavs.addValue(type, val, argIndex, true);
+          }
+          finaliseStoringArgValue(id, tavs);
+          break;
+
+        case SETBOOLEAN:
+          tavs.setBoolean(type, b, argIndex, true);
+          finaliseStoringArgValue(id, tavs);
+          break;
+
+        case SETNEGATED:
+          tavs.setNegated(b, true);
+          break;
+
+        case INCREMENTCOUNT:
+          tavs.incrementCount();
+          break;
+
+        default:
+          break;
+
+        }
+
+      }
+    }
+    else // no wildcard linkedId -- do it simpler
+    {
+      switch (op)
+      {
+      case ADDVALUE:
+        String val = v;
+        if (sv != null)
+        {
+          if (doSubs)
+          {
+            val = makeSubstitutions(v, linkedId);
+            sv = new SubVals(sv, val);
+          }
+          avs.addValue(sv, type, val, argIndex, false);
+        }
+        else
+        {
+          if (doSubs)
+          {
+            val = makeSubstitutions(v, linkedId);
+          }
+          avs.addValue(type, val, argIndex, false);
+        }
+        finaliseStoringArgValue(linkedId, avs);
+        break;
+
+      case SETBOOLEAN:
+        avs.setBoolean(type, b, argIndex, false);
+        finaliseStoringArgValue(linkedId, avs);
+        break;
+
+      case SETNEGATED:
+        avs.setNegated(b, false);
+        break;
+
+      case INCREMENTCOUNT:
+        avs.incrementCount();
+        break;
+
+      default:
+        break;
+      }
+    }
+  }
+
+  private ArgValuesMap getOrCreateLinkedArgValuesMap(String linkedId)
+  {
+    if (linkedArgs.containsKey(linkedId)
+            && linkedArgs.get(linkedId) != null)
+      return linkedArgs.get(linkedId);
+
+    linkedArgs.put(linkedId, new ArgValuesMap(linkedId));
+    return linkedArgs.get(linkedId);
+  }
+
+}
\ No newline at end of file
diff --git a/src/jalview/bin/argparser/ArgValue.java b/src/jalview/bin/argparser/ArgValue.java
new file mode 100644 (file)
index 0000000..3467f61
--- /dev/null
@@ -0,0 +1,107 @@
+package jalview.bin.argparser;
+
+import jalview.bin.argparser.Arg.Opt;
+import jalview.bin.argparser.Arg.Type;
+
+/**
+ * A helper class to keep an index of argument position with argument values
+ */
+public class ArgValue implements Comparable<ArgValue>
+{
+  private Arg arg;
+
+  private int argIndex;
+
+  private String value;
+
+  /*
+   * Type type is only really used by --help-type
+   */
+  private Type type = null;
+
+  /*
+   * This id is set by a subVal id= to identify the product of this ArgValue
+   * later. Set but not currently used.
+   */
+  private String id;
+
+  private SubVals subVals;
+
+  protected ArgValue(Arg a, SubVals sv, Type type, String content,
+          int argIndex)
+  {
+    this.arg = a;
+    this.value = content;
+    this.argIndex = argIndex;
+    this.subVals = sv == null ? new SubVals("") : sv;
+    this.setType(type);
+  }
+
+  protected ArgValue(Arg a, Type type, String value, int argIndex)
+  {
+    this.arg = a;
+    this.argIndex = argIndex;
+    this.subVals = new SubVals(value);
+    this.value = getSubVals().getContent();
+    this.setType(type);
+  }
+
+  protected void setType(Type t)
+  {
+    if (this.getArg().hasOption(Opt.HASTYPE))
+      this.type = t;
+  }
+
+  public Type getType()
+  {
+    return type;
+  }
+
+  public Arg getArg()
+  {
+    return arg;
+  }
+
+  public String getValue()
+  {
+    return value;
+  }
+
+  public int getArgIndex()
+  {
+    return argIndex;
+  }
+
+  protected void setId(String i)
+  {
+    id = i;
+  }
+
+  public String getId()
+  {
+    return id;
+  }
+
+  public SubVals getSubVals()
+  {
+    return subVals;
+  }
+
+  public String getSubVal(String key)
+  {
+    if (subVals == null || !subVals.has(key))
+      return null;
+    return subVals.get(key);
+  }
+
+  protected void putSubVal(String key, String val)
+  {
+    this.subVals.put(key, val);
+  }
+
+  @Override
+  public final int compareTo(ArgValue o)
+  {
+    return this.getArgIndex() - o.getArgIndex();
+  }
+}
\ No newline at end of file
diff --git a/src/jalview/bin/argparser/ArgValues.java b/src/jalview/bin/argparser/ArgValues.java
new file mode 100644 (file)
index 0000000..f25fc9a
--- /dev/null
@@ -0,0 +1,221 @@
+package jalview.bin.argparser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import jalview.bin.Console;
+import jalview.bin.argparser.Arg.Opt;
+import jalview.bin.argparser.Arg.Type;
+
+public class ArgValues
+{
+  public static final String ID = "id";
+
+  private Arg arg;
+
+  private int argCount = 0;
+
+  private boolean boolValue = false;
+
+  private boolean negated = false;
+
+  private boolean setByWildcard = false;
+
+  private int boolIndex = -1;
+
+  private List<Integer> argsIndexes;
+
+  private List<ArgValue> argValueList;
+
+  private Map<String, ArgValue> idMap = new HashMap<>();
+
+  /*
+   * Type type is only really used by --help-type
+   */
+  private Type type = null;
+
+  protected ArgValues(Arg a)
+  {
+    this.arg = a;
+    this.argValueList = new ArrayList<ArgValue>();
+    this.boolValue = arg.getDefaultBoolValue();
+  }
+
+  protected boolean setByWildcard()
+  {
+    return setByWildcard;
+  }
+
+  protected void setSetByWildcard(boolean b)
+  {
+    setByWildcard = b;
+  }
+
+  public Arg arg()
+  {
+    return arg;
+  }
+
+  protected void setType(Type t)
+  {
+    if (this.arg().hasOption(Opt.HASTYPE))
+      this.type = t;
+  }
+
+  public Type getType()
+  {
+    return type;
+  }
+
+  protected int getCount()
+  {
+    return argCount;
+  }
+
+  protected void incrementCount()
+  {
+    argCount++;
+  }
+
+  protected void setNegated(boolean b, boolean beingSetByWildcard)
+  {
+    // don't overwrite a wildcard set boolean with a non-wildcard set boolean
+    if (boolIndex >= 0 && !this.setByWildcard && beingSetByWildcard)
+      return;
+    this.negated = b;
+  }
+
+  protected boolean isNegated()
+  {
+    return this.negated;
+  }
+
+  protected void setBoolean(Type t, boolean b, int i,
+          boolean beingSetByWildcard)
+  {
+    this.setType(t);
+    // don't overwrite a wildcard set boolean with a non-wildcard set boolean
+    if (boolIndex >= 0 && !this.setByWildcard && beingSetByWildcard)
+      return;
+    this.boolValue = b;
+    this.boolIndex = i;
+    this.setSetByWildcard(beingSetByWildcard);
+  }
+
+  protected boolean getBoolean()
+  {
+    return this.boolValue;
+  }
+
+  @Override
+  public String toString()
+  {
+    if (argValueList == null)
+      return null;
+    StringBuilder sb = new StringBuilder();
+    sb.append(arg.toLongString());
+    if (arg.hasOption(Opt.BOOLEAN) || arg.hasOption(Opt.UNARY))
+      sb.append("Boolean: ").append(boolValue).append("; Default: ")
+              .append(arg.getDefaultBoolValue()).append("; Negated: ")
+              .append(negated).append("\n");
+    if (arg.hasOption(Opt.STRING))
+    {
+      sb.append("Values:");
+      sb.append("'")
+              .append(String
+                      .join("',\n  '",
+                              argValueList.stream().map(av -> av.getValue())
+                                      .collect(Collectors.toList())))
+              .append("'");
+      sb.append("\n");
+    }
+    sb.append("Count: ").append(argCount).append("\n");
+    return sb.toString();
+  }
+
+  protected void addValue(Type type, String val, int argIndex,
+          boolean wildcard)
+  {
+    addArgValue(new ArgValue(arg(), type, val, argIndex), wildcard);
+  }
+
+  protected void addValue(SubVals sv, Type type, String content,
+          int argIndex, boolean wildcard)
+  {
+    addArgValue(new ArgValue(arg(), sv, type, content, argIndex), wildcard);
+  }
+
+  protected void addArgValue(ArgValue av, boolean beingSetByWildcard)
+  {
+    // allow a non-wildcard value to overwrite a wildcard set single value
+    boolean overwrite = !arg.hasOption(Opt.MULTI) && setByWildcard
+            && !beingSetByWildcard;
+    if ((!arg.hasOption(Opt.MULTI) && argValueList.size() > 0)
+            && !overwrite)
+      return;
+    if (arg.hasOption(Opt.NODUPLICATEVALUES)
+            && this.containsValue(av.getValue()))
+      return;
+    // new or overwrite if single valued
+    if (argValueList == null || overwrite)
+    {
+      argValueList = new ArrayList<ArgValue>();
+    }
+    SubVals sv = new SubVals(av.getValue());
+    if (sv.has(ID))
+    {
+      String id = sv.get(ID);
+      av.setId(id);
+      idMap.put(id, av);
+    }
+    argValueList.add(av);
+    this.setSetByWildcard(beingSetByWildcard);
+  }
+
+  protected boolean hasValue(String val)
+  {
+    return argValueList.contains(val);
+  }
+
+  protected ArgValue getArgValue()
+  {
+    if (arg.hasOption(Opt.MULTI))
+      Console.warn("Requesting single value for multi value argument");
+    return argValueList.size() > 0 ? argValueList.get(0) : null;
+  }
+
+  protected List<ArgValue> getArgValueList()
+  {
+    return argValueList;
+  }
+
+  protected boolean hasId(String id)
+  {
+    return idMap.containsKey(id);
+  }
+
+  protected ArgValue getId(String id)
+  {
+    return idMap.get(id);
+  }
+
+  private boolean containsValue(String v)
+  {
+    if (argValueList == null)
+      return false;
+    for (ArgValue av : argValueList)
+    {
+      String val = av.getValue();
+      if (v == null && val == null)
+        return true;
+      if (v == null)
+        continue;
+      if (v.equals(val))
+        return true;
+    }
+    return false;
+  }
+}
\ No newline at end of file
diff --git a/src/jalview/bin/argparser/ArgValuesMap.java b/src/jalview/bin/argparser/ArgValuesMap.java
new file mode 100644 (file)
index 0000000..ab6fcc1
--- /dev/null
@@ -0,0 +1,284 @@
+package jalview.bin.argparser;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jalview.bin.argparser.Arg.Opt;
+import jalview.util.FileUtils;
+
+/**
+ * Helper class to allow easy extraction of information about specific argument
+ * values (without having to check for null etc all the time)
+ */
+public class ArgValuesMap
+{
+  protected Map<Arg, ArgValues> m;
+
+  private String linkedId;
+
+  protected ArgValuesMap(String linkedId)
+  {
+    this.linkedId = linkedId;
+    this.newMap();
+  }
+
+  protected ArgValuesMap(String linkedId, Map<Arg, ArgValues> map)
+  {
+    this.linkedId = linkedId;
+    this.m = map;
+  }
+
+  public String getLinkedId()
+  {
+    return linkedId;
+  }
+
+  private Map<Arg, ArgValues> getMap()
+  {
+    return m;
+  }
+
+  private void newMap()
+  {
+    m = new HashMap<Arg, ArgValues>();
+  }
+
+  private void newArg(Arg a)
+  {
+    if (m == null)
+      newMap();
+    if (!containsArg(a))
+      m.put(a, new ArgValues(a));
+  }
+
+  public ArgValues getArgValues(Arg a)
+  {
+    return m == null ? null : m.get(a);
+  }
+
+  public ArgValues getOrCreateArgValues(Arg a)
+  {
+    ArgValues avs = m.get(a);
+    if (avs == null)
+      newArg(a);
+    return getArgValues(a);
+  }
+
+  public List<ArgValue> getArgValueList(Arg a)
+  {
+    ArgValues avs = getArgValues(a);
+    return avs == null ? new ArrayList<>() : avs.getArgValueList();
+  }
+
+  public ArgValue getArgValue(Arg a)
+  {
+    List<ArgValue> vals = getArgValueList(a);
+    return (vals == null || vals.size() == 0) ? null : vals.get(0);
+  }
+
+  public String getValue(Arg a)
+  {
+    ArgValue av = getArgValue(a);
+    return av == null ? null : av.getValue();
+  }
+
+  public boolean containsArg(Arg a)
+  {
+    if (m == null || !m.containsKey(a))
+      return false;
+    return a.hasOption(Opt.STRING) ? getArgValue(a) != null : true;
+  }
+
+  public boolean hasValue(Arg a, String val)
+  {
+    if (m == null || !m.containsKey(a))
+      return false;
+    for (ArgValue av : getArgValueList(a))
+    {
+      String avVal = av.getValue();
+      if ((val == null && avVal == null)
+              || (val != null && val.equals(avVal)))
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public boolean getBoolean(Arg a)
+  {
+    ArgValues av = getArgValues(a);
+    return av == null ? false : av.getBoolean();
+  }
+
+  public Set<Arg> getArgKeys()
+  {
+    return m.keySet();
+  }
+
+  public ArgValue getArgValueOfArgWithSubValKey(Arg a, String svKey)
+  {
+    return getArgValueOfArgWithSubValKey(a, svKey, false);
+  }
+
+  public ArgValue getArgValueOfArgWithSubValKey(Arg a, String svKey,
+          boolean last)
+  {
+    ArgValues avs = this.getArgValues(a);
+    if (avs == null)
+    {
+      return null;
+    }
+    List<ArgValue> compareAvs = avs.getArgValueList();
+    for (int i = 0; i < compareAvs.size(); i++)
+    {
+      int index = last ? compareAvs.size() - 1 - i : i;
+      ArgValue av = compareAvs.get(index);
+      SubVals sv = av.getSubVals();
+      if (sv.has(svKey) && !sv.get(svKey).equals("false"))
+      {
+        return av;
+      }
+    }
+    return null;
+  }
+
+  public ArgValue getClosestPreviousArgValueOfArg(ArgValue thisAv, Arg a)
+  {
+    ArgValue closestAv = null;
+    int thisArgIndex = thisAv.getArgIndex();
+    ArgValues compareAvs = this.getArgValues(a);
+    int closestPreviousIndex = -1;
+    for (ArgValue av : compareAvs.getArgValueList())
+    {
+      int argIndex = av.getArgIndex();
+      if (argIndex < thisArgIndex && argIndex > closestPreviousIndex)
+      {
+        closestPreviousIndex = argIndex;
+        closestAv = av;
+      }
+    }
+    return closestAv;
+  }
+
+  public ArgValue getClosestNextArgValueOfArg(ArgValue thisAv, Arg a)
+  {
+    // this looks for the *next* arg that *might* be referring back to
+    // a thisAv. Such an arg would have no subValues (if it does it should
+    // specify an id in the subValues so wouldn't need to be guessed).
+    ArgValue closestAv = null;
+    int thisArgIndex = thisAv.getArgIndex();
+    if (!containsArg(a))
+      return null;
+    ArgValues compareAvs = this.getArgValues(a);
+    int closestNextIndex = Integer.MAX_VALUE;
+    for (ArgValue av : compareAvs.getArgValueList())
+    {
+      int argIndex = av.getArgIndex();
+      if (argIndex > thisArgIndex && argIndex < closestNextIndex)
+      {
+        closestNextIndex = argIndex;
+        closestAv = av;
+      }
+    }
+    return closestAv;
+  }
+
+  // TODO this is incomplete and currently unused (fortunately)
+  public ArgValue[] getArgValuesReferringTo(String key, String value, Arg a)
+  {
+    // this looks for the *next* arg that *might* be referring back to
+    // a thisAv. Such an arg would have no subValues (if it does it should
+    // specify an id in the subValues so wouldn't need to be guessed).
+    List<ArgValue> avList = new ArrayList<>();
+    Arg[] args = a == null ? (Arg[]) this.getMap().keySet().toArray()
+            : new Arg[]
+            { a };
+    for (Arg keyArg : args)
+    {
+      for (ArgValue av : this.getArgValueList(keyArg))
+      {
+
+      }
+    }
+    return (ArgValue[]) avList.toArray();
+  }
+
+  public boolean hasId(Arg a, String id)
+  {
+    ArgValues avs = this.getArgValues(a);
+    return avs == null ? false : avs.hasId(id);
+  }
+
+  public ArgValue getId(Arg a, String id)
+  {
+    ArgValues avs = this.getArgValues(a);
+    return avs == null ? null : avs.getId(id);
+  }
+
+  /*
+   * This method returns the basename of the first --append or --open value. 
+   * Used primarily for substitutions in output filenames.
+   */
+  public String getBasename()
+  {
+    return getDirBasenameOrExtension(false, false);
+  }
+
+  /*
+   * This method returns the basename of the first --append or --open value. 
+   * Used primarily for substitutions in output filenames.
+   */
+  public String getExtension()
+  {
+    return getDirBasenameOrExtension(false, true);
+  }
+
+  /*
+   * This method returns the dirname of the first --append or --open value. 
+   * Used primarily for substitutions in output filenames.
+   */
+  public String getDirname()
+  {
+    return getDirBasenameOrExtension(true, false);
+  }
+
+  public String getDirBasenameOrExtension(boolean dirname,
+          boolean extension)
+  {
+    String filename = null;
+    String appendVal = getValue(Arg.APPEND);
+    String openVal = getValue(Arg.OPEN);
+    if (appendVal != null)
+      filename = appendVal;
+    if (filename == null && openVal != null)
+      filename = openVal;
+    if (filename == null)
+      return null;
+
+    File file = new File(filename);
+    if (dirname)
+    {
+      return FileUtils.getDirname(file);
+    }
+    return extension ? FileUtils.getExtension(file)
+            : FileUtils.getBasename(file);
+  }
+
+  /*
+   * Checks if there is an Arg with Opt
+   */
+  public boolean hasArgWithOption(Opt o)
+  {
+    for (Arg a : getArgKeys())
+    {
+      if (a.hasOption(o))
+        return true;
+    }
+    return false;
+  }
+}
diff --git a/src/jalview/bin/argparser/BootstrapArgs.java b/src/jalview/bin/argparser/BootstrapArgs.java
new file mode 100644 (file)
index 0000000..ec62bcd
--- /dev/null
@@ -0,0 +1,403 @@
+package jalview.bin.argparser;
+
+import java.io.File;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import jalview.bin.argparser.Arg.Opt;
+import jalview.bin.argparser.Arg.Type;
+import jalview.util.FileUtils;
+
+public class BootstrapArgs
+{
+  // only need one
+  private Map<Arg, List<Map.Entry<Type, String>>> bootstrapArgMap = new HashMap<>();
+
+  private Set<File> argFiles = new HashSet<>();
+
+  private Set<Opt> argsOptions = new HashSet<>();
+
+  private Set<Type> argsTypes = new HashSet<>();
+
+  private boolean outputToStdout = false;
+
+  public static BootstrapArgs getBootstrapArgs(String[] args)
+  {
+    List<String> argList = new ArrayList<>(Arrays.asList(args));
+    return new BootstrapArgs(argList);
+  }
+
+  public static BootstrapArgs getBootstrapArgs(List<String> args)
+  {
+    return new BootstrapArgs(args);
+  }
+
+  private BootstrapArgs(List<String> args)
+  {
+    parse(args, null);
+  }
+
+  private void parse(List<String> args, File inArgFile)
+  {
+    if (args == null)
+      return;
+    // avoid looping argFiles
+    if (inArgFile != null)
+    {
+      if (argFiles.contains(inArgFile))
+      {
+        jalview.bin.Console.errPrintln(
+                "Looped argfiles detected: '" + inArgFile.getPath() + "'");
+        return;
+      }
+      argFiles.add(inArgFile);
+    }
+
+    for (int i = 0; i < args.size(); i++)
+    {
+      String arg = args.get(i);
+      // look for double-dash, e.g. --arg
+      if (arg.startsWith(ArgParser.DOUBLEDASH))
+      {
+        String argName = null;
+        String val = null;
+        Type type = null;
+        // remove "--"
+        argName = arg.substring(ArgParser.DOUBLEDASH.length());
+
+        // look for equals e.g. --arg=value
+        int equalPos = argName.indexOf(ArgParser.EQUALS);
+        if (equalPos > -1)
+        {
+          val = argName.substring(equalPos + 1);
+          argName = argName.substring(0, equalPos);
+        }
+
+        // check for boolean prepended by "no"
+        if (argName.startsWith(ArgParser.NEGATESTRING)
+                && ArgParser.argMap.containsKey(
+                        argName.substring(ArgParser.NEGATESTRING.length())))
+        {
+          val = "false";
+          argName = argName.substring(ArgParser.NEGATESTRING.length());
+        }
+
+        // look for type modification e.g. --help-opening
+        int dashPos = argName.indexOf(ArgParser.SINGLEDASH);
+        if (dashPos > -1)
+        {
+          String potentialArgName = argName.substring(0, dashPos);
+          Arg potentialArg = ArgParser.argMap.get(potentialArgName);
+          if (potentialArg != null && potentialArg.hasOption(Opt.HASTYPE))
+          {
+            String typeName = argName.substring(dashPos + 1);
+            try
+            {
+              type = Type.valueOf(typeName.toUpperCase(Locale.ROOT));
+            } catch (IllegalArgumentException e)
+            {
+              type = Type.INVALID;
+            }
+            argName = argName.substring(0, dashPos);
+          }
+        }
+
+        // after all other args, look for Opt.PREFIX args if still not found
+        if (!ArgParser.argMap.containsKey(argName))
+        {
+          for (Arg potentialArg : EnumSet.allOf(Arg.class))
+          {
+            if (potentialArg.hasOption(Opt.PREFIXKEV) && argName != null
+                    && argName.startsWith(potentialArg.getName())
+                    && val != null)
+            {
+              val = argName.substring(potentialArg.getName().length())
+                      + ArgParser.EQUALS + val;
+              argName = argName.substring(0,
+                      potentialArg.getName().length());
+              break;
+            }
+          }
+        }
+
+        Arg a = ArgParser.argMap.get(argName);
+
+        if (a != null)
+        {
+          for (Opt opt : a.getOptions())
+          {
+            if (!argsOptions.contains(opt))
+            {
+              argsOptions.add(opt);
+            }
+          }
+          Type t = a.getType();
+          if (!argsTypes.contains(t))
+          {
+            argsTypes.add(t);
+          }
+        }
+
+        if (a == null || !a.hasOption(Opt.BOOTSTRAP))
+        {
+          // not a bootstrap arg
+
+          // make a check for an output going to stdout
+          if (a != null && a.hasOption(Opt.OUTPUTFILE)
+                  && a.hasOption(Opt.STDOUT))
+          {
+            if (val == null && i + 1 < args.size())
+            {
+              val = args.get(i + 1);
+            }
+            if (val.startsWith("[") && val.indexOf(']') > 0)
+            {
+              val = val.substring(val.indexOf(']') + 1);
+            }
+
+            if (ArgParser.STDOUTFILENAME.equals(val))
+            {
+              this.outputToStdout = true;
+            }
+          }
+
+          continue;
+        }
+
+        if (a.hasOption(Opt.STRING))
+        {
+          List<String> vals = null;
+          if (equalPos == -1)
+          {
+            vals = ArgParser.getShellGlobbedFilenameValues(a, args, i + 1);
+          }
+          else
+          {
+            if (a.hasOption(Opt.GLOB))
+            {
+              vals = FileUtils.getFilenamesFromGlob(val);
+            }
+            else
+            {
+              vals = new ArrayList<>();
+              vals.add(val);
+            }
+          }
+          addAll(a, type, vals);
+
+          if (a == Arg.ARGFILE)
+          {
+            for (String filename : vals)
+            {
+              File argFile = new File(filename);
+              parse(ArgParser.readArgFile(argFile), argFile);
+            }
+          }
+        }
+        else
+        {
+          if (val == null)
+          {
+            val = "true";
+          }
+
+          add(a, type, val);
+        }
+      }
+    }
+  }
+
+  public boolean contains(Arg a)
+  {
+    return bootstrapArgMap.containsKey(a);
+  }
+
+  public boolean containsType(Type t)
+  {
+    for (List<Map.Entry<Type, String>> l : bootstrapArgMap.values())
+    {
+      for (Map.Entry<Type, String> e : l)
+      {
+        if (e.getKey() == t)
+          return true;
+      }
+    }
+    return false;
+  }
+
+  public List<Arg> getArgsOfType(Type t)
+  {
+    return getArgsOfType(t, new Opt[] {});
+  }
+
+  public List<Arg> getArgsOfType(Type t, Opt... opts)
+  {
+    List<Arg> args = new ArrayList<>();
+    for (Arg a : bootstrapArgMap.keySet())
+    {
+      if (!a.hasAllOptions(opts))
+        continue;
+
+      List<Map.Entry<Type, String>> l = bootstrapArgMap.get(a);
+      if (l.stream().anyMatch(e -> e.getKey() == t))
+      {
+        args.add(a);
+      }
+    }
+    return args;
+  }
+
+  public List<Map.Entry<Type, String>> getList(Arg a)
+  {
+    return bootstrapArgMap.get(a);
+  }
+
+  public List<String> getValueList(Arg a)
+  {
+    return bootstrapArgMap.get(a).stream().map(e -> e.getValue())
+            .collect(Collectors.toList());
+  }
+
+  private List<Map.Entry<Type, String>> getOrCreateList(Arg a)
+  {
+    List<Map.Entry<Type, String>> l = getList(a);
+    if (l == null)
+    {
+      l = new ArrayList<>();
+      putList(a, l);
+    }
+    return l;
+  }
+
+  private void putList(Arg a, List<Map.Entry<Type, String>> l)
+  {
+    bootstrapArgMap.put(a, l);
+  }
+
+  /*
+   * Creates a new list if not used before,
+   * adds the value unless the existing list is non-empty
+   * and the arg is not MULTI (so first expressed value is
+   * retained).
+   */
+  private void add(Arg a, Type t, String s)
+  {
+    List<Map.Entry<Type, String>> l = getOrCreateList(a);
+    if (a.hasOption(Opt.MULTI) || l.size() == 0)
+    {
+      l.add(entry(t, s));
+    }
+  }
+
+  private void addAll(Arg a, Type t, List<String> al)
+  {
+    List<Map.Entry<Type, String>> l = getOrCreateList(a);
+    if (a.hasOption(Opt.MULTI))
+    {
+      for (String s : al)
+      {
+        l.add(entry(t, s));
+      }
+    }
+    else if (l.size() == 0 && al.size() > 0)
+    {
+      l.add(entry(t, al.get(0)));
+    }
+  }
+
+  private static Map.Entry<Type, String> entry(Type t, String s)
+  {
+    return new AbstractMap.SimpleEntry<Type, String>(t, s);
+  }
+
+  /*
+   * Retrieves the first value even if MULTI.
+   * A convenience for non-MULTI args.
+   */
+  public String getValue(Arg a)
+  {
+    if (!bootstrapArgMap.containsKey(a))
+      return null;
+    List<Map.Entry<Type, String>> aL = bootstrapArgMap.get(a);
+    return (aL == null || aL.size() == 0) ? null : aL.get(0).getValue();
+  }
+
+  public boolean getBoolean(Arg a, boolean d)
+  {
+    if (!bootstrapArgMap.containsKey(a))
+      return d;
+    return Boolean.parseBoolean(getValue(a));
+  }
+
+  public boolean getBoolean(Arg a)
+  {
+    if (!(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY)))
+    {
+      return false;
+    }
+    if (bootstrapArgMap.containsKey(a))
+    {
+      return Boolean.parseBoolean(getValue(a));
+    }
+    else
+    {
+      return a.getDefaultBoolValue();
+    }
+  }
+
+  public boolean argsHaveOption(Opt opt)
+  {
+    return argsOptions.contains(opt);
+  }
+
+  public boolean argsHaveType(Type type)
+  {
+    return argsTypes.contains(type);
+  }
+
+  public boolean isHeadless()
+  {
+    boolean isHeadless = false;
+    if (this.argsHaveType(Type.HELP))
+    {
+      // --help, --help-all, ... specified => headless
+      isHeadless = true;
+    }
+    else if (this.contains(Arg.VERSION))
+    {
+      // --version specified => headless
+      isHeadless = true;
+    }
+    else if (this.contains(Arg.GUI))
+    {
+      // --gui specified => forced NOT headless
+      isHeadless = !this.getBoolean(Arg.GUI);
+    }
+    else if (this.contains(Arg.HEADLESS))
+    {
+      // --headless has been specified on the command line => headless
+      isHeadless = this.getBoolean(Arg.HEADLESS);
+    }
+    else if (this.argsHaveOption(Opt.OUTPUTFILE))
+    {
+      // --output file.fa, --image pic.png, --structureimage struct.png =>
+      // assume headless unless above has been already specified
+      isHeadless = true;
+    }
+    return isHeadless;
+  }
+
+  public boolean outputToStdout()
+  {
+    return this.outputToStdout;
+  }
+}
diff --git a/src/jalview/bin/argparser/SubVals.java b/src/jalview/bin/argparser/SubVals.java
new file mode 100644 (file)
index 0000000..4d146d9
--- /dev/null
@@ -0,0 +1,183 @@
+package jalview.bin.argparser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import jalview.bin.Console;
+
+/**
+ * A helper class to parse a string of the possible forms "content"
+ * "[index]content", "[keyName=keyValue]content" and return the integer index,
+ * the strings keyName and keyValue, and the content after the square brackets
+ * (if present). Values not set `will be -1 or null.
+ */
+public class SubVals
+{
+  public static int NOTSET = -1;
+
+  private int index = NOTSET;
+
+  private Map<String, String> subValMap;
+
+  private static char SEPARATOR = ',';
+
+  private static char EQUALS = '=';
+
+  private String content = null;
+
+  protected SubVals(SubVals sv, String c)
+  {
+    this(sv, c, true);
+  }
+
+  protected SubVals(SubVals sv, String c, boolean merge)
+  {
+    SubVals subvals;
+    if (merge)
+    {
+      SubVals vsv = new SubVals(c);
+      if (sv != null && sv.getSubValMap() != null)
+      {
+        for (String key : sv.getSubValMap().keySet())
+        {
+          vsv.put(key, sv.get(key));
+        }
+      }
+      if (sv != null && sv.getIndex() > 0)
+      {
+        vsv.index = sv.getIndex();
+      }
+      subvals = vsv;
+    }
+    else
+    {
+      // replace
+      subvals = sv;
+    }
+    if (subvals == null)
+    {
+      this.subValMap = new HashMap<>();
+    }
+    else
+    {
+      this.subValMap = subvals == null ? new HashMap<>()
+              : subvals.getSubValMap();
+      this.index = subvals.getIndex();
+    }
+    this.content = c;
+  }
+
+  protected SubVals(String item)
+  {
+    if (subValMap == null)
+      subValMap = new HashMap<>();
+    this.parseVals(item);
+  }
+
+  public void parseVals(String item)
+  {
+    if (item == null)
+      return;
+    if (item.indexOf('[') == 0 && item.indexOf(']') > 1)
+    {
+      int openBracket = 0;
+      int closeBracket = item.indexOf(']');
+      String subvalsString = item.substring(openBracket + 1, closeBracket);
+      this.content = item.substring(closeBracket + 1);
+      boolean setIndex = false;
+      for (String subvalString : subvalsString
+              .split(Character.toString(SEPARATOR)))
+      {
+        int equals = subvalString.indexOf(EQUALS);
+        if (equals > -1)
+        {
+          this.put(subvalString.substring(0, equals),
+                  subvalString.substring(equals + 1));
+        }
+        else
+        {
+          try
+          {
+            this.index = Integer.parseInt(subvalString);
+            setIndex = true;
+          } catch (NumberFormatException e)
+          {
+            // store this non-numeric key as a "true" value
+            this.put(subvalString, "true");
+          }
+        }
+      }
+      if (!setIndex)
+        this.index = NOTSET;
+      else
+        Console.debug("SubVals from '" + subvalsString + "' has index "
+                + this.index + " set");
+    }
+    else
+    {
+      this.content = item;
+    }
+  }
+
+  protected void put(String key, String val)
+  {
+    subValMap.put(key, val);
+  }
+
+  public boolean notSet()
+  {
+    // notSet is true if content present but nonsensical
+    return index == NOTSET && (subValMap == null || subValMap.size() == 0);
+  }
+
+  public String getWithSubstitutions(ArgParser ap, String id, String key)
+  {
+    return ap.makeSubstitutions(subValMap.get(key), id);
+  }
+
+  public String get(String key)
+  {
+    return subValMap.get(key);
+  }
+
+  public boolean has(String key)
+  {
+    return subValMap.containsKey(key);
+  }
+
+  public int getIndex()
+  {
+    return index;
+  }
+
+  public String getContent()
+  {
+    return content;
+  }
+
+  protected Map<String, String> getSubValMap()
+  {
+    return subValMap;
+  }
+
+  public String toString()
+  {
+    if (subValMap == null && getIndex() == NOTSET)
+      return "";
+
+    StringBuilder sb = new StringBuilder();
+    List<String> entries = new ArrayList<>();
+    subValMap.entrySet().stream().forEachOrdered(
+            m -> entries.add(m.getValue().equals("true") ? m.getKey()
+                    : new StringBuilder().append(m.getKey()).append(EQUALS)
+                            .append(m.getValue()).toString()));
+    if (getIndex() != NOTSET)
+      entries.add(Integer.toString(getIndex()));
+    sb.append('[');
+    sb.append(String.join(Character.toString(SEPARATOR), entries));
+    sb.append(']');
+    return sb.toString();
+  }
+}
\ No newline at end of file
index 62ef660..c15bbf8 100644 (file)
@@ -473,7 +473,7 @@ public class EditCommand implements CommandI
     {
       command.seqs[s].insertCharAt(command.position, command.number,
               command.gapChar);
-      // System.out.println("pos: "+command.position+" number:
+      // jalview.bin.Console.outPrintln("pos: "+command.position+" number:
       // "+command.number);
     }
 
@@ -486,7 +486,7 @@ public class EditCommand implements CommandI
   //
   // for (int s = 0; s < command.seqs.length; s++)
   // {
-  // System.out.println("pos: "+command.position+" number: "+command.number);
+  // jalview.bin.Console.outPrintln("pos: "+command.position+" number: "+command.number);
   // command.seqs[s].insertCharAt(command.position, command.number,'A');
   // }
   //
@@ -1433,7 +1433,7 @@ public class EditCommand implements CommandI
           }
           else
           {
-            System.err.println("Can't undo edit action " + action);
+            jalview.bin.Console.errPrintln("Can't undo edit action " + action);
             // throw new IllegalStateException("Can't undo edit action " +
             // action);
           }
index f5154ec..cb74a66 100644 (file)
@@ -707,7 +707,7 @@ public class AlignedCodonFrame
             ds.setSequenceFeatures(dna.getSequenceFeatures());
             // dnaSeqs[i] = ds;
             ssm.fromSeq = ds;
-            System.out.println("Realised mapped sequence " + ds.getName());
+            jalview.bin.Console.outPrintln("Realised mapped sequence " + ds.getName());
           }
         }
       }
index 517a6dd..514a326 100755 (executable)
@@ -2050,14 +2050,14 @@ public class Alignment implements AlignmentI, AutoCloseable
   public ContactMatrixI getContactMatrixFor(AlignmentAnnotation _aa)
   {
     ContactMatrixI cm = cmholder.getContactMatrixFor(_aa);
-    if (cm==null && _aa.groupRef!=null)
+    if (cm == null && _aa.groupRef != null)
     {
       cm = _aa.groupRef.getContactMatrixFor(_aa);
     }
-    if (cm==null && _aa.sequenceRef!=null)
+    if (cm == null && _aa.sequenceRef != null)
     {
       cm = _aa.sequenceRef.getContactMatrixFor(_aa);
-      if (cm==null)
+      if (cm == null)
       {
         // TODO fix up this logic and unify with getContactListFor
         cm = _aa.sequenceRef.getDatasetSequence().getContactMatrixFor(_aa);
@@ -2076,14 +2076,19 @@ public class Alignment implements AlignmentI, AutoCloseable
     }
     if (cl == null && _aa.sequenceRef != null)
     {
-      int spos = _aa.sequenceRef.findPosition(column);
-      if (spos >= _aa.sequenceRef.getStart()
-              && spos <= 1 + _aa.sequenceRef.getEnd())
+      if (_aa.annotations[column] != null)
       {
-        cl = _aa.sequenceRef.getContactListFor(_aa, spos-_aa.sequenceRef.getStart());
+        // sequence associated
+        cl = _aa.sequenceRef.getContactListFor(_aa, column);
         if (cl == null && _aa.sequenceRef.getDatasetSequence() != null)
         {
-          _aa.sequenceRef.getDatasetSequence().getContactListFor(_aa, spos-_aa.sequenceRef.getStart());
+          int spos = _aa.sequenceRef.findPosition(column);
+          if (spos >= _aa.sequenceRef.getStart()
+                  && spos <= 1 + _aa.sequenceRef.getEnd())
+          {
+            cl = _aa.sequenceRef.getDatasetSequence().getContactListFor(_aa,
+                    spos - _aa.sequenceRef.getStart());
+          }
         }
       }
     }
@@ -2096,8 +2101,7 @@ public class Alignment implements AlignmentI, AutoCloseable
     AlignmentAnnotation aa = cmholder.addContactList(cm);
 
     Annotation _aa[] = new Annotation[getWidth()];
-    Annotation dummy = new Annotation(0.0f);
-    for (int i = 0; i < _aa.length; _aa[i++] = dummy)
+    for (int i = 0; i < _aa.length; _aa[i++] = new Annotation(0.0f))
     {
       ;
     }
index 4861dfd..7e6b904 100755 (executable)
@@ -126,7 +126,7 @@ public class AlignmentAnnotation
       invalidrnastruc = -1;
     } catch (WUSSParseException px)
     {
-      // DEBUG System.out.println(px);
+      // DEBUG jalview.bin.Console.outPrintln(px);
       invalidrnastruc = px.getProblemPos();
     }
     if (invalidrnastruc > -1)
@@ -142,7 +142,7 @@ public class AlignmentAnnotation
       scaleColLabel = true;
       _markRnaHelices();
     }
-    // System.out.println("featuregroup " + _rnasecstr[0].getFeatureGroup());
+    // jalview.bin.Console.outPrintln("featuregroup " + _rnasecstr[0].getFeatureGroup());
 
   }
 
@@ -156,10 +156,10 @@ public class AlignmentAnnotation
     {
 
       /*
-       * System.out.println(this.annotation._rnasecstr[x] + " Begin" +
+       * jalview.bin.Console.outPrintln(this.annotation._rnasecstr[x] + " Begin" +
        * this.annotation._rnasecstr[x].getBegin());
        */
-      // System.out.println(this.annotation._rnasecstr[x].getFeatureGroup());
+      // jalview.bin.Console.outPrintln(this.annotation._rnasecstr[x].getFeatureGroup());
       int val = 0;
       try
       {
@@ -308,6 +308,11 @@ public class AlignmentAnnotation
 
   public static final int CONTACT_MAP = 4;
 
+  /**
+   * property that when set to non-empty string disables display of column groups defined on the contact matrix
+   */
+  public static final String CONTACT_MAP_NOGROUPS = "CMNOGRPS";
+
   public boolean belowAlignment = true;
 
   public SequenceGroup groupRef = null;
@@ -381,7 +386,7 @@ public class AlignmentAnnotation
     char firstChar = 0;
     for (int i = 0; i < annotations.length; i++)
     {
-      // DEBUG System.out.println(i + ": " + annotations[i]);
+      // DEBUG jalview.bin.Console.outPrintln(i + ": " + annotations[i]);
       if (annotations[i] == null)
       {
         continue;
@@ -389,14 +394,14 @@ public class AlignmentAnnotation
       if (annotations[i].secondaryStructure == 'H'
               || annotations[i].secondaryStructure == 'E')
       {
-        // DEBUG System.out.println( "/H|E/ '" +
+        // DEBUG jalview.bin.Console.outPrintln( "/H|E/ '" +
         // annotations[i].secondaryStructure + "'");
         hasIcons |= true;
       }
       else
       // Check for RNA secondary structure
       {
-        // DEBUG System.out.println( "/else/ '" +
+        // DEBUG jalview.bin.Console.outPrintln( "/else/ '" +
         // annotations[i].secondaryStructure + "'");
         // TODO: 2.8.2 should this ss symbol validation check be a function in
         // RNA/ResidueProperties ?
@@ -441,7 +446,7 @@ public class AlignmentAnnotation
         }
       }
 
-      // System.out.println("displaychar " + annotations[i].displayCharacter);
+      // jalview.bin.Console.outPrintln("displaychar " + annotations[i].displayCharacter);
 
       if (annotations[i].displayCharacter == null
               || annotations[i].displayCharacter.length() == 0)
@@ -568,12 +573,12 @@ public class AlignmentAnnotation
                       : annotations[index + offset].displayCharacter == null
                               || annotations[index
                                       + offset].displayCharacter
-                                      .length() == 0
-                                              ? annotations[index
-                                                      + offset].secondaryStructure
-                                              : annotations[index
-                                                      + offset].displayCharacter
-                                                      .charAt(0));
+                                              .length() == 0
+                                                      ? annotations[index
+                                                              + offset].secondaryStructure
+                                                      : annotations[index
+                                                              + offset].displayCharacter
+                                                                      .charAt(0));
     }
 
     @Override
@@ -1745,5 +1750,23 @@ public class AlignmentAnnotation
     }
     return aa;
   }
+  
+  /**
+   * convenience method to check for the 'CONTACT_MAP_NOGROUPS' property for this alignment annotation row
+   * @return true if no CONTACT_MAP_NOGROUPS property is found, or it is set to ""
+   */
+  public boolean isShowGroupsForContactMatrix()
+  {
+    return getProperty(AlignmentAnnotation.CONTACT_MAP_NOGROUPS)==null || "".equals(getProperty(AlignmentAnnotation.CONTACT_MAP_NOGROUPS));
+  }
+  /**
+   * set the 'CONTACT_MAP_NOGROUPS' property for this alignment annotation row
+   * @see isShowGroupsForContactMatrix
+   */
+  public void setShowGroupsForContactMatrix(boolean showGroups)
+  {
+    setProperty(AlignmentAnnotation.CONTACT_MAP_NOGROUPS, showGroups ? "" : "nogroups");
+  }
+
 
 }
index e6604d1..6ab71c7 100644 (file)
@@ -1128,11 +1128,11 @@ public class AlignmentView
   public static void testSelectionViews(AlignmentI alignment,
           HiddenColumns hidden, SequenceGroup selection)
   {
-    System.out.println("Testing standard view creation:\n");
+    jalview.bin.Console.outPrintln("Testing standard view creation:\n");
     AlignmentView view = null;
     try
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "View with no hidden columns, no limit to selection, no groups to be collected:");
       view = new AlignmentView(alignment, hidden, selection, false, false,
               false);
@@ -1141,12 +1141,12 @@ public class AlignmentView
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to generate alignment with selection but no groups marked.");
     }
     try
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "View with no hidden columns, no limit to selection, and all groups to be collected:");
       view = new AlignmentView(alignment, hidden, selection, false, false,
               true);
@@ -1154,12 +1154,12 @@ public class AlignmentView
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to generate alignment with selection marked but no groups marked.");
     }
     try
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "View with no hidden columns, limited to selection and no groups to be collected:");
       view = new AlignmentView(alignment, hidden, selection, false, true,
               false);
@@ -1167,12 +1167,12 @@ public class AlignmentView
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to generate alignment with selection restricted but no groups marked.");
     }
     try
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "View with no hidden columns, limited to selection, and all groups to be collected:");
       view = new AlignmentView(alignment, hidden, selection, false, true,
               true);
@@ -1180,12 +1180,12 @@ public class AlignmentView
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to generate alignment with selection restricted and groups marked.");
     }
     try
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "View *with* hidden columns, no limit to selection, no groups to be collected:");
       view = new AlignmentView(alignment, hidden, selection, true, false,
               false);
@@ -1193,12 +1193,12 @@ public class AlignmentView
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to generate alignment with selection but no groups marked.");
     }
     try
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "View *with* hidden columns, no limit to selection, and all groups to be collected:");
       view = new AlignmentView(alignment, hidden, selection, true, false,
               true);
@@ -1206,12 +1206,12 @@ public class AlignmentView
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to generate alignment with selection marked but no groups marked.");
     }
     try
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "View *with* hidden columns, limited to selection and no groups to be collected:");
       view = new AlignmentView(alignment, hidden, selection, true, true,
               false);
@@ -1219,12 +1219,12 @@ public class AlignmentView
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to generate alignment with selection restricted but no groups marked.");
     }
     try
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "View *with* hidden columns, limited to selection, and all groups to be collected:");
       view = new AlignmentView(alignment, hidden, selection, true, true,
               true);
@@ -1232,7 +1232,7 @@ public class AlignmentView
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to generate alignment with selection restricted and groups marked.");
     }
 
index 5b55594..624c2b9 100755 (executable)
@@ -23,22 +23,22 @@ package jalview.datamodel;
 import java.awt.Color;
 
 /**
- * DOCUMENT ME!
+ * Represent a node in a binary tree
  * 
- * @author $author$
+ * @author $mclamp (probably!)$
  * @version $Revision$
  */
-public class BinaryNode
+public class BinaryNode<T>
 {
-  Object element;
+  T element;
 
   String name;
 
-  BinaryNode left;
+  BinaryNode<T> left;
 
-  BinaryNode right;
+  BinaryNode<T> right;
 
-  BinaryNode parent;
+  BinaryNode<T> parent;
 
   /** Bootstrap value */
   public int bootstrap;
@@ -58,7 +58,10 @@ public class BinaryNode
   /** DOCUMENT ME!! */
   public Color color = Color.black;
 
-  /** DOCUMENT ME!! */
+  /**
+   * if true, node is created to simulate polytomy between parent and its 3 or
+   * more children
+   */
   public boolean dummy = false;
 
   /**
@@ -81,7 +84,7 @@ public class BinaryNode
    * @param name
    *          DOCUMENT ME!
    */
-  public BinaryNode(Object element, BinaryNode parent, String name,
+  public BinaryNode(T element, BinaryNode<T> parent, String name,
           double dist)
   {
     this();
@@ -91,14 +94,14 @@ public class BinaryNode
     this.dist = dist;
   }
 
-  public BinaryNode(Object element, BinaryNode parent, String name,
+  public BinaryNode(T element, BinaryNode<T> parent, String name,
           double dist, int bootstrap)
   {
     this(element, parent, name, dist);
     this.bootstrap = bootstrap;
   }
 
-  public BinaryNode(Object val, BinaryNode parent, String name, double dist,
+  public BinaryNode(T val, BinaryNode<T> parent, String name, double dist,
           int bootstrap, boolean dummy)
   {
     this(val, parent, name, dist, bootstrap);
@@ -110,7 +113,7 @@ public class BinaryNode
    * 
    * @return DOCUMENT ME!
    */
-  public Object element()
+  public T element()
   {
     return element;
   }
@@ -123,7 +126,7 @@ public class BinaryNode
    * 
    * @return DOCUMENT ME!
    */
-  public Object setElement(Object v)
+  public T setElement(T v)
   {
     return element = v;
   }
@@ -133,7 +136,7 @@ public class BinaryNode
    * 
    * @return DOCUMENT ME!
    */
-  public BinaryNode left()
+  public BinaryNode<T> left()
   {
     return left;
   }
@@ -146,7 +149,7 @@ public class BinaryNode
    * 
    * @return DOCUMENT ME!
    */
-  public BinaryNode setLeft(BinaryNode n)
+  public BinaryNode<T> setLeft(BinaryNode<T> n)
   {
     return left = n;
   }
@@ -156,7 +159,7 @@ public class BinaryNode
    * 
    * @return DOCUMENT ME!
    */
-  public BinaryNode right()
+  public BinaryNode<T> right()
   {
     return right;
   }
@@ -169,7 +172,7 @@ public class BinaryNode
    * 
    * @return DOCUMENT ME!
    */
-  public BinaryNode setRight(BinaryNode n)
+  public BinaryNode<T> setRight(BinaryNode<T> n)
   {
     return right = n;
   }
@@ -179,7 +182,7 @@ public class BinaryNode
    * 
    * @return DOCUMENT ME!
    */
-  public BinaryNode parent()
+  public BinaryNode<T> parent()
   {
     return parent;
   }
@@ -192,7 +195,7 @@ public class BinaryNode
    * 
    * @return DOCUMENT ME!
    */
-  public BinaryNode setParent(BinaryNode n)
+  public BinaryNode<T> setParent(BinaryNode<T> n)
   {
     return parent = n;
   }
@@ -214,7 +217,7 @@ public class BinaryNode
    * setChild(null), or detach() for this.
    * 
    */
-  public void SetChildren(BinaryNode leftchild, BinaryNode rightchild)
+  public void SetChildren(BinaryNode<T> leftchild, BinaryNode<T> rightchild)
   {
     if (leftchild != null)
     {
@@ -236,7 +239,7 @@ public class BinaryNode
    * 
    * @return BinaryNode The detached node.
    */
-  public BinaryNode detach()
+  public BinaryNode<T> detach()
   {
     if (this.parent != null)
     {
@@ -264,9 +267,9 @@ public class BinaryNode
    * 
    * @return BinaryNode
    */
-  public BinaryNode ascendLeft()
+  public BinaryNode<T> ascendLeft()
   {
-    BinaryNode c = this;
+    BinaryNode<T> c = this;
 
     do
     {
@@ -283,9 +286,9 @@ public class BinaryNode
    * 
    * @return BinaryNode
    */
-  public BinaryNode ascendRight()
+  public BinaryNode<T> ascendRight()
   {
-    BinaryNode c = this;
+    BinaryNode<T> c = this;
 
     do
     {
@@ -366,9 +369,9 @@ public class BinaryNode
    * ascends the tree but doesn't stop until a non-dummy node is discovered.
    * 
    */
-  public BinaryNode AscendTree()
+  public BinaryNode<T> AscendTree()
   {
-    BinaryNode c = this;
+    BinaryNode<T> c = this;
 
     do
     {
index 6ee324f..4a38ec0 100644 (file)
@@ -278,6 +278,27 @@ public class ColumnSelection
   }
 
   /**
+   * add a series of start,end (inclusive) ranges to the column selection
+   * 
+   * @param rng
+   *          [start_0, end_0, start_1, end_1, ... ]
+   * @param baseOne
+   *          - when true, ranges are base 1 and will be mapped to base 0
+   */
+  public void addRangeOfElements(int[] rng, boolean baseOne)
+  {
+    int base = baseOne ? -1 : 0;
+    for (int c = 0; c < rng.length; c += 2)
+    {
+      for (int p = rng[c]; p <= rng[c + 1]; p++)
+      {
+        selection.add(base + p);
+      }
+    }
+
+  }
+
+  /**
    * clears column selection
    */
   public void clear()
@@ -586,8 +607,8 @@ public class ColumnSelection
           int cpos = ann_row.sequenceRef.findPosition(column) - 1;
           ContactListI clist = ann_row.sequenceRef
                   .getContactListFor(ann_row, cpos);
-          for (int row = column + 8,
-                  rowEnd = clist.getContactHeight(); row < rowEnd; row++)
+          for (int row = column + 8, rowEnd = clist
+                  .getContactHeight(); row < rowEnd; row++)
           {
             if (filterParams
                     .getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD
index ac06adb..da55403 100644 (file)
@@ -1,5 +1,9 @@
 package jalview.datamodel;
 
+import java.awt.Color;
+
+import jalview.renderer.ContactGeometry.contactInterval;
+
 public interface ContactListI extends ContactListProviderI
 {
 
@@ -12,4 +16,8 @@ public interface ContactListI extends ContactListProviderI
    */
   ContactRange getRangeFor(int from_column, int to_column);
 
+  default Color getColourForGroup()
+  {
+    return null;
+  }
 }
index 8e806e4..bb31c5d 100644 (file)
@@ -1,5 +1,9 @@
 package jalview.datamodel;
 
+import java.awt.Color;
+
+import jalview.renderer.ContactGeometry.contactInterval;
+
 /**
  * helper class to compute min/max/mean for a range on a contact list
  * 
@@ -51,9 +55,9 @@ public class ContactListImpl implements ContactListI
     {
       from_column = 0;
     }
-    if (to_column > getContactHeight())
+    if (to_column >= getContactHeight())
     {
-      to_column = getContactHeight();
+      to_column = getContactHeight()-1;
     }
     ContactRange cr = new ContactRange();
     cr.setFrom_column(from_column);
@@ -95,4 +99,15 @@ public class ContactListImpl implements ContactListI
     return cr;
   }
 
+  @Override
+  public int[] getMappedPositionsFor(int cStart, int cEnd)
+  {
+    return clist.getMappedPositionsFor(cStart, cEnd);
+  }
+
+  @Override
+  public Color getColourForGroup()
+  {
+    return clist.getColourForGroup();
+  }
 }
index f027e01..d6e9ba9 100644 (file)
@@ -1,5 +1,7 @@
 package jalview.datamodel;
 
+import java.awt.Color;
+
 public interface ContactListProviderI
 {
 
@@ -26,4 +28,23 @@ public interface ContactListProviderI
    */
   double getContactAt(int column);
 
+  /**
+   * Return positions in local reference corresponding to cStart and cEnd in
+   * matrix data. Positions are base 1 column indices for sequence associated
+   * matrices.
+   * 
+   * @param cStart
+   * @param cEnd
+   * @return int[] { start, end (inclusive) for each contiguous segment}
+   */
+  default int[] getMappedPositionsFor(int cStart, int cEnd)
+  {
+    return new int[] { cStart, cEnd };
+  }
+
+  default Color getColourForGroup()
+  {
+    return null;
+  }
+
 }
index 296feaf..af083dd 100644 (file)
@@ -5,6 +5,8 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+import jalview.ws.datamodel.MappableContactMatrixI;
+
 public class ContactMapHolder implements ContactMapHolderI
 {
 
@@ -28,6 +30,14 @@ public class ContactMapHolder implements ContactMapHolderI
     {
       return null;
     }
+    if (cm instanceof MappableContactMatrixI)
+    {
+      if (_aa.sequenceRef != null)
+      {
+        return ((MappableContactMatrixI) cm)
+                .getMappableContactList(_aa.sequenceRef, column);
+      }
+    }
     // TODO: could resolve sequence position to column position here
     // TODO: what about for complexes - where contactMatrix may involve two or
     // more sequences
@@ -49,9 +59,9 @@ public class ContactMapHolder implements ContactMapHolderI
     contactmaps.put(aa.annotationId, cm);
     // TODO: contact matrices could be intra or inter - more than one refseq
     // possible!
-    if (cm.hasReferenceSeq())
+    if (cm instanceof MappableContactMatrixI)
     {
-      aa.setSequenceRef(cm.getReferenceSeq());
+      aa.setSequenceRef(((MappableContactMatrixI) cm).getReferenceSeq());
     }
     return aa;
   }
index 1b1889e..48b6e6b 100644 (file)
@@ -150,20 +150,6 @@ public abstract class ContactMatrix implements ContactMatrixI
   }
 
   @Override
-  public boolean hasReferenceSeq()
-  {
-    // TODO Auto-generated method stub
-    return false;
-  }
-
-  @Override
-  public SequenceI getReferenceSeq()
-  {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
   public String getAnnotLabel()
   {
     return "Contact Matrix";
@@ -174,67 +160,33 @@ public abstract class ContactMatrix implements ContactMatrixI
   {
     return "Contact Matrix";
   }
-  List<BitSet> groups=null;
-  @Override
-  public void updateGroups(List<BitSet> colGroups)
-  {
-    groups = colGroups;
-    colorMap=new HashMap<>();
-  }
-  @Override
-  public boolean hasGroups()
-  {
-    return groups!=null && groups.size()>0;
-  }
+  GroupSet grps = new GroupSet();
   @Override
-  public List<BitSet> getGroups()
+  public GroupSetI getGroupSet()
   {
-    return groups;
+    return grps;
   }
   @Override
-  public BitSet getGroupsFor(int column)
+  public void setGroupSet(GroupSet makeGroups)
   {
-    for (BitSet gp:groups) {
-      if (gp.get(column))
-      {
-        return gp;
-      }
-    }
-    return ContactMatrixI.super.getGroupsFor(column);
-  }
-  HashMap<BitSet,Color> colorMap = new HashMap<>();
-  @Override 
-  public Color getColourForGroup(BitSet bs)
-  {
-    if (bs==null) {
-      return Color.white;
-    }
-    Color groupCol=colorMap.get(bs);
-    if (groupCol==null)
-    {
-      return Color.white;
-    }
-    return groupCol;
-  }
-  @Override 
-  public void setColorForGroup(BitSet bs,Color color)
-  {
-    colorMap.put(bs,color);
+    grps = makeGroups;
   }
   public static String contactToFloatString(ContactMatrixI cm)
   {
     StringBuilder sb = new StringBuilder();
-    for (int c=0;c<cm.getWidth();c++)
+    for (int c = 0; c < cm.getWidth(); c++)
     {
-      ContactListI cl=cm.getContactList(c);
-      if (cl!=null) {
-      for (int h=0;h<=cl.getContactHeight();h++)
+      ContactListI cl = cm.getContactList(c);
+      if (cl != null)
       {
-        if (sb.length()>0) {
-          sb.append('\t');
+        for (int h = 0; h <= cl.getContactHeight(); h++)
+        {
+          if (sb.length() > 0)
+          {
+            sb.append('\t');
+          }
+          sb.append(cl.getContactAt(h));
         }
-        sb.append(cl.getContactAt(h));
-      }
       }
     }
     return sb.toString();
@@ -244,29 +196,27 @@ public abstract class ContactMatrix implements ContactMatrixI
           int rows)
   {
     float[][] vals = new float[cols][rows];
-    StringTokenizer tabsep = new StringTokenizer(values,""+'\t');
-    int c=0,r=0;
-    
+    StringTokenizer tabsep = new StringTokenizer(values, "" + '\t');
+    int c = 0, r = 0;
     while (tabsep.hasMoreTokens())
     {
       double elem = Double.valueOf(tabsep.nextToken());
-      vals[c][r++]=(float) elem;
-      if (r>=vals[c].length)
+      vals[c][r++] = (float) elem;
+      if (r >= vals[c].length)
       {
-        r=0;
+        r = 0;
         c++;
       }
-      if (c>=vals.length)
+      if (c >= vals.length)
       {
-        
         break;
       }
     }
     if (tabsep.hasMoreElements())
     {
-      Console.warn("Ignoring additional elements for Float string to contact matrix parsing.");
+      Console.warn(
+              "Ignoring additional elements for Float string to contact matrix parsing.");
     }
-      
     return vals;
   }
 }
index 1c169ef..925025f 100644 (file)
@@ -5,6 +5,9 @@ import java.util.Arrays;
 import java.util.BitSet;
 import java.util.List;
 
+import jalview.util.ColorUtils;
+import jalview.ws.datamodel.MappableContactMatrixI;
+
 public interface ContactMatrixI
 {
 
@@ -14,63 +17,187 @@ public interface ContactMatrixI
 
   float getMax();
 
-  boolean hasReferenceSeq();
-
-  SequenceI getReferenceSeq();
-
   String getAnnotDescr();
 
   String getAnnotLabel();
 
   /**
-   * string indicating how the contactMatrix should be rendered - stored in calcId
-   * @return 
+   * string indicating how the contactMatrix should be rendered - stored in
+   * calcId
+   * 
+   * @return
    */
   String getType();
 
   int getWidth();
   int getHeight();
-  
-  default boolean hasGroups() {
-    return false;
+  public GroupSetI getGroupSet();
+
+  /// proxy methods to simplify use of the interface
+  /// Mappable contact matrices can override these to perform mapping
+
+  default public boolean hasGroupSet()
+  {
+    return getGroupSet() != null;
   }
-  default BitSet getGroupsFor(int column) {
-    BitSet colbitset  = new BitSet();
-    colbitset.set(column);
-    return colbitset;
+
+  default boolean hasGroups()
+  {
+    return hasGroupSet() && getGroupSet().hasGroups();
+  }
+
+  default BitSet getGroupsFor(int column)
+  {
+    if (!hasGroupSet())
+    {
+      BitSet colbitset = new BitSet();
+      colbitset.set(column);
+      return colbitset;
+    }
+    return getGroupSet().getGroupsFor(column);
   }
 
-  default List<BitSet> getGroups() {
-    return Arrays.asList();
+  default List<BitSet> getGroups()
+  {
+    if (!hasGroupSet())
+    {
+      return Arrays.asList();
+    }
+    return getGroupSet().getGroups();
   }
 
-  default boolean hasTree() {
-    return false;
+  default boolean hasTree()
+  {
+    return hasGroupSet() ? getGroupSet().hasTree() : false;
   }
 
   /**
    * Newick representation of clustered matrix
+   * 
    * @return null unless hasTree is true
    */
-  default String getNewick() {
-    return null;
+  default String getNewick()
+  {
+    return hasGroupSet() ? getGroupSet().getNewick() : null;
   }
 
-  default String getTreeMethod() {
-    return null;
+  default String getTreeMethod()
+  {
+    return hasGroupSet() ? getGroupSet().getTreeMethod() : null;
   }
 
-  default boolean hasCutHeight() {
-    return false;
+  default boolean hasCutHeight()
+  {
+    return hasGroupSet() ? getGroupSet().hasCutHeight() : false;
   }
 
-  default double getCutHeight() {
-    return 0;
+  default double getCutHeight()
+  {
+    return hasGroupSet() ? getGroupSet().getCutHeight() : 0;
   }
 
-  void updateGroups(List<BitSet> colGroups);
+  default void updateGroups(List<BitSet> colGroups)
+  {
+    if (hasGroupSet())
+    {
+      getGroupSet().updateGroups(colGroups);
+    }
+  }
 
-  void setColorForGroup(BitSet bs, Color color);
+  default void setColorForGroup(BitSet bs, Color color)
+  {
+    if (hasGroupSet())
+    {
+      getGroupSet().setColorForGroup(bs, color);
+    }
+  }
 
-  default Color getColourForGroup(BitSet bs) { return Color.white;};
+  default Color getColourForGroup(BitSet bs)
+  {
+    if (hasGroupSet())
+    {
+      return getGroupSet().getColourForGroup(bs);
+    }
+    else
+    {
+      return Color.white;
+    }
+  }
+
+  void setGroupSet(GroupSet makeGroups);
+
+  default void randomlyReColourGroups() {
+    if (hasGroupSet())
+    {
+      GroupSetI groups = getGroupSet();
+      for (BitSet group:groups.getGroups())
+      {
+        groups.setColorForGroup(group, ColorUtils.getARandomColor());
+      }
+    }
+  }
+
+  default void transferGroupColorsTo(AlignmentAnnotation aa)
+  {
+    if (hasGroupSet())
+    {
+      GroupSetI groups = getGroupSet();
+      // stash colors in linked annotation row.
+      // doesn't work yet. TESTS!
+      int sstart = aa.sequenceRef != null ? aa.sequenceRef.getStart() - 1
+              : 0;
+      Annotation ae;
+      Color gpcol = null;
+      int[] seqpos = null;
+      for (BitSet gp : groups.getGroups())
+      {
+        gpcol = groups.getColourForGroup(gp);
+        for (int p = gp.nextSetBit(0); p >= 0
+                && p < Integer.MAX_VALUE; p = gp.nextSetBit(p + 1))
+        {
+          if (this instanceof MappableContactMatrixI)
+          {
+            MappableContactMatrixI mcm = (MappableContactMatrixI) this;
+            seqpos = mcm.getMappedPositionsFor(aa.sequenceRef, p);
+            if (seqpos == null)
+            {
+              // no mapping for this column.
+              continue;
+            }
+            // TODO: handle ranges...
+            ae = aa.getAnnotationForPosition(seqpos[0]);
+          }
+          else
+          {
+            ae = aa.getAnnotationForPosition(p + sstart);
+          }
+          if (ae != null)
+          {
+            ae.colour = gpcol.brighter().darker();
+          }
+        }
+      }
+    }
+  }
+  
+  /**
+   * look up the colour for a column in the associated contact matrix 
+   * @return Color.white or assigned colour
+   */
+  default Color getGroupColorForPosition(int column)
+  {
+    if (hasGroupSet())
+    {
+      GroupSetI groups = getGroupSet();
+      for (BitSet gp:groups.getGroups())
+      {
+        if (gp.get(column))
+        {
+          return groups.getColourForGroup(gp);
+        }
+      }
+    }
+    return Color.white;
+  }
+  
 }
index 5de8b04..fe66aa5 100644 (file)
@@ -1,6 +1,5 @@
 package jalview.datamodel;
 
-
 /**
  * bean for max/min positions for a given range
  * 
@@ -31,8 +30,8 @@ public class ContactRange
    * @param maxPos
    * @param max
    */
-  public void update(int from_column, int to_column, int minPos,
-          double min, int maxPos, double max, double mean)
+  public void update(int from_column, int to_column, int minPos, double min,
+          int maxPos, double max, double mean)
   {
     this.from_column = from_column;
     this.to_column = to_column;
index f384b1e..3b1757b 100755 (executable)
@@ -154,6 +154,11 @@ public class DBRefSource
 
   public static boolean isPrimaryCandidate(String ucversion)
   {
+    if (ucversion==null)
+    {
+      // Null/empty version is not a real reference ?
+      return false;
+    }
     // tricky - this test really needs to search the sequence's set of dbrefs to
     // see if there is a primary reference that derived this reference.
     for (int i = allSources.length; --i >= 0;)
diff --git a/src/jalview/datamodel/GroupSet.java b/src/jalview/datamodel/GroupSet.java
new file mode 100644 (file)
index 0000000..db38e7b
--- /dev/null
@@ -0,0 +1,221 @@
+package jalview.datamodel;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.List;
+
+import jalview.analysis.AverageDistanceEngine;
+import jalview.bin.Console;
+
+public class GroupSet implements GroupSetI
+{
+  List<BitSet> groups = Arrays.asList();
+
+  public GroupSet(GroupSet grps)
+  {
+    abs = grps.abs;
+    colorMap = new HashMap<BitSet, Color>(grps.colorMap);
+    groups = new ArrayList<BitSet>(grps.groups);
+    newick = grps.newick;
+    thresh = grps.thresh;
+    treeType = grps.treeType;
+  }
+
+  public GroupSet()
+  {
+    // TODO Auto-generated constructor stub
+  }
+
+  public GroupSet(boolean abs2, float thresh2, List<BitSet> groups2,
+          String treeType2, String newick2)
+  {
+    abs = abs2;
+    thresh = thresh2;
+    groups = groups2;
+    treeType = treeType2;
+    newick = newick2;
+  }
+
+  @Override
+  public boolean hasGroups()
+  {
+    return groups != null;
+  }
+
+  String newick = null;
+
+  @Override
+  public String getNewick()
+  {
+    return newick;
+  }
+
+  @Override
+  public boolean hasTree()
+  {
+    return newick != null && newick.length() > 0;
+  }
+
+  boolean abs = false;
+
+  double thresh = 0;
+
+  String treeType = null;
+
+  @Override
+  public void updateGroups(List<BitSet> colGroups)
+  {
+    if (colGroups != null)
+    {
+      groups = colGroups;
+    }
+  }
+
+  @Override
+  public BitSet getGroupsFor(int column)
+  {
+    if (groups != null)
+    {
+      for (BitSet gp : groups)
+      {
+        if (gp.get(column))
+        {
+          return gp;
+        }
+      }
+    }
+    // return singleton set;
+    BitSet bs = new BitSet();
+    bs.set(column);
+    return bs;
+  }
+
+  HashMap<BitSet, Color> colorMap = new HashMap<>();
+
+  @Override
+  public Color getColourForGroup(BitSet bs)
+  {
+    if (bs == null)
+    {
+      return Color.white;
+    }
+    Color groupCol = colorMap.get(bs);
+    if (groupCol == null)
+    {
+      return Color.white;
+    }
+    return groupCol;
+  }
+
+  @Override
+  public void setColorForGroup(BitSet bs, Color color)
+  {
+    colorMap.put(bs, color);
+  }
+
+  @Override
+  public void restoreGroups(List<BitSet> newgroups, String treeMethod,
+          String tree, double thresh2)
+  {
+    treeType = treeMethod;
+    groups = newgroups;
+    thresh = thresh2;
+    newick = tree;
+
+  }
+
+  @Override
+  public boolean hasCutHeight()
+  {
+    return groups != null && thresh != 0;
+  }
+
+  @Override
+  public double getCutHeight()
+  {
+    return thresh;
+  }
+
+  @Override
+  public String getTreeMethod()
+  {
+    return treeType;
+  }
+
+  public static GroupSet makeGroups(ContactMatrixI matrix, boolean autoCut)
+  {
+    return makeGroups(matrix, autoCut, 0, autoCut);
+  }
+  public static GroupSet makeGroups(ContactMatrixI matrix, boolean auto, float thresh,
+          boolean abs)
+  {
+    AverageDistanceEngine clusterer = new AverageDistanceEngine(null, null,
+            matrix, true);
+    double height = clusterer.findHeight(clusterer.getTopNode());
+    Console.debug("Column tree height: " + height);
+    String newick = new jalview.io.NewickFile(clusterer.getTopNode(), false,
+            true).print();
+    String treeType = "UPGMA";
+    Console.trace("Newick string\n" + newick);
+
+    List<BinaryNode> nodegroups;
+    float cut = -1f;
+    if (auto)
+    {
+      double rootw = 0;
+      int p = 2;
+      BinaryNode bn = clusterer.getTopNode();
+      while (p-- > 0 & bn.left() != null)
+      {
+        if (bn.left() != null)
+        {
+          bn = bn.left();
+        }
+        if (bn.left() != null)
+        {
+          rootw = bn.height;
+        }
+      }
+      thresh = Math.max((float) (rootw / height) - 0.01f, 0);
+      cut = thresh;
+      nodegroups = clusterer.groupNodes(thresh);
+    }
+    else
+    {
+      if (abs ? (height > thresh) : (0 < thresh && thresh < 1))
+      {
+        cut = abs ? thresh : (float) (thresh * height);
+        Console.debug("Threshold " + cut + " for height=" + height);
+        nodegroups = clusterer.groupNodes(cut);
+      }
+      else
+      {
+        nodegroups = new ArrayList<BinaryNode>();
+        nodegroups.add(clusterer.getTopNode());
+      }
+    }
+    
+    List<BitSet> groups = new ArrayList<>();
+    for (BinaryNode root : nodegroups)
+    {
+      BitSet gpset = new BitSet();
+      for (BinaryNode leaf : clusterer.findLeaves(root))
+      {
+        gpset.set((Integer) leaf.element());
+      }
+      groups.add(gpset);
+    }
+    GroupSet grps = new GroupSet(abs, (cut == -1f) ? thresh : cut, groups,
+            treeType, newick);
+    return grps;
+  }
+
+  @Override
+  public List<BitSet> getGroups()
+  {
+    return groups;
+  }
+}
diff --git a/src/jalview/datamodel/GroupSetI.java b/src/jalview/datamodel/GroupSetI.java
new file mode 100644 (file)
index 0000000..7c086a5
--- /dev/null
@@ -0,0 +1,34 @@
+package jalview.datamodel;
+
+import java.awt.Color;
+import java.util.BitSet;
+import java.util.List;
+
+public interface GroupSetI
+{
+  boolean hasGroups();
+
+  String getNewick();
+
+  boolean hasTree();
+
+  void updateGroups(List<BitSet> colGroups);
+
+  BitSet getGroupsFor(int column);
+
+  Color getColourForGroup(BitSet bs);
+
+  void setColorForGroup(BitSet bs, Color color);
+
+  void restoreGroups(List<BitSet> newgroups, String treeMethod, String tree,
+          double thresh2);
+
+  boolean hasCutHeight();
+
+  double getCutHeight();
+
+  String getTreeMethod();
+
+  List<BitSet> getGroups();
+
+}
index b5efeb4..e2ef318 100755 (executable)
@@ -159,7 +159,7 @@ public class HiddenSequences
 
     if (alignmentIndex < 0 || hiddenSequences[alignmentIndex] != null)
     {
-      System.out.println("ERROR!!!!!!!!!!!");
+      jalview.bin.Console.outPrintln("ERROR!!!!!!!!!!!");
       return;
     }
 
@@ -239,7 +239,7 @@ public class HiddenSequences
           }
           else
           {
-            System.out.println(
+            jalview.bin.Console.outPrintln(
                     seq.getName() + " has been deleted whilst hidden");
           }
         }
index 909a0fe..8d6cbb1 100755 (executable)
@@ -269,7 +269,7 @@ public class SearchResults implements SearchResultsI
         else
         {
           // debug
-          // System.err.println("Outwith bounds!" + matchStart+">"+end +" or "
+          // jalview.bin.Console.errPrintln("Outwith bounds!" + matchStart+">"+end +" or "
           // + matchEnd+"<"+start);
         }
       }
index c3f3670..f8fd750 100644 (file)
@@ -5,13 +5,17 @@ import java.util.BitSet;
 import java.util.HashMap;
 import java.util.List;
 
+import jalview.util.MapList;
+import jalview.ws.datamodel.alphafold.MappableContactMatrix;
 /**
  * Dummy contact matrix based on sequence distance
  * 
  * @author jprocter
  *
  */
-public class SeqDistanceContactMatrix implements ContactMatrixI
+public class SeqDistanceContactMatrix
+        extends MappableContactMatrix<SeqDistanceContactMatrix>
+        implements ContactMatrixI
 {
   private static final String SEQUENCE_DISTANCE = "SEQUENCE_DISTANCE";
   private int width = 0;
@@ -81,20 +85,6 @@ public class SeqDistanceContactMatrix implements ContactMatrixI
   }
 
   @Override
-  public boolean hasReferenceSeq()
-  {
-    // TODO Auto-generated method stub
-    return false;
-  }
-
-  @Override
-  public SequenceI getReferenceSeq()
-  {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
   public String getAnnotDescr()
   {
     return "Sequence distance matrix";
@@ -123,40 +113,16 @@ public class SeqDistanceContactMatrix implements ContactMatrixI
   {
     return width;
   }
-  private List<BitSet> groups=null;
   @Override
-  public void updateGroups(List<BitSet> colGroups)
+  protected double getElementAt(int _column, int i)
   {
-    groups = colGroups;
+    return Math.abs(_column - i);
   }
   @Override
-  public boolean hasGroups()
+  protected SeqDistanceContactMatrix newMappableContactMatrix(
+          SequenceI newRefSeq, MapList newFromMapList)
   {
-    return groups!=null;
-  }
-  @Override
-  public List<BitSet> getGroups()
-  {
-    return groups;
-  }  
 
-  HashMap<BitSet,Color> colorMap = new HashMap<>();
-  @Override 
-  public Color getColourForGroup(BitSet bs)
-  {
-    if (bs==null) {
-      return Color.white;
-    }
-    Color groupCol=colorMap.get(bs);
-    if (groupCol==null)
-    {
-      return Color.white;
-    }
-    return groupCol;
-  }
-  @Override 
-  public void setColorForGroup(BitSet bs,Color color)
-  {
-    colorMap.put(bs,color);
+    return new SeqDistanceContactMatrix(width);
   }
 }
index 5ae7195..7a5d5bc 100755 (executable)
@@ -33,12 +33,15 @@ import java.util.Vector;
 
 import fr.orsay.lri.varna.models.rna.RNA;
 import jalview.analysis.AlignSeq;
+import jalview.analysis.AlignmentUtils;
+import jalview.analysis.SeqsetUtils;
 import jalview.datamodel.features.SequenceFeatures;
 import jalview.datamodel.features.SequenceFeaturesI;
 import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.MapList;
 import jalview.util.StringUtils;
+import jalview.ws.datamodel.alphafold.MappableContactMatrix;
 
 /**
  * 
@@ -171,7 +174,7 @@ public class Sequence extends ASequence implements SequenceI
   {
     if (name == null)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "POSSIBLE IMPLEMENTATION ERROR: null sequence name passed to constructor.");
       name = "";
     }
@@ -349,6 +352,11 @@ public class Sequence extends ASequence implements SequenceI
         {
           // only copy the given annotation
           AlignmentAnnotation newann = new AlignmentAnnotation(sqann[i]);
+          ContactMatrixI cm = seq.getContactMatrixFor(sqann[i]);
+          if (cm!=null)
+          {
+            addContactListFor(newann, cm);
+          }
           addAlignmentAnnotation(newann);
         }
       }
@@ -379,7 +387,7 @@ public class Sequence extends ASequence implements SequenceI
   {
     if (sf.getType() == null)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "SequenceFeature type may not be null: " + sf.toString());
       return false;
     }
@@ -1626,14 +1634,19 @@ public class Sequence extends ASequence implements SequenceI
                                     // sequence-column mapping
           datasetSequence.addAlignmentAnnotation(_aa);
 
-          // transfer contact matrices
-          ContactMatrixI cm = getContactMatrixFor(aa);
-          if (cm != null)
-          {
-            datasetSequence.addContactListFor(_aa, cm);
+          if (_cmholder != null)
+          { // transfer contact matrices
+            ContactMatrixI cm = _cmholder.getContactMatrixFor(aa);
+            if (cm != null)
+            {
+              datasetSequence.addContactListFor(_aa, cm);
+              datasetSequence.addContactListFor(aa, cm);
+            }
           }
         }
       }
+      // all matrices should have been transferred. so we clear the local holder
+      _cmholder=null;
     }
     return datasetSequence;
   }
@@ -1741,6 +1754,13 @@ public class Sequence extends ASequence implements SequenceI
       transferAnnotation(entry.getDatasetSequence(), mp);
       return;
     }
+    // transfer from entry to sequence
+    // if entry has a description and sequence doesn't, then transfer
+    if (entry.getDescription()!=null && (description==null || description.trim().length()==0))
+    {
+      description = entry.getDescription();
+    }
+    
     // transfer any new features from entry onto sequence
     if (entry.getSequenceFeatures() != null)
     {
@@ -2118,39 +2138,70 @@ public class Sequence extends ASequence implements SequenceI
   ////
   //// Contact Matrix Holder Boilerplate
   ////
-  ContactMapHolderI cmholder = new ContactMapHolder();
+  ContactMapHolderI _cmholder = null;
 
+  private ContactMapHolderI getContactMapHolder()
+  {
+    if (datasetSequence!=null) {
+      return ((Sequence)datasetSequence).getContactMapHolder();
+    }
+    if (_cmholder==null)
+    {
+      _cmholder=new ContactMapHolder();
+    }
+    return _cmholder;
+  }
   @Override
   public Collection<ContactMatrixI> getContactMaps()
   {
-    return cmholder.getContactMaps();
+    return getContactMapHolder().getContactMaps();
   }
 
   @Override
   public ContactMatrixI getContactMatrixFor(AlignmentAnnotation ann)
   {
-    return cmholder.getContactMatrixFor(ann);
+    return getContactMapHolder().getContactMatrixFor(ann);
   }
 
   @Override
   public ContactListI getContactListFor(AlignmentAnnotation _aa, int column)
   {
-    return cmholder.getContactListFor(_aa, column);
+    return getContactMapHolder().getContactListFor(_aa, column);
   }
 
   @Override
   public AlignmentAnnotation addContactList(ContactMatrixI cm)
   {
-    AlignmentAnnotation aa = cmholder.addContactList(cm);
+    AlignmentAnnotation aa;
+    
+    if (datasetSequence != null)
+    {
+      aa = datasetSequence.addContactList(cm);
+      // clone the annotation for the local sequence
+      aa = new AlignmentAnnotation(aa);
+      aa.restrict(start, end);
+      aa.adjustForAlignment();
+      getContactMapHolder().addContactListFor(aa,cm);
+      addAlignmentAnnotation(aa);
+      return aa;
+    }
+    
+    // construct new annotation for matrix on dataset sequence
+    aa = getContactMapHolder().addContactList(cm);
 
     Annotation _aa[] = new Annotation[getLength()];
-    Annotation dummy = new Annotation(0.0f);
-    for (int i = 0; i < _aa.length; _aa[i++] = dummy)
+
+    for (int i = 0; i < _aa.length; _aa[i++] = new Annotation(0.0f))
     {
       ;
     }
     aa.annotations = _aa;
     aa.setSequenceRef(this);
+    if (cm instanceof MappableContactMatrix
+            && !((MappableContactMatrix) cm).hasReferenceSeq())
+    {
+      ((MappableContactMatrix) cm).setRefSeq(this);
+    }
     aa.createSequenceMapping(this, getStart(), false);
     addAlignmentAnnotation(aa);
     return aa;
@@ -2160,6 +2211,6 @@ public class Sequence extends ASequence implements SequenceI
   public void addContactListFor(AlignmentAnnotation annotation,
           ContactMatrixI cm)
   {
-    cmholder.addContactListFor(annotation, cm);
+    getContactMapHolder().addContactListFor(annotation, cm);
   }
 }
index b356894..9837104 100755 (executable)
@@ -274,14 +274,6 @@ public class SequenceGroup implements AnnotatedCollectionI
               endRes + 1);
       if (seqipos != null)
       {
-        seqipos.setDescription(seq.getDescription());
-        seqipos.setDBRefs(seq.getDBRefs());
-        seqipos.setSequenceFeatures(seq.getSequenceFeatures());
-        if (seq.getDatasetSequence() != null)
-        {
-          seqipos.setDatasetSequence(seq.getDatasetSequence());
-        }
-
         if (seq.getAnnotation() != null)
         {
           AlignmentAnnotation[] alann = align.getAlignmentAnnotation();
@@ -311,6 +303,11 @@ public class SequenceGroup implements AnnotatedCollectionI
             newannot.restrict(startRes, endRes);
             newannot.setSequenceRef(seqs[ipos]);
             newannot.adjustForAlignment();
+            ContactMatrixI cm = seq.getContactMatrixFor(seq.getAnnotation()[a]);
+            if (cm!=null)
+            {
+              seqs[ipos].addContactListFor(newannot, cm);
+            }
             seqipos.addAlignmentAnnotation(newannot);
           }
         }
@@ -647,7 +644,7 @@ public class SequenceGroup implements AnnotatedCollectionI
     } catch (java.lang.OutOfMemoryError err)
     {
       // TODO: catch OOM
-      System.out.println("Out of memory loading groups: " + err);
+      jalview.bin.Console.outPrintln("Out of memory loading groups: " + err);
     }
     return upd;
   }
index c789857..2e1daa3 100755 (executable)
@@ -415,7 +415,7 @@ public interface SequenceI extends ASequenceI, ContactMapHolderI
   /**
    * Derive a sequence (using this one's dataset or as the dataset)
    * 
-   * @return duplicate sequence with valid dataset sequence
+   * @return duplicate sequence and any annotation present with valid dataset sequence
    */
   public SequenceI deriveSequence();
 
index 010d4aa..9d00fa5 100755 (executable)
@@ -26,7 +26,7 @@ package jalview.datamodel;
  * @author $author$
  * @version $Revision$
  */
-public class SequenceNode extends BinaryNode
+public class SequenceNode extends BinaryNode<SequenceI>
 {
   private boolean placeholder = false;
 
@@ -38,20 +38,20 @@ public class SequenceNode extends BinaryNode
     super();
   }
 
-  public SequenceNode(SequenceI val, BinaryNode parent, String name,
-          double dist, int bootstrap, boolean dummy)
+  public SequenceNode(SequenceI val, BinaryNode<SequenceI> parent,
+          String name, double dist, int bootstrap, boolean dummy)
   {
     super(val, parent, name, dist, bootstrap, dummy);
   }
 
-  public SequenceNode(SequenceI element, BinaryNode parent, String name,
-          double dist, int bootstrap)
+  public SequenceNode(SequenceI element, BinaryNode<SequenceI> parent,
+          String name, double dist, int bootstrap)
   {
     super(element, parent, name, dist, bootstrap);
   }
 
-  public SequenceNode(SequenceI element, BinaryNode parent, String name,
-          double dist)
+  public SequenceNode(SequenceI element, BinaryNode<SequenceI> parent,
+          String name, double dist)
   {
     super(element, parent, name, dist);
   }
index b3d567a..c7e4549 100644 (file)
@@ -1,7 +1,6 @@
 package jalview.datamodel.annotations;
 
 import jalview.datamodel.Annotation;
-import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureImportSettings.TFType;
 
 public class AnnotationRowBuilder
@@ -18,14 +17,15 @@ public class AnnotationRowBuilder
   /**
    * the type of temperature factor plot (if it is one)
    */
-  private StructureImportSettings.TFType tfType = StructureImportSettings.TFType.DEFAULT;
+  // private TFType tfType = TFType.DEFAULT;
+  private TFType tfType = null;
 
-  public void setTFType(StructureImportSettings.TFType t)
+  public void setTFType(TFType t)
   {
     tfType = t;
   }
 
-  public StructureImportSettings.TFType getTFType()
+  public TFType getTFType()
   {
     return tfType;
   }
@@ -97,7 +97,7 @@ public class AnnotationRowBuilder
     name = string;
   }
 
-  public AnnotationRowBuilder(String name, float min, float max, StructureImportSettings.TFType tft)
+  public AnnotationRowBuilder(String name, float min, float max, TFType tft)
   {
     this(name, min, max);
     setTFType(tft);
index 65cba0d..124909c 100644 (file)
@@ -147,7 +147,7 @@ public class FeatureMatcher implements FeatureMatcherI
       int nextQuotePos = descriptor.indexOf(QUOTE, 1);
       if (nextQuotePos == -1)
       {
-        System.err.println(invalidFormat);
+        jalview.bin.Console.errPrintln(invalidFormat);
         return null;
       }
       firstField = descriptor.substring(1, nextQuotePos);
@@ -159,7 +159,7 @@ public class FeatureMatcher implements FeatureMatcherI
       int nextSpacePos = descriptor.indexOf(SPACE);
       if (nextSpacePos == -1)
       {
-        System.err.println(invalidFormat);
+        jalview.bin.Console.errPrintln(invalidFormat);
         return null;
       }
       firstField = descriptor.substring(0, nextSpacePos);
@@ -193,7 +193,7 @@ public class FeatureMatcher implements FeatureMatcherI
       cond = Condition.fromString(leftToParse);
       if (cond == null || cond.needsAPattern())
       {
-        System.err.println(invalidFormat);
+        jalview.bin.Console.errPrintln(invalidFormat);
         return null;
       }
     }
@@ -214,7 +214,7 @@ public class FeatureMatcher implements FeatureMatcherI
         else
         {
           // unbalanced quote
-          System.err.println(invalidFormat);
+          jalview.bin.Console.errPrintln(invalidFormat);
           return null;
         }
       }
index a5efe5d..eae3664 100644 (file)
@@ -93,7 +93,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI
         if (spacePos == -1)
         {
           // trailing junk after a match condition
-          System.err.println(invalid);
+          jalview.bin.Console.errPrintln(invalid);
           return null;
         }
         String conjunction = leftToParse.substring(0, spacePos);
@@ -109,7 +109,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI
         else
         {
           // not an AND or an OR - invalid
-          System.err.println(invalid);
+          jalview.bin.Console.errPrintln(invalid);
           return null;
         }
       }
@@ -123,7 +123,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI
         int closePos = leftToParse.indexOf(CLOSE_BRACKET);
         if (closePos == -1)
         {
-          System.err.println(invalid);
+          jalview.bin.Console.errPrintln(invalid);
           return null;
         }
         nextCondition = leftToParse.substring(1, closePos);
@@ -137,7 +137,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI
       FeatureMatcher fm = FeatureMatcher.fromString(nextCondition);
       if (fm == null)
       {
-        System.err.println(invalid);
+        jalview.bin.Console.errPrintln(invalid);
         return null;
       }
       try
@@ -154,7 +154,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI
       } catch (IllegalStateException e)
       {
         // thrown if OR and AND are mixed
-        System.err.println(invalid);
+        jalview.bin.Console.errPrintln(invalid);
         return null;
       }
 
index eb5688c..c19d782 100644 (file)
@@ -401,7 +401,7 @@ public class FeatureStore
       SequenceFeature sf = contactFeatureEnds.get(index);
       if (!sf.isContactFeature())
       {
-        System.err.println("Error! non-contact feature type " + sf.getType()
+        jalview.bin.Console.errPrintln("Error! non-contact feature type " + sf.getType()
                 + " in contact features list");
         index++;
         continue;
@@ -454,7 +454,7 @@ public class FeatureStore
       SequenceFeature sf = contactFeatureStarts.get(index);
       if (!sf.isContactFeature())
       {
-        System.err.println("Error! non-contact feature " + sf.toString()
+        jalview.bin.Console.errPrintln("Error! non-contact feature " + sf.toString()
                 + " in contact features list");
         index++;
         continue;
index 905fd8b..ed4474e 100644 (file)
@@ -88,7 +88,7 @@ public class SequenceFeatures implements SequenceFeaturesI
     String type = sf.getType();
     if (type == null)
     {
-      System.err.println("Feature type may not be null: " + sf.toString());
+      jalview.bin.Console.errPrintln("Feature type may not be null: " + sf.toString());
       return false;
     }
 
index 75a7154..391fd6f 100644 (file)
@@ -226,7 +226,7 @@ public class EnsemblGene extends EnsemblSeqProxy
         return true;
       } catch (NumberFormatException e)
       {
-        System.err.println("Bad integers in description " + description);
+        jalview.bin.Console.errPrintln("Bad integers in description " + description);
       }
     }
     return false;
index 0813ba8..e188986 100644 (file)
@@ -222,7 +222,7 @@ public class EnsemblLookup extends EnsemblRestClient
               ids, -1, MODE_MAP, null);
     } catch (IOException | ParseException e)
     {
-      System.err.println("Error parsing " + identifier + " lookup response "
+      jalview.bin.Console.errPrintln("Error parsing " + identifier + " lookup response "
               + e.getMessage());
       return null;
     }
index f2ab195..1fd9a23 100644 (file)
@@ -157,7 +157,7 @@ public class EnsemblMap extends EnsemblRestClient
       return (parseAssemblyMappingResponse(url));
     } catch (Throwable t)
     {
-      System.out.println("Error calling " + url + ": " + t.getMessage());
+      jalview.bin.Console.outPrintln("Error calling " + url + ": " + t.getMessage());
       return null;
     }
   }
@@ -265,7 +265,7 @@ public class EnsemblMap extends EnsemblRestClient
       return null;
     } catch (Throwable t)
     {
-      System.out.println("Error calling " + url + ": " + t.getMessage());
+      jalview.bin.Console.outPrintln("Error calling " + url + ": " + t.getMessage());
       return null;
     }
   }
@@ -342,7 +342,7 @@ public class EnsemblMap extends EnsemblRestClient
         String ass = mapped.get("assembly_name").toString();
         if (assembly != null && !assembly.equals(ass))
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "EnsemblMap found multiple assemblies - can't resolve");
           return null;
         }
@@ -350,7 +350,7 @@ public class EnsemblMap extends EnsemblRestClient
         String chr = mapped.get("seq_region_name").toString();
         if (chromosome != null && !chromosome.equals(chr))
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "EnsemblMap found multiple chromosomes - can't resolve");
           return null;
         }
index 4a5544e..540fc98 100644 (file)
@@ -211,7 +211,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
       return pingString != null;
     } catch (Throwable t)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error connecting to " + pingUrl + ": " + t.getMessage());
     } finally
     {
@@ -313,7 +313,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
        * note: a GET request for an invalid id returns an error code e.g. 415
        * but POST request returns 200 and an empty Fasta response 
        */
-      System.err.println("Response code " + responseCode);// + " for " + url);
+      jalview.bin.Console.errPrintln("Response code " + responseCode);// + " for " + url);
       return null;
     }
 
@@ -338,7 +338,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
   protected HttpURLConnection tryConnection(URL url, List<String> ids,
           int readTimeout) throws IOException, ProtocolException
   {
-    // System.out.println(System.currentTimeMillis() + " " + url);
+    // jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url);
 
     HttpURLConnection connection = (HttpURLConnection) url.openConnection();
 
@@ -387,14 +387,14 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
         int retrySecs = Integer.valueOf(retryDelay);
         if (retrySecs > 0 && retrySecs < 10)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Ensembl REST service rate limit exceeded, waiting "
                           + retryDelay + " seconds before retrying");
           Thread.sleep(1000 * retrySecs);
         }
       } catch (NumberFormatException | InterruptedException e)
       {
-        System.err.println("Error handling Retry-After: " + e.getMessage());
+        jalview.bin.Console.errPrintln("Error handling Retry-After: " + e.getMessage());
       }
     }
   }
@@ -566,7 +566,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
         }
       } catch (NumberFormatException e)
       {
-        System.err.println("Error in REST version: " + e.toString());
+        jalview.bin.Console.errPrintln("Error in REST version: " + e.toString());
       }
 
       /*
@@ -578,14 +578,14 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
               expected) == 1;
       if (laterVersion)
       {
-        System.err.println(String.format(
+        jalview.bin.Console.errPrintln(String.format(
                 "EnsemblRestClient expected %s REST version %s but found %s, see %s",
                 getDbSource(), expected, version, REST_CHANGE_LOG));
       }
       info.restVersion = version;
     } catch (Throwable t)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error checking Ensembl REST version: " + t.getMessage());
     }
   }
@@ -617,7 +617,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
       domainData.get(getDomain()).dataVersion = versions.get(0).toString();
     } catch (Throwable e)
     {// could be IOException | ParseException e) {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error checking Ensembl data version: " + e.getMessage());
     }
   }
index 56eda5e..949c52e 100644 (file)
@@ -155,7 +155,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
         String msg = "Aborting ID retrieval after " + v
                 + " chunks. Unexpected problem (" + r.getLocalizedMessage()
                 + ")";
-        System.err.println(msg);
+        jalview.bin.Console.errPrintln(msg);
         r.printStackTrace();
         break;
       }
@@ -240,7 +240,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
       }
     } catch (IOException e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error transferring Ensembl features: " + e.getMessage());
     }
     // Platform.timeCheck("ESP.addfeat done", Platform.TIME_MARK);
@@ -265,12 +265,12 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
     String accId = querySeq.getName();
     try
     {
-      System.out.println("Adding protein product for " + accId);
+      jalview.bin.Console.outPrintln("Adding protein product for " + accId);
       AlignmentI protein = new EnsemblProtein(getDomain())
               .getSequenceRecords(accId);
       if (protein == null || protein.getHeight() == 0)
       {
-        System.out.println("No protein product found for " + accId);
+        jalview.bin.Console.outPrintln("No protein product found for " + accId);
         return;
       }
       SequenceI proteinSeq = protein.getSequenceAt(0);
@@ -382,7 +382,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
       seq.addDBRef(xrefs.get(i));
     }
 
-    // System.out.println("primaries are " + seq.getPrimaryDBRefs().toString());
+    // jalview.bin.Console.outPrintln("primaries are " + seq.getPrimaryDBRefs().toString());
     /*
      * and add a reference to itself
      */
@@ -430,7 +430,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
 
     if (seqs.size() != ids.size())
     {
-      System.out.println(String.format(
+      jalview.bin.Console.outPrintln(String.format(
               "Only retrieved %d sequences for %d query strings",
               seqs.size(), ids.size()));
     }
@@ -508,7 +508,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
       result.add(sequence);
     } catch (ParseException | IOException e)
     {
-      System.err.println("Error processing JSON response: " + e.toString());
+      jalview.bin.Console.errPrintln("Error processing JSON response: " + e.toString());
       // ignore
     }
     // Platform.timeCheck("ENS seqproxy2", Platform.TIME_MARK);
@@ -659,7 +659,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
 
     if (regions.isEmpty())
     {
-      System.out.println("Failed to identify target sequence for " + accId
+      jalview.bin.Console.outPrintln("Failed to identify target sequence for " + accId
               + " from genomic features");
       return null;
     }
@@ -829,7 +829,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
 
     boolean result = transferFeatures(sfs, targetSequence, mapping,
             accessionId);
-    // System.out.println("transferFeatures (" + (sfs.size()) + " --> "
+    // jalview.bin.Console.outPrintln("transferFeatures (" + (sfs.size()) + " --> "
     // + targetSequence.getFeatures().getFeatureCount(true) + ") to "
     // + targetSequence.getName() + " took "
     // + (System.currentTimeMillis() - start) + "ms");
index 9a985b6..8cce87a 100644 (file)
@@ -261,7 +261,7 @@ public class HtsContigDb
   {
     if (!isValid() || !refFile.isIndexed())
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Cannot read contig as file is invalid or not indexed");
       return null;
     }
index 21a19ae..870db65 100644 (file)
@@ -163,21 +163,21 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
 
   public void createImage(String file, String type, int quality)
   {
-    System.out.println("JMOL CREATE IMAGE");
+    jalview.bin.Console.outPrintln("JMOL CREATE IMAGE");
   }
 
   @Override
   public String createImage(String fileName, String type,
           Object textOrBytes, int quality)
   {
-    System.out.println("JMOL CREATE IMAGE");
+    jalview.bin.Console.outPrintln("JMOL CREATE IMAGE");
     return null;
   }
 
   @Override
   public String eval(String strEval)
   {
-    // System.out.println(strEval);
+    // jalview.bin.Console.outPrintln(strEval);
     // "# 'eval' is implemented only for the applet.";
     return null;
   }
@@ -476,7 +476,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     lastMessage = strInfo;
     if (data != null)
     {
-      System.err.println("Ignoring additional hover info: " + data
+      jalview.bin.Console.errPrintln("Ignoring additional hover info: " + data
               + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
     }
     mouseOverStructure(atomIndex, strInfo);
@@ -497,7 +497,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
      */
     if (strData != null)
     {
-      System.err.println("Ignoring additional pick data string " + strData);
+      jalview.bin.Console.errPrintln("Ignoring additional pick data string " + strData);
     }
     int chainSeparator = strInfo.indexOf(":");
     int p = 0;
@@ -599,7 +599,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
                 (data == null) ? ((String) null) : (String) data[1]);
         break;
       case ERROR:
-        // System.err.println("Ignoring error callback.");
+        // jalview.bin.Console.errPrintln("Ignoring error callback.");
         break;
       case SYNC:
       case RESIZE:
@@ -609,13 +609,13 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
 
       case CLICK:
       default:
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Unhandled callback " + type + " " + data[1].toString());
         break;
       }
     } catch (Exception e)
     {
-      System.err.println("Squashed Jmol callback handler error:");
+      jalview.bin.Console.errPrintln("Squashed Jmol callback handler error:");
       e.printStackTrace();
     }
   }
@@ -864,7 +864,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   public void setCallbackFunction(String callbackType,
           String callbackFunction)
   {
-    System.err.println("Ignoring set-callback request to associate "
+    jalview.bin.Console.errPrintln("Ignoring set-callback request to associate "
             + callbackType + " with function " + callbackFunction);
 
   }
@@ -938,7 +938,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
           String buttonsToShow)
   {
 
-    System.err.println("Allocating Jmol Viewer: " + commandOptions);
+    jalview.bin.Console.errPrintln("Allocating Jmol Viewer: " + commandOptions);
 
     if (commandOptions == null)
     {
@@ -956,7 +956,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       console = createJmolConsole(consolePanel, buttonsToShow);
     } catch (Throwable e)
     {
-      System.err.println("Could not create Jmol application console. "
+      jalview.bin.Console.errPrintln("Could not create Jmol application console. "
               + e.getMessage());
       e.printStackTrace();
     }
index f0e477c..0ca2ba8 100644 (file)
@@ -88,6 +88,10 @@ public class JmolParser extends StructureFile implements JmolStatusListener
     super(inFile, sourceType, tempfacType);
   }
 
+  public JmolParser(FileParse fp, boolean doXferSettings) throws IOException
+  {
+    super(fp, doXferSettings);
+  }
   public JmolParser(FileParse fp) throws IOException
   {
     super(fp);
@@ -108,6 +112,12 @@ public class JmolParser extends StructureFile implements JmolStatusListener
   @Override
   public void parse() throws IOException
   {
+    parse(true);
+  }
+
+  @Override
+  public void parse(boolean doXferSettings) throws IOException
+  {
     setChains(new Vector<PDBChain>());
     Viewer jmolModel = getJmolData();
     jmolModel.openReader(getDataName(), getDataName(), getReader());
@@ -132,7 +142,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
                       ? PDBEntry.Type.MMCIF.toString()
                       : "PDB");
 
-      transformJmolModelToJalview(jmolModel.ms);
+      transformJmolModelToJalview(jmolModel.ms, doXferSettings);
     }
   }
 
@@ -202,7 +212,8 @@ public class JmolParser extends StructureFile implements JmolStatusListener
     return false;
   }
 
-  public void transformJmolModelToJalview(ModelSet ms) throws IOException
+  public void transformJmolModelToJalview(ModelSet ms,
+          boolean localDoXferSettings) throws IOException
   {
     try
     {
@@ -260,7 +271,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
         }
         lastID = tmpatom.resNumIns.trim();
       }
-      if (isParseImmediately())
+      if (isParseImmediately() && localDoXferSettings)
       {
         // configure parsing settings from the static singleton
         xferSettings();
@@ -292,7 +303,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
       {
         try
         {
-          Console.info("retrieving pAE for " + pdbId);
+          Console.info("Retrieving PAE for " + pdbId);
           File paeFile = EBIAlfaFold.fetchAlphaFoldPAE(pdbId, null);
           this.setPAEMatrix(paeFile.getAbsolutePath());
         } catch (Throwable t)
@@ -303,21 +314,31 @@ public class JmolParser extends StructureFile implements JmolStatusListener
       // add a PAEMatrix if set (either by above or otherwise)
       if (hasPAEMatrix())
       {
-        Alignment al = new Alignment(prot.toArray(new SequenceI[0]));
-        EBIAlfaFold.addAlphaFoldPAE(al, new File(this.getPAEMatrix()), 0,
-                null, false, false);
-
-        if (al.getAlignmentAnnotation() != null)
+        try
         {
-          for (AlignmentAnnotation alann : al.getAlignmentAnnotation())
+          Alignment al = new Alignment(prot.toArray(new SequenceI[0]));
+          EBIAlfaFold.addAlphaFoldPAE(al, new File(this.getPAEMatrix()), 0,
+                  null, false, false, null);
+
+          if (al.getAlignmentAnnotation() != null)
           {
-            annotations.add(alann);
+            for (AlignmentAnnotation alann : al.getAlignmentAnnotation())
+            {
+              annotations.add(alann);
+            }
           }
+        } catch (Throwable ff)
+        {
+          Console.error("Couldn't import PAE Matrix from " + getPAEMatrix(),
+                  ff);
+          warningMessage += "Couldn't import PAE Matrix"
+                  + getNewlineString() + ff.getLocalizedMessage()
+                  + getNewlineString();
         }
       }
     } catch (OutOfMemoryError er)
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "OUT OF MEMORY LOADING TRANSFORMING JMOL MODEL TO JALVIEW MODEL");
       throw new IOException(MessageManager
               .getString("exception.outofmemory_loading_mmcif_file"));
@@ -370,7 +391,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
           org.jmol.modelset.Atom prevAtom,
           HashMap<String, org.jmol.modelset.Atom> chainTerMap)
   {
-    // System.out.println("Atom: " + curAtom.getAtomNumber()
+    // jalview.bin.Console.outPrintln("Atom: " + curAtom.getAtomNumber()
     // + " Last atom index " + curAtom.group.lastAtomIndex);
     if (chainTerMap == null || prevAtom == null)
     {
@@ -467,7 +488,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
   {
     int length = sq.getLength();
     boolean ssFound = false;
-    Annotation asecstr[] = new Annotation[length + firstResNum - 1];
+    Annotation asecstr[] = new Annotation[length + (firstResNum-sq.getStart())];
     for (int p = 0; p < length; p++)
     {
       if (secstr[p] >= 'A' && secstr[p] <= 'z')
index de1d90c..3817ee9 100644 (file)
@@ -229,7 +229,7 @@ class RvalsIterator implements Iterator, AutoCloseable
 
     if (sval == null)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "DEVELOPER WARNING: Annotate3d didn't return a '2D' tag in its response. Consider checking output of server. Response was :"
                       + val.toString());
 
index 7dfdb0c..ddc8d84 100644 (file)
@@ -158,7 +158,7 @@ public class PymolManager
           boolean getReply)
   {
     String postBody = getPostRequest(command);
-    // System.out.println(postBody);// debug
+    // jalview.bin.Console.outPrintln(postBody);// debug
     String rpcUrl = "http://127.0.0.1:" + this.pymolXmlRpcPort;
     PrintWriter out = null;
     BufferedReader in = null;
index 40b0ff0..af31b78 100644 (file)
@@ -126,12 +126,12 @@ public class ChimeraListener extends AbstractRequestHandler
       }
       else if (message.startsWith(MODEL_CHANGED))
       {
-        System.err.println(message);
+        jalview.bin.Console.errPrintln(message);
         processModelChanged(message.substring(MODEL_CHANGED.length()));
       }
       else
       {
-        System.err.println("Unexpected chimeraNotification: " + message);
+        jalview.bin.Console.errPrintln("Unexpected chimeraNotification: " + message);
       }
     }
   }
@@ -143,7 +143,7 @@ public class ChimeraListener extends AbstractRequestHandler
    */
   protected void processModelChanged(String message)
   {
-    // System.out.println(message + " (not implemented in Jalview)");
+    // jalview.bin.Console.outPrintln(message + " (not implemented in Jalview)");
   }
 
   /**
index aebfede..a292e88 100644 (file)
@@ -207,7 +207,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       startListening(chimeraListener.getUri());
     } catch (BindException e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Failed to start Chimera listener: " + e.getMessage());
     }
   }
@@ -568,7 +568,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   private void log(String message)
   {
-    System.err.println("## Chimera log: " + message);
+    jalview.bin.Console.errPrintln("## Chimera log: " + message);
   }
 
   /**
@@ -627,7 +627,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       executeCommand(false, null, command);
     } catch (IOException e)
     {
-      System.err.println("Sending commands to Chimera via file failed with "
+      jalview.bin.Console.errPrintln("Sending commands to Chimera via file failed with "
               + e.getMessage());
     }
   }
index 0971235..86b8c7d 100644 (file)
@@ -94,7 +94,7 @@ public class FTSDataColumnPreferences extends JScrollPane
     int x = 0;
     for (FTSDataColumnI field : allFTSDataColumns)
     {
-      // System.out.println("allFTSDataColumns==" + allFTSDataColumns);
+      // jalview.bin.Console.outPrintln("allFTSDataColumns==" + allFTSDataColumns);
       if (field.getName().equalsIgnoreCase("all"))
       {
         continue;
@@ -106,7 +106,7 @@ public class FTSDataColumnPreferences extends JScrollPane
         data[x++] = new Object[] { ftsRestClient
                 .getAllDefaultDisplayedFTSDataColumns().contains(field),
             field.getName(), field.getGroup() };
-        // System.out.println(" PUIS " + field.getName() + " ET AUSSI " +
+        // jalview.bin.Console.outPrintln(" PUIS " + field.getName() + " ET AUSSI " +
         // field.getGroup() + "X = " + x);
         break;
       case STRUCTURE_CHOOSER:
index d52ff89..dd7fd94 100644 (file)
@@ -696,6 +696,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     this.add(pnl_inputs, java.awt.BorderLayout.NORTH);
     this.add(pnl_results, java.awt.BorderLayout.CENTER);
     this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
+    mainFrame.setFrameIcon(null);
     mainFrame.setVisible(true);
     if (tabs != null)
     {
index 7e95dd2..a631902 100644 (file)
@@ -118,7 +118,7 @@ public class AlphafoldRestClient
           } catch (Exception e)
           {
             e.printStackTrace();
-            System.out.println("offending value:" + fieldData);
+            jalview.bin.Console.outPrintln("offending value:" + fieldData);
           }
         }
       }
index 796bc0e..5619075 100644 (file)
@@ -175,7 +175,7 @@ public class PDBFTSRestClient extends FTSRestClient
 
       URI uri = webResource.getURI();
 
-      System.out.println(uri);
+      jalview.bin.Console.outPrintln(uri);
       ClientResponse clientResponse = null;
       int responseStatus = -1;
       // Get the JSON string from the response object or directly from the
@@ -183,7 +183,7 @@ public class PDBFTSRestClient extends FTSRestClient
       Map<String, Object> jsonObj = null;
       String responseString = null;
 
-      System.out.println("query >>>>>>> " + pdbRestRequest.toString());
+      jalview.bin.Console.outPrintln("query >>>>>>> " + pdbRestRequest.toString());
 
       if (!isMocked())
       {
@@ -413,10 +413,10 @@ public class PDBFTSRestClient extends FTSRestClient
 
     for (FTSDataColumnI field : diplayFields)
     {
-      // System.out.println("Field " + field);
+      // jalview.bin.Console.outPrintln("Field " + field);
       String fieldData = (pdbJsonDoc.get(field.getCode()) == null) ? ""
               : pdbJsonDoc.get(field.getCode()).toString();
-      // System.out.println("Field Data : " + fieldData);
+      // jalview.bin.Console.outPrintln("Field Data : " + fieldData);
       if (field.isPrimaryKeyColumn())
       {
         primaryKey = fieldData;
@@ -440,7 +440,7 @@ public class PDBFTSRestClient extends FTSRestClient
         } catch (Exception e)
         {
           e.printStackTrace();
-          System.out.println("offending value:" + fieldData);
+          jalview.bin.Console.outPrintln("offending value:" + fieldData);
         }
       }
     }
index 253de42..dfb39cb 100644 (file)
@@ -277,7 +277,7 @@ public class TDBeaconsFTSPanel extends GFTSPanel
   @Override
   protected void showHelp()
   {
-    System.out.println("No help implemented yet.");
+    jalview.bin.Console.outPrintln("No help implemented yet.");
 
   }
 
index d7f534e..c275bda 100644 (file)
@@ -101,7 +101,7 @@ public class TDBeaconsFTSRestClient extends FTSRestClient
       webResource = client.resource(DEFAULT_THREEDBEACONS_DOMAIN + query);
 
       URI uri = webResource.getURI();
-      System.out.println(uri.toString());
+      jalview.bin.Console.outPrintln(uri.toString());
 
       // Execute the REST request
       ClientResponse clientResponse;
@@ -269,7 +269,7 @@ public class TDBeaconsFTSRestClient extends FTSRestClient
       String fieldData = (tdbJsonStructure.get(field.getCode()) == null)
               ? " "
               : tdbJsonStructure.get(field.getCode()).toString();
-      // System.out.println("Field : " + field + " Data : " + fieldData);
+      // jalview.bin.Console.outPrintln("Field : " + field + " Data : " + fieldData);
       if (field.isPrimaryKeyColumn())
       {
         primaryKey = fieldData;
@@ -293,7 +293,7 @@ public class TDBeaconsFTSRestClient extends FTSRestClient
         } catch (Exception e)
         {
           // e.printStackTrace();
-          System.out.println("offending value:" + fieldData + fieldData);
+          jalview.bin.Console.outPrintln("offending value:" + fieldData + fieldData);
         }
       }
     }
index 1827293..df48c0d 100644 (file)
@@ -219,7 +219,7 @@ public class UniProtFTSRestClient extends FTSRestClient
               .getEntity(String.class);
       // Make redundant objects eligible for garbage collection to conserve
       // memory
-      // System.out.println(">>>>> response : "
+      // jalview.bin.Console.outPrintln(">>>>> response : "
       // + uniProtTabDelimittedResponseString);
       if (clientResponse.getStatus() != 200)
       {
@@ -307,7 +307,7 @@ public class UniProtFTSRestClient extends FTSRestClient
           firstRow = false;
           continue;
         }
-        // System.out.println(dataRow);
+        // jalview.bin.Console.outPrintln(dataRow);
         result.add(getFTSData(dataRow, uniprotRestRequest));
       }
       searchResult.setNumberOfItemsFound(xTotalResults);
@@ -389,7 +389,7 @@ public class UniProtFTSRestClient extends FTSRestClient
           } catch (Exception e)
           {
             e.printStackTrace();
-            System.out.println("offending value:" + fieldData);
+            jalview.bin.Console.outPrintln("offending value:" + fieldData);
           }
         }
       } catch (Exception e)
index a23cbfa..6ca21c7 100644 (file)
@@ -26,13 +26,13 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
-import java.util.concurrent.Callable;
 
 import javax.swing.JCheckBox;
 import javax.swing.JPanel;
 
 import jalview.api.AlignExportSettingsI;
 import jalview.api.AlignViewportI;
+import jalview.bin.Jalview;
 import jalview.io.FileFormatI;
 import jalview.util.MessageManager;
 
@@ -73,12 +73,9 @@ public class AlignExportOptions extends JPanel
   public static boolean isNeeded(AlignViewportI viewport,
           FileFormatI format)
   {
-    if (viewport.hasHiddenColumns() || viewport.hasHiddenRows()
-            || format.isComplexAlignFile())
-    {
-      return true;
-    }
-    return false;
+    return !Jalview.getInstance().isHeadlessMode()
+            && (viewport.hasHiddenColumns() || viewport.hasHiddenRows()
+                    || format.isComplexAlignFile());
   }
 
   /**
@@ -120,7 +117,7 @@ public class AlignExportOptions extends JPanel
    * 
    * @param action
    */
-  public void setResponseAction(Object response, Callable action)
+  public void setResponseAction(Object response, Runnable action)
   {
     dialog.setResponseHandler(response, action);
   }
index 2d02e79..dba400e 100644 (file)
@@ -49,6 +49,7 @@ import java.beans.PropertyChangeEvent;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.net.URL;
 import java.util.ArrayList;
@@ -59,7 +60,6 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.Locale;
 import java.util.Vector;
-import java.util.concurrent.Callable;
 
 import javax.swing.ButtonGroup;
 import javax.swing.JCheckBoxMenuItem;
@@ -112,6 +112,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.ContactMatrixI;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SeqCigar;
@@ -140,6 +141,7 @@ import jalview.io.JnetAnnotationMaker;
 import jalview.io.NewickFile;
 import jalview.io.ScoreMatrixFile;
 import jalview.io.TCoffeeScoreFile;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.io.vcf.VCFLoader;
 import jalview.jbgui.GAlignFrame;
 import jalview.project.Jalview2XML;
@@ -151,11 +153,11 @@ import jalview.util.HttpUtils;
 import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.util.imagemaker.BitmapImageSizing;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.ViewportRanges;
 import jalview.ws.DBRefFetcher;
 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
-import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 import jalview.ws.jws1.Discoverer;
 import jalview.ws.jws2.Jws2Discoverer;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
@@ -622,12 +624,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         // if (viewport.cursorMode)
         // {
         // alignPanel.seqPanel.insertNucAtCursor(false,"A");
-        // //System.out.println("A");
+        // //jalview.bin.Console.outPrintln("A");
         // }
         // break;
         /*
          * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
-         * System.out.println("closing bracket"); } break;
+         * jalview.bin.Console.outPrintln("closing bracket"); } break;
          */
         case KeyEvent.VK_DELETE:
         case KeyEvent.VK_BACK_SPACE:
@@ -828,7 +830,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               @Override
               public void propertyChange(PropertyChangeEvent evt)
               {
-                // // System.out.println("Discoverer property change.");
+                // // jalview.bin.Console.outPrintln("Discoverer property
+                // change.");
                 // if (evt.getPropertyName().equals("services"))
                 {
                   SwingUtilities.invokeLater(new Runnable()
@@ -837,7 +840,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                     @Override
                     public void run()
                     {
-                      System.err.println(
+                      jalview.bin.Console.errPrintln(
                               "Rebuild WS Menu for service change");
                       BuildWebServiceMenu();
                     }
@@ -852,7 +855,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       public void internalFrameClosed(
               javax.swing.event.InternalFrameEvent evt)
       {
-        // System.out.println("deregistering discoverer listener");
+        // jalview.bin.Console.outPrintln("deregistering discoverer listener");
         Desktop.instance.removeJalviewPropertyChangeListener("services",
                 thisListener);
         closeMenuItem_actionPerformed(true);
@@ -981,7 +984,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void setProgressBar(String message, long id)
   {
-    if (!Platform.isHeadless())
+    if (!Platform.isHeadless() && progressBar != null)
       progressBar.setProgressBar(message, id);
   }
 
@@ -989,7 +992,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void registerHandler(final long id,
           final IProgressIndicatorHandler handler)
   {
-    progressBar.registerHandler(id, handler);
+    if (progressBar != null)
+      progressBar.registerHandler(id, handler);
   }
 
   /**
@@ -999,7 +1003,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public boolean operationInProgress()
   {
-    return progressBar.operationInProgress();
+    return progressBar == null ? false : progressBar.operationInProgress();
   }
 
   /**
@@ -1248,8 +1252,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   public void saveAlignment(String file, FileFormatI format)
   {
+    saveAlignment(file, format, false);
+  }
+
+  public void saveAlignment(String file, FileFormatI format, boolean stdout)
+  {
     lastSaveSuccessful = true;
-    lastFilenameSaved = file;
+    if (!stdout)
+    {
+      lastFilenameSaved = file;
+    }
     lastFormatSaved = format;
 
     if (FileFormat.Jalview.equals(format))
@@ -1260,6 +1272,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         shortName = shortName
                 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
       }
+      // TODO deal with stdout=true
       lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
               shortName);
 
@@ -1277,11 +1290,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
 
     AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
-    Callable<Void> cancelAction = () -> {
+    Runnable cancelAction = () -> {
       lastSaveSuccessful = false;
-      return null;
     };
-    Callable<Void> outputAction = () -> {
+    Runnable outputAction = () -> {
       // todo defer this to inside formatSequences (or later)
       AlignmentExportData exportData = viewport.getAlignExportData(options);
       String output = new FormatAdapter(alignPanel, options)
@@ -1296,7 +1308,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       else
       {
         // create backupfiles object and get new temp filename destination
-        boolean doBackup = BackupFiles.getEnabled();
+        boolean doBackup = BackupFiles.getEnabled() && !stdout;
         BackupFiles backupfiles = null;
         if (doBackup)
         {
@@ -1308,7 +1320,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           String tempFilePath = doBackup ? backupfiles.getTempFilePath()
                   : file;
           Console.trace("ALIGNFRAME setting PrintWriter");
-          PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
+          PrintWriter out = stdout
+                  ? new PrintWriter(new OutputStreamWriter(System.out))
+                  : new PrintWriter(new FileWriter(tempFilePath));
 
           if (backupfiles != null)
           {
@@ -1317,13 +1331,28 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           }
 
           out.print(output);
-          Console.trace("ALIGNFRAME about to close file");
-          out.close();
-          Console.trace("ALIGNFRAME closed file");
-          AlignFrame.this.setTitle(file);
-          statusBar.setText(MessageManager.formatMessage(
-                  "label.successfully_saved_to_file_in_format", new Object[]
-                  { fileName, format.getName() }));
+          out.flush();
+          if (!stdout)
+          {
+            Console.trace("ALIGNFRAME about to close file");
+            out.close();
+            Console.trace("ALIGNFRAME closed file");
+          }
+          AlignFrame.this.setTitle(stdout ? "STDOUT" : file);
+          if (stdout)
+          {
+            statusBar.setText(MessageManager.formatMessage(
+                    "label.successfully_printed_to_stdout_in_format",
+                    new Object[]
+                    { format.getName() }));
+          }
+          else
+          {
+            statusBar.setText(MessageManager.formatMessage(
+                    "label.successfully_saved_to_file_in_format",
+                    new Object[]
+                    { fileName, format.getName() }));
+          }
           lastSaveSuccessful = true;
         } catch (IOException e)
         {
@@ -1359,7 +1388,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           AlignFrame.this.getViewport().setSavedUpToDate(true);
         }
       }
-      return null;
     };
 
     /*
@@ -1377,7 +1405,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       try
       {
-        outputAction.call();
+        outputAction.run();
       } catch (Exception e)
       {
         // TODO Auto-generated catch block
@@ -1399,7 +1427,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     FileFormatI fileFormat = FileFormats.getInstance()
             .forName(fileFormatName);
     AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
-    Callable<Void> outputAction = () -> {
+    Runnable outputAction = () -> {
       // todo defer this to inside formatSequences (or later)
       AlignmentExportData exportData = viewport.getAlignExportData(options);
       CutAndPasteTransfer cap = new CutAndPasteTransfer();
@@ -1421,7 +1449,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                 oom);
         cap.dispose();
       }
-      return null;
     };
 
     /*
@@ -1438,7 +1465,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       try
       {
-        outputAction.call();
+        outputAction.run();
       } catch (Exception e)
       {
         e.printStackTrace();
@@ -1456,19 +1483,75 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void htmlMenuItem_actionPerformed(ActionEvent e)
   {
     HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
-    htmlSVG.exportHTML(null);
+    try
+    {
+      htmlSVG.exportHTML(null);
+    } catch (ImageOutputException x)
+    {
+      // report problem to console and raise dialog
+    }
   }
 
   @Override
   public void bioJSMenuItem_actionPerformed(ActionEvent e)
   {
     BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
-    bjs.exportHTML(null);
+    try
+    {
+      bjs.exportHTML(null);
+    } catch (ImageOutputException x)
+    {
+      // report problem to console and raise dialog
+    }
   }
 
   public void createImageMap(File file, String image)
   {
-    alignPanel.makePNGImageMap(file, image);
+    try
+    {
+      alignPanel.makePNGImageMap(file, image);
+    } catch (ImageOutputException x)
+    {
+      // report problem to console and raise dialog
+    }
+  }
+
+  @Override
+  public void createPNG_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      createPNG(null);
+    } catch (ImageOutputException ioex)
+    {
+      // raise dialog, and report via console
+    }
+  }
+
+  @Override
+  public void createEPS_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      createEPS(null);
+    } catch (ImageOutputException ioex)
+    {
+      // raise dialog, and report via console
+    }
+
+  }
+
+  @Override
+  public void createSVG_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      createSVG(null);
+    } catch (ImageOutputException ioex)
+    {
+      // raise dialog, and report via console
+    }
+
   }
 
   /**
@@ -1477,10 +1560,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param f
    */
-  @Override
-  public void createPNG(File f)
+  public void createPNG(File f) throws ImageOutputException
   {
-    alignPanel.makeAlignmentImage(TYPE.PNG, f);
+    createPNG(f, null, BitmapImageSizing.defaultBitmapImageSizing());
+  }
+
+  public void createPNG(File f, String renderer, BitmapImageSizing userBis)
+          throws ImageOutputException
+  {
+    alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
   }
 
   /**
@@ -1489,10 +1577,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param f
    */
-  @Override
-  public void createEPS(File f)
+  public void createEPS(File f) throws ImageOutputException
   {
-    alignPanel.makeAlignmentImage(TYPE.EPS, f);
+    createEPS(f, null);
+  }
+
+  public void createEPS(File f, String renderer) throws ImageOutputException
+  {
+    alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
   }
 
   /**
@@ -1501,10 +1593,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param f
    */
-  @Override
-  public void createSVG(File f)
+  public void createSVG(File f) throws ImageOutputException
   {
-    alignPanel.makeAlignmentImage(TYPE.SVG, f);
+    createSVG(f, null);
+  }
+
+  public void createSVG(File f, String renderer) throws ImageOutputException
+  {
+    alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
   }
 
   @Override
@@ -1554,7 +1650,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       String choice = chooser.getSelectedFile().getPath();
       Cache.setProperty("LAST_DIRECTORY", choice);
       loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
-      return null;
     });
 
     chooser.showOpenDialog(this);
@@ -1574,6 +1669,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       closeAllTabs = true;
     }
 
+    Desktop.closeModal(this);
+
     try
     {
       if (alignPanels != null)
@@ -1603,6 +1700,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           featureSettings.close();
           featureSettings = null;
         }
+
         /*
          * this will raise an INTERNAL_FRAME_CLOSED event and this method will
          * be called recursively, with the frame now in 'closed' state
@@ -1696,7 +1794,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @return alignment objects for all views
    */
-  AlignmentI[] getViewAlignments()
+  public AlignmentI[] getViewAlignments()
   {
     if (alignPanels != null)
     {
@@ -2286,10 +2384,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                         .intValue();
               }
             }
-            alignment.addAnnotation(sequences[i].getAnnotation()[a]); // annotation
-            // was
-            // duplicated
-            // earlier
+            // annotation was duplicated earlier
+            alignment.addAnnotation(sequences[i].getAnnotation()[a]);
+            // take care of contact matrix too
+            ContactMatrixI cm = sequences[i]
+                    .getContactMatrixFor(sequences[i].getAnnotation()[a]);
+            if (cm != null)
+            {
+              alignment.addContactListFor(sequences[i].getAnnotation()[a],
+                      cm);
+            }
+
             alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
                     a);
           }
@@ -2397,7 +2502,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     } catch (Exception ex)
     {
       ex.printStackTrace();
-      System.out.println("Exception whilst pasting: " + ex);
+      jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex);
       // could be anything being pasted in here
     }
 
@@ -2445,7 +2550,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     } catch (Exception ex)
     {
       ex.printStackTrace();
-      System.out.println("Exception whilst pasting: " + ex);
+      jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex);
       // could be anything being pasted in here
     } catch (OutOfMemoryError oom)
     {
@@ -2476,7 +2581,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       return;
     }
 
-    Callable okAction = () -> {
+    Runnable okAction = () -> {
       SequenceI[] cut = sg.getSequences()
               .toArray(new SequenceI[sg.getSize()]);
 
@@ -2500,7 +2605,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         {
         }
       }
-      return null;
     };
 
     /*
@@ -2526,7 +2630,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       try
       {
-        okAction.call();
+        okAction.run();
       } catch (Exception e)
       {
         e.printStackTrace();
@@ -3082,11 +3186,20 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void wrapMenuItem_actionPerformed(ActionEvent e)
   {
-    scaleAbove.setVisible(wrapMenuItem.isSelected());
-    scaleLeft.setVisible(wrapMenuItem.isSelected());
-    scaleRight.setVisible(wrapMenuItem.isSelected());
-    viewport.setWrapAlignment(wrapMenuItem.isSelected());
+    setWrapFormat(wrapMenuItem.isSelected(), false);
+  }
+
+  public void setWrapFormat(boolean b, boolean setMenuItem)
+  {
+    scaleAbove.setVisible(b);
+    scaleLeft.setVisible(b);
+    scaleRight.setVisible(b);
+    viewport.setWrapAlignment(b);
     alignPanel.updateLayout();
+    if (setMenuItem)
+    {
+      wrapMenuItem.setSelected(b);
+    }
   }
 
   @Override
@@ -3424,7 +3537,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
 
     JInternalFrame frame = new JInternalFrame();
-
+    frame.setFrameIcon(null);
     frame.getContentPane().add(new JScrollPane(pane));
 
     Desktop.addInternalFrame(frame, MessageManager
@@ -3440,8 +3553,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void overviewMenuItem_actionPerformed(ActionEvent e)
   {
-    boolean showHiddenRegions = Cache.getDefault(Preferences.SHOW_OV_HIDDEN_AT_START,
-                false);
+    boolean showHiddenRegions = Cache
+            .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
     openOverviewPanel(showHiddenRegions);
   }
 
@@ -3452,14 +3565,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       return alignPanel.overviewPanel;
     }
     JInternalFrame frame = new JInternalFrame();
-    final OverviewPanel overview = new OverviewPanel(alignPanel, frame, showHidden);
-    frame.setContentPane(overview);
-    Desktop.addInternalFrame(frame, "", true, frame.getWidth(), frame.getHeight(),
-            true, true);
     frame.setFrameIcon(null);
+    final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
+            showHidden);
+    frame.setContentPane(overview);
+    Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
+            frame.getHeight(), true, true);
     frame.pack();
     frame.setLayer(JLayeredPane.PALETTE_LAYER);
-    final AlignmentPanel thePanel = this.alignPanel; 
+    final AlignmentPanel thePanel = this.alignPanel;
     frame.addInternalFrameListener(
             new javax.swing.event.InternalFrameAdapter()
             {
@@ -3478,7 +3592,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     alignPanel.setOverviewPanel(overview);
     alignPanel.setOverviewTitle(this);
-    
+
     return overview;
   }
 
@@ -3730,6 +3844,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     else
     {
       JInternalFrame frame = new JInternalFrame();
+      frame.setFrameIcon(null);
       frame.setContentPane(new PairwiseAlignPanel(viewport));
       Desktop.addInternalFrame(frame,
               MessageManager.getString("action.pairwise_alignment"), 600,
@@ -4117,7 +4232,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                         .getString("label.possible_problem_with_tree_file"),
                 JvOptionPane.WARNING_MESSAGE);
       }
-      return null;
     });
     chooser.showOpenDialog(this);
   }
@@ -4133,7 +4247,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     return showNewickTree(nf, treeTitle, null, w, h, x, y);
   }
 
-
   /**
    * Add a treeviewer for the tree extracted from a Newick file object to the
    * current alignment view
@@ -4184,56 +4297,57 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     return tp;
   }
 
-
-  public void showContactMapTree(AlignmentAnnotation aa,
-          PAEContactMatrix cm)
+  public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm)
   {
     int x = 4, y = 5;
     int w = 400, h = 500;
-    
+
     try
     {
       NewickFile fin = new NewickFile(
               new FileParse(cm.getNewick(), DataSourceType.PASTE));
-      String title = "PAE Matrix Tree for "
-              + cm.getReferenceSeq().getDisplayId(false);
+      String title = aa.label + " " + cm.getTreeMethod() + " tree"
+              + (aa.sequenceRef != null
+                      ? (" for " + aa.sequenceRef.getDisplayId(false))
+                      : "");
 
-      showColumnWiseTree(fin, aa, title, w,h, x,y);
+      showColumnWiseTree(fin, aa, title, w, h, x, y);
     } catch (Throwable xx)
     {
       Console.error("Unexpected exception showing tree for contact matrix",
               xx);
     }
   }
-  public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa, String treeTitle,
-           int w, int h, int x, int y)
+
+  public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
+          String treeTitle, int w, int h, int x, int y)
   {
-      try
+    try
+    {
+      nf.parse();
+      if (nf.getTree() == null)
       {
-        nf.parse();
-        if (nf.getTree() == null)
-        {
-          return null;
-        }
-        TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
+        return null;
+      }
+      TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle);
 
-        tp.setSize(w, h);
+      tp.setSize(w, h);
 
-        if (x > 0 && y > 0)
-        {
-          tp.setLocation(x, y);
-        }
-
-        Desktop.addInternalFrame(tp, title, w, h);
-        return tp;
-      } catch (Throwable xx)
+      if (x > 0 && y > 0)
       {
-        Console.error("Unexpected exception showing tree for contact matrix",
-                xx);
+        tp.setLocation(x, y);
       }
-      return null;
+
+      Desktop.addInternalFrame(tp, treeTitle, w, h);
+      return tp;
+    } catch (Throwable xx)
+    {
+      Console.error("Unexpected exception showing tree for contact matrix",
+              xx);
+    }
+    return null;
   }
-  
+
   private boolean buildingMenu = false;
 
   /**
@@ -4246,7 +4360,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       try
       {
-        System.err.println("Waiting for building menu to finish.");
+        jalview.bin.Console
+                .errPrintln("Waiting for building menu to finish.");
         Thread.sleep(10);
       } catch (Exception e)
       {
@@ -4262,7 +4377,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         final List<JMenuItem> legacyItems = new ArrayList<>();
         try
         {
-          // System.err.println("Building ws menu again "
+          // jalview.bin.Console.errPrintln("Building ws menu again "
           // + Thread.currentThread());
           // TODO: add support for context dependent disabling of services based
           // on
@@ -4800,7 +4915,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                                     Desktop.instance);
                     if (pe != null)
                     {
-                      System.err.println("Associated file : "
+                      jalview.bin.Console.errPrintln("Associated file : "
                               + (fm[0].toString()) + " with "
                               + toassoc.getDisplayId(true));
                       assocfiles++;
@@ -5027,7 +5142,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
        * to add view name "Original" if necessary
        */
       alignPanel.setOverviewTitle(this);
-      
+
       /*
        * switch panels and set Overview title (if there is one
        * because it was opened automatically)
@@ -5698,7 +5813,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    *          update non-sequence-related annotations
    */
   @Override
-  protected void setAnnotationsVisibility(boolean visible,
+  public void setAnnotationsVisibility(boolean visible,
           boolean forSequences, boolean forAlignment)
   {
     AlignmentAnnotation[] anns = alignPanel.getAlignment()
@@ -5833,7 +5948,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               viewport.getAlignment()));
     } catch (Exception ex)
     {
-      System.err.println(ex.getMessage());
+      jalview.bin.Console.errPrintln(ex.getMessage());
       return;
     }
   }
@@ -5855,7 +5970,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         console.runScript();
       } catch (Exception ex)
       {
-        System.err.println((ex.toString()));
+        jalview.bin.Console.errPrintln((ex.toString()));
         JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                 MessageManager.getString("label.couldnt_run_groovy_script"),
                 MessageManager.getString("label.groovy_support_failed"),
@@ -5864,7 +5979,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
     else
     {
-      System.err.println("Can't run Groovy script as console not found");
+      jalview.bin.Console
+              .errPrintln("Can't run Groovy script as console not found");
     }
   }
 
@@ -5964,7 +6080,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       Cache.setProperty("LAST_DIRECTORY", choice);
       SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
       new VCFLoader(choice).loadVCF(seqs, us);
-      return null;
     });
     chooser.showOpenDialog(null);
 
index 90f627e..ef9e575 100644 (file)
@@ -340,7 +340,7 @@ public class AlignViewport extends AlignmentViewport
     viewStyle.setFontName(font.getName());
     viewStyle.setFontStyle(font.getStyle());
     viewStyle.setFontSize(font.getSize());
-    
+
     validCharWidth = true;
   }
 
@@ -745,6 +745,11 @@ public class AlignViewport extends AlignmentViewport
    */
   public void addFile(File file, FileFormatI format)
   {
+    addFile(file, format, true);
+  }
+
+  public void addFile(File file, FileFormatI format, boolean async)
+  {
     DataSourceType protocol = AppletFormatAdapter.checkProtocol(file);
 
     if (format == null)
@@ -769,7 +774,8 @@ public class AlignViewport extends AlignmentViewport
       }
     }
 
-    new FileLoader().LoadFile(this, file, DataSourceType.FILE, format);
+    new FileLoader().LoadFile(this, file, DataSourceType.FILE, format,
+            async);
   }
 
   public void addFile(File file)
@@ -803,13 +809,10 @@ public class AlignViewport extends AlignmentViewport
     JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop)
             .setResponseHandler(0, () -> {
               addDataToAlignment(al);
-              return null;
             }).setResponseHandler(1, () -> {
               us.openLinkedAlignmentAs(al, title, true);
-              return null;
             }).setResponseHandler(2, () -> {
               us.openLinkedAlignmentAs(al, title, false);
-              return null;
             });
     dialog.showDialog(question,
             MessageManager.getString("label.open_split_window"),
@@ -1155,4 +1158,5 @@ public class AlignViewport extends AlignmentViewport
   {
     this.viewName = viewName;
   }
+
 }
index 2d057bb..ce87c01 100644 (file)
  */
 package jalview.gui;
 
-import jalview.analysis.AnnotationSorter;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.Cache;
-import jalview.bin.Console;
-import jalview.bin.Jalview;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.SearchResultsI;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.gui.ImageExporter.ImageWriterI;
-import jalview.io.HTMLOutput;
-import jalview.jbgui.GAlignmentPanel;
-import jalview.math.AlignmentDimension;
-import jalview.schemes.ResidueProperties;
-import jalview.structure.StructureSelectionManager;
-import jalview.util.Comparison;
-import jalview.util.ImageMaker;
-import jalview.util.MessageManager;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Container;
@@ -68,6 +44,33 @@ import java.util.List;
 
 import javax.swing.SwingUtilities;
 
+import jalview.analysis.AnnotationSorter;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
+import jalview.bin.Console;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.ImageExporter.ImageWriterI;
+import jalview.io.HTMLOutput;
+import jalview.io.exceptions.ImageOutputException;
+import jalview.jbgui.GAlignmentPanel;
+import jalview.math.AlignmentDimension;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.Comparison;
+import jalview.util.ImageMaker;
+import jalview.util.MessageManager;
+import jalview.util.imagemaker.BitmapImageSizing;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
 /**
  * DOCUMENT ME!
  * 
@@ -229,8 +232,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
     // set idCanvas bufferedImage to null
     // to prevent drawing old image
     FontMetrics fm = getFontMetrics(av.getFont());
-    
-    // update the flag controlling whether the grid is too small to render the font
+
+    // update the flag controlling whether the grid is too small to render the
+    // font
     av.validCharWidth = fm.charWidth('M') <= av.getCharWidth();
 
     scalePanelHolder.setPreferredSize(
@@ -266,10 +270,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
     Dimension r = null;
     if (av.getIdWidth() < 0)
     {
-      int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
-      int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3);
-      int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth);
-      r = calculateIdWidth(maxwidth);
+      r = calculateDefaultAlignmentIdWidth();
       av.setIdWidth(r.width);
     }
     else
@@ -291,6 +292,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
     return r;
   }
 
+  public Dimension calculateDefaultAlignmentIdWidth()
+  {
+    int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
+    int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3);
+    int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth);
+    return calculateIdWidth(-1, false, false);
+  }
+
   /**
    * Calculate the width of the alignment labels based on the displayed names
    * and any bounds on label width set in preferences.
@@ -302,6 +311,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
    */
   protected Dimension calculateIdWidth(int maxwidth)
   {
+    return calculateIdWidth(maxwidth, true, false);
+  }
+
+  public Dimension calculateIdWidth(int maxwidth,
+          boolean includeAnnotations, boolean visibleOnly)
+  {
     Container c = new Container();
 
     FontMetrics fm = c.getFontMetrics(
@@ -321,18 +336,29 @@ public class AlignmentPanel extends GAlignmentPanel implements
     }
 
     // Also check annotation label widths
-    i = 0;
-
-    if (al.getAlignmentAnnotation() != null)
+    if (includeAnnotations && al.getAlignmentAnnotation() != null)
     {
-      fm = c.getFontMetrics(getAlabels().getFont());
-
-      while (i < al.getAlignmentAnnotation().length)
+      if (Jalview.isHeadlessMode())
       {
-        String label = al.getAlignmentAnnotation()[i].label;
-        int stringWidth = fm.stringWidth(label);
+        AnnotationLabels aal = getAlabels();
+        int stringWidth = aal.drawLabels(null, false, idWidth, false, false, fm);
         idWidth = Math.max(idWidth, stringWidth);
-        i++;
+      }
+      else
+      {
+        fm = c.getFontMetrics(getAlabels().getFont());
+
+        for (i = 0; i < al.getAlignmentAnnotation().length; i++)
+        {
+          AlignmentAnnotation aa = al.getAlignmentAnnotation()[i];
+          if (visibleOnly && !aa.visible)
+          {
+            continue;
+          }
+          String label = aa.label;
+          int stringWidth = fm.stringWidth(label);
+          idWidth = Math.max(idWidth, stringWidth);
+        }
       }
     }
 
@@ -540,7 +566,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
     // this is called after loading new annotation onto alignment
     if (alignFrame.getHeight() == 0)
     {
-      System.out.println("NEEDS FIXING");
+      jalview.bin.Console.outPrintln("NEEDS FIXING");
     }
     validateAnnotationDimensions(true);
     addNotify();
@@ -564,21 +590,29 @@ public class AlignmentPanel extends GAlignmentPanel implements
     // not be called directly by programs.
     // I note that addNotify() is called in several areas of Jalview.
 
-    int annotationHeight = getAnnotationPanel().adjustPanelHeight();
-    annotationHeight = getAnnotationPanel()
-            .adjustForAlignFrame(adjustPanelHeight, annotationHeight);
+    AnnotationPanel ap = getAnnotationPanel();
+    int annotationHeight = ap.adjustPanelHeight();
+    annotationHeight = ap.adjustForAlignFrame(adjustPanelHeight,
+            annotationHeight);
 
     hscroll.addNotify();
-    annotationScroller.setPreferredSize(
-            new Dimension(annotationScroller.getWidth(), annotationHeight));
-
     Dimension e = idPanel.getSize();
-    alabels.setSize(new Dimension(e.width, annotationHeight));
+    int idWidth = e.width;
+    boolean manuallyAdjusted = this.getIdPanel().getIdCanvas()
+            .manuallyAdjusted();
+    annotationScroller.setPreferredSize(new Dimension(
+            manuallyAdjusted ? idWidth : annotationScroller.getWidth(),
+            annotationHeight));
+
+    alabels.setPreferredSize(new Dimension(idWidth, annotationHeight));
 
     annotationSpaceFillerHolder.setPreferredSize(new Dimension(
-            annotationSpaceFillerHolder.getWidth(), annotationHeight));
+            manuallyAdjusted ? idWidth
+                    : annotationSpaceFillerHolder.getWidth(),
+            annotationHeight));
     annotationScroller.validate();
     annotationScroller.addNotify();
+    ap.validate();
   }
 
   /**
@@ -594,9 +628,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
     boolean wrap = av.getWrapAlignment();
     ViewportRanges ranges = av.getRanges();
     ranges.setStartSeq(0);
-    scalePanelHolder.setVisible(!wrap);
+    // scalePanelHolder.setVisible(!wrap);
     hscroll.setVisible(!wrap);
-    idwidthAdjuster.setVisible(!wrap);
+    // Allow idPanel width adjustment in wrap mode
+    idwidthAdjuster.setVisible(true);
 
     if (wrap)
     {
@@ -630,7 +665,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
       }
     }
 
-    idSpaceFillerPanel1.setVisible(!wrap);
+    // idSpaceFillerPanel1.setVisible(!wrap);
 
     repaint();
   }
@@ -851,10 +886,27 @@ public class AlignmentPanel extends GAlignmentPanel implements
   public void paintComponent(Graphics g)
   {
     invalidate(); // needed so that the id width adjuster works correctly
-
     Dimension d = getIdPanel().getIdCanvas().getPreferredSize();
-    idPanelHolder.setPreferredSize(d);
-    hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));
+    int idWidth = d.width;
+
+    // check wrapped alignment as at least 1 residue width
+    if (av.getWrapAlignment())
+    {
+      SeqCanvas sc = this.getSeqPanel().seqCanvas;
+      if (sc != null && sc.getWidth() < sc.getMinimumWrappedCanvasWidth())
+      {
+        // need to make some adjustments
+        idWidth -= (sc.getMinimumWrappedCanvasWidth() - sc.getWidth());
+        av.setIdWidth(idWidth);
+        av.getAlignPanel().getIdPanel().getIdCanvas()
+                .setManuallyAdjusted(true);
+
+        validateAnnotationDimensions(false);
+      }
+    }
+
+    idPanelHolder.setPreferredSize(new Dimension(idWidth, d.height));
+    hscrollFillerPanel.setPreferredSize(new Dimension(idWidth, 12));
 
     validate(); // needed so that the id width adjuster works correctly
 
@@ -1012,7 +1064,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
     List<SequenceI> selection = av.getSelectionGroup() == null ? null
             : av.getSelectionGroup().getSequences(null);
     idCanvas.drawIds((Graphics2D) idGraphics, av, startSeq, endSeq - 1,
-            selection);
+            selection, false);
 
     idGraphics.setFont(av.getFont());
     idGraphics.translate(0, -scaleHeight);
@@ -1036,7 +1088,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
       int offset = getAlabels().getScrollOffset();
       idGraphics.translate(0, -offset);
       idGraphics.translate(0, alignmentDrawnHeight);
-      getAlabels().drawComponent(idGraphics, idWidth);
+      getAlabels().drawComponentNotGUI(idGraphics, idWidth);
       idGraphics.translate(0, -alignmentDrawnHeight);
 
       /*
@@ -1045,6 +1097,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
        */
       alignmentGraphics.translate(alignmentGraphicsOffset,
               alignmentDrawnHeight);
+      updateLayout();
       getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av,
               alignmentGraphics, -1, startRes, endRes + 1);
     }
@@ -1116,7 +1169,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
      * draw sequence ids and annotation labels (if shown)
      */
     IdCanvas idCanvas = getIdPanel().getIdCanvas();
-    idCanvas.drawIdsWrapped((Graphics2D) g, av, 0, totalHeight);
+    idCanvas.drawIdsWrappedNoGUI((Graphics2D) g, av, 0, totalHeight);
 
     g.translate(idWidth, 0);
 
@@ -1168,21 +1221,33 @@ public class AlignmentPanel extends GAlignmentPanel implements
     }
 
     int w = getIdPanel().getWidth();
+    w = this.calculateIdWidth(-1, true, true).width;
     return (w > 0 ? w : calculateIdWidth().width);
   }
 
+  void makeAlignmentImage(ImageMaker.TYPE type, File file, String renderer)
+          throws ImageOutputException
+  {
+    makeAlignmentImage(type, file, renderer,
+            BitmapImageSizing.nullBitmapImageSizing());
+  }
+
   /**
    * Builds an image of the alignment of the specified type (EPS/PNG/SVG) and
    * writes it to the specified file
    * 
    * @param type
    * @param file
+   * @param textrenderer
+   * @param bitmapscale
    */
-  void makeAlignmentImage(ImageMaker.TYPE type, File file)
+  void makeAlignmentImage(ImageMaker.TYPE type, File file, String renderer,
+          BitmapImageSizing userBis) throws ImageOutputException
   {
     final int borderBottomOffset = 5;
 
     AlignmentDimension aDimension = getAlignmentDimension();
+
     // todo use a lambda function in place of callback here?
     ImageWriterI writer = new ImageWriterI()
     {
@@ -1208,7 +1273,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
     int imageWidth = aDimension.getWidth();
     int imageHeight = aDimension.getHeight() + borderBottomOffset;
     String of = MessageManager.getString("label.alignment");
-    exporter.doExport(file, this, imageWidth, imageHeight, of);
+    exporter.doExport(file, this, imageWidth, imageHeight, of, renderer,
+            userBis);
   }
 
   /**
@@ -1253,6 +1319,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
   }
 
   public void makePNGImageMap(File imgMapFile, String imageName)
+          throws ImageOutputException
   {
     // /////ONLY WORKS WITH NON WRAPPED ALIGNMENTS
     // ////////////////////////////////////////////
@@ -1377,7 +1444,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
       } catch (Exception ex)
       {
-        ex.printStackTrace();
+        throw new ImageOutputException(
+                "couldn't write ImageMap due to unexpected error", ex);
       }
     } // /////////END OF IMAGE MAP
 
@@ -1393,8 +1461,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
   {
     int seqPanelWidth = getSeqPanel().seqCanvas.getWidth();
 
-    if (System.getProperty("java.awt.headless") != null
-            && System.getProperty("java.awt.headless").equals("true"))
+    if (Jalview.isHeadlessMode())
     {
       seqPanelWidth = alignFrame.getWidth() - getVisibleIdWidth()
               - vscroll.getPreferredSize().width
index a0ab709..d898398 100644 (file)
@@ -41,6 +41,7 @@ import javax.swing.JPanel;
 
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
 import jalview.datamodel.GraphLine;
 import jalview.datamodel.SequenceGroup;
 import jalview.gui.JalviewColourChooser.ColourChooserListener;
@@ -72,6 +73,10 @@ public class AnnotationColourChooser extends AnnotationRowFilter
 
   public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap)
   {
+    this(av,ap,null);
+  }
+  public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap,AnnotationColourGradient initSettings)
+  {
     super(av, ap);
     oldcs = av.getGlobalColourScheme();
     if (av.getAlignment().getGroups() != null)
@@ -105,11 +110,28 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     setDefaultMinMax();
 
     adjusting = true;
-    if (oldcs instanceof AnnotationColourGradient)
+    if (oldcs instanceof AnnotationColourGradient && initSettings==null)
+    {
+      // init from oldcs
+      initialiseFrom((AnnotationColourGradient) oldcs);
+    } else {
+      // use initial colour gradient - if any..
+      initialiseFrom(initSettings);
+    }
+    
+    jbInit();
+    adjusting = false;
+
+    updateView();
+    frame.invalidate();
+    frame.pack();
+  }
+  private void initialiseFrom(AnnotationColourGradient acg)
+  {
+    if (acg!=null)
     {
-      AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
       useOriginalColours.setSelected(
-              acg.isPredefinedColours() || acg.getBaseColour() != null);
+            acg.isPredefinedColours() || acg.getBaseColour() != null);
       if (!acg.isPredefinedColours() && acg.getBaseColour() == null)
       {
         minColour.setBackground(acg.getMinColour());
@@ -124,10 +146,14 @@ public class AnnotationColourChooser extends AnnotationRowFilter
 
     populateThresholdComboBox(threshold);
 
-    if (oldcs instanceof AnnotationColourGradient)
+    if (acg!=null)
     {
-      AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
       String label = getAnnotationMenuLabel(acg.getAnnotation());
+      // TODO: workaround below shouldn't be necessary - there's a bug in getAnnotationMenuLabel!
+      if (acg.isSeqAssociated())
+      {
+        label = acg.getAnnotation().label;
+      }
       annotations.setSelectedItem(label);
       switch (acg.getAboveThreshold())
       {
@@ -147,13 +173,6 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       thresholdIsMin.setSelected(acg.isThresholdIsMinMax());
       thresholdValue.setText(String.valueOf(acg.getAnnotationThreshold()));
     }
-
-    jbInit();
-    adjusting = false;
-
-    updateView();
-    frame.invalidate();
-    frame.pack();
   }
 
   @Override
@@ -356,9 +375,11 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       return;
     }
 
+    int selIndex = annotations
+            .getSelectedIndex();
+    int annIndex = annmap[selIndex];
     setCurrentAnnotation(
-            av.getAlignment().getAlignmentAnnotation()[annmap[annotations
-                    .getSelectedIndex()]]);
+            av.getAlignment().getAlignmentAnnotation()[annIndex]);
 
     int selectedThresholdItem = getSelectedThresholdItem(
             getThreshold().getSelectedIndex());
@@ -447,4 +468,33 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     super.sliderDragReleased();
     ap.paintAlignment(true, true);
   }
+
+  /**
+   * construct and display a colourchooser for a given annotation row
+   * 
+   * @param av
+   * @param ap
+   * @param alignmentAnnotation
+   * @param perseq - when true, enable per-sequence if alignment annotation is per sequence 
+   */
+  public static void displayFor(AlignViewport av, AlignmentPanel ap,
+          AlignmentAnnotation alignmentAnnotation, boolean perSeq)
+  {
+    ColourSchemeI global = av.getGlobalColourScheme();
+    AnnotationColourGradient newCS = new AnnotationColourGradient(alignmentAnnotation, global, alignmentAnnotation.threshold!=null ? AnnotationColourGradient.ABOVE_THRESHOLD:AnnotationColourGradient.NO_THRESHOLD);
+    if (alignmentAnnotation.sequenceRef!=null)
+    {
+      newCS.setSeqAssociated(perSeq);
+    }
+    for (int i=0;i<alignmentAnnotation.annotations.length;i++)
+    {
+      Annotation ann = alignmentAnnotation.annotations[i];
+      if (ann!=null && ann.colour!=null && !ann.colour.equals(Color.white))
+      {
+        newCS.setPredefinedColours(true);
+        break;
+      }
+    }
+    AnnotationColourChooser achooser = new AnnotationColourChooser(av,ap,newCS);
+  }
 }
index c6c0e10..0483aa6 100644 (file)
@@ -42,6 +42,7 @@ import javax.swing.JPanel;
 import javax.swing.JRadioButton;
 import javax.swing.border.TitledBorder;
 
+import jalview.bin.Console;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.HiddenColumns;
 import jalview.io.cache.JvCacheableInputBox;
@@ -95,6 +96,10 @@ public class AnnotationColumnChooser extends AnnotationRowFilter
 
   public AnnotationColumnChooser(AlignViewport av, final AlignmentPanel ap)
   {
+    this(av,ap,null);
+  }
+  public AnnotationColumnChooser(AlignViewport av, final AlignmentPanel ap, AlignmentAnnotation selectedAnnotation)
+  {
     super(av, ap);
     frame = new JInternalFrame();
     frame.setFrameIcon(null);
@@ -115,7 +120,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter
     }
     setOldHiddenColumns(av.getAlignment().getHiddenColumns());
     adjusting = true;
-
+    
     setAnnotations(new JComboBox<>(getAnnotationItems(false)));
     populateThresholdComboBox(threshold);
     AnnotationColumnChooser lastChooser = av
@@ -134,6 +139,16 @@ public class AnnotationColumnChooser extends AnnotationRowFilter
       percentThreshold
               .setSelected(lastChooser.percentThreshold.isSelected());
     }
+    if (selectedAnnotation!=null)
+    {
+      try {
+        setCurrentAnnotation(selectedAnnotation);
+        annotations.setSelectedItem(getAnnotationMenuLabel(selectedAnnotation));
+      } catch (Exception x)
+      {
+        Console.error("Couldn't select annotation in column chooser",x);
+      }
+    }
 
     try
     {
@@ -850,4 +865,10 @@ public class AnnotationColumnChooser extends AnnotationRowFilter
     gSearchPanel.searchBox.updateCache();
     ngSearchPanel.searchBox.updateCache();
   }
+
+  public static void displayFor(AlignViewport av, AlignmentPanel ap,
+          AlignmentAnnotation alignmentAnnotation)
+  {
+    AnnotationColumnChooser colchooser = new AnnotationColumnChooser(av, ap, alignmentAnnotation);    
+  }
 }
index 52a6066..d9d6b9f 100755 (executable)
@@ -20,6 +20,7 @@
  */
 package jalview.gui;
 
+import java.awt.Canvas;
 import java.awt.Color;
 import java.awt.Cursor;
 import java.awt.Dimension;
@@ -36,7 +37,6 @@ import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
 import java.awt.geom.AffineTransform;
-import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
@@ -51,23 +51,22 @@ import javax.swing.ToolTipManager;
 
 import jalview.analysis.AlignSeq;
 import jalview.analysis.AlignmentUtils;
-import jalview.bin.Console;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ContactMatrixI;
+import jalview.datamodel.GroupSet;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
-import jalview.io.DataSourceType;
 import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
-import jalview.io.NewickFile;
 import jalview.util.Comparison;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
-import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 
 /**
  * The panel that holds the labels for alignment annotations, providing
@@ -89,7 +88,7 @@ public class AnnotationLabels extends JPanel
   /**
    * height in pixels for allowing height adjuster to be active
    */
-  private static int HEIGHT_ADJUSTER_HEIGHT = 10;
+  public static int HEIGHT_ADJUSTER_HEIGHT = 10;
 
   private static final Font font = new Font("Arial", Font.PLAIN, 11);
 
@@ -117,6 +116,8 @@ public class AnnotationLabels extends JPanel
   private static final String COPYCONS_SEQ = MessageManager
           .getString("label.copy_consensus_sequence");
 
+  private static final String ADJUST_ANNOTATION_LABELS_WIDTH_PREF = "ADJUST_ANNOTATION_LABELS_WIDTH";
+
   private final boolean debugRedraw = false;
 
   private AlignmentPanel ap;
@@ -135,6 +136,10 @@ public class AnnotationLabels extends JPanel
 
   private boolean resizePanel = false;
 
+  private int annotationIdWidth = -1;
+
+  public static final String RESIZE_MARGINS_MARK_PREF = "RESIZE_MARGINS_MARK";
+
   /**
    * Creates a new AnnotationLabels object
    * 
@@ -142,7 +147,6 @@ public class AnnotationLabels extends JPanel
    */
   public AnnotationLabels(AlignmentPanel ap)
   {
-
     this.ap = ap;
     av = ap.av;
     ToolTipManager.sharedInstance().registerComponent(this);
@@ -312,7 +316,6 @@ public class AnnotationLabels extends JPanel
         ap.av.getAlignment().setAnnotationIndex(annotation, 0);
       }
       ap.refresh(true);
-      return null;
     });
   }
 
@@ -422,33 +425,160 @@ public class AnnotationLabels extends JPanel
         consclipbrd.addActionListener(this);
         pop.add(consclipbrd);
       }
-       if (aa[selectedRow].graph == AlignmentAnnotation.CONTACT_MAP
-              && PAEContactMatrix.PAEMATRIX
-                      .equals(aa[selectedRow].getCalcId()))
+
+      addColourOrFilterByOptions(ap, aa[selectedRow], pop);
+
+      if (aa[selectedRow].graph == AlignmentAnnotation.CONTACT_MAP)
+      {
+        addContactMatrixOptions(ap, aa[selectedRow], pop);
+        // Set/adjust threshold for grouping ?
+        // colour alignment by this [type]
+        // select/hide columns by this row
+
+      }
+    }
+
+    pop.show(this, evt.getX(), evt.getY());
+  }
+
+  static void addColourOrFilterByOptions(final AlignmentPanel ap,
+          final AlignmentAnnotation alignmentAnnotation,
+          final JPopupMenu pop)
+  {
+    JMenuItem item;
+    item = new JMenuItem(
+            MessageManager.getString("label.colour_by_annotation"));
+    item.addActionListener(new ActionListener()
+    {
+
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        AnnotationColourChooser.displayFor(ap.av, ap, alignmentAnnotation,
+                false);
+      };
+    });
+    pop.add(item);
+    if (alignmentAnnotation.sequenceRef != null)
+    {
+      item = new JMenuItem(
+              MessageManager.getString("label.colour_by_annotation") + " ("
+                      + MessageManager.getString("label.per_seq") + ")");
+      item.addActionListener(new ActionListener()
       {
-        final PAEContactMatrix cm = (PAEContactMatrix) av
-                .getContactMatrix(aa[selectedRow]);
-        if (cm!=null && cm.getNewick()!=null && cm.getNewick().length()>0)
+        @Override
+        public void actionPerformed(ActionEvent e)
         {
-          item = new JMenuItem("Show Tree for Matrix");
-          item.addActionListener(new ActionListener()
-          {
+          AnnotationColourChooser.displayFor(ap.av, ap, alignmentAnnotation,
+                  true);
+        };
+      });
+      pop.add(item);
+    }
+    item = new JMenuItem(
+            MessageManager.getString("action.select_by_annotation"));
+    item.addActionListener(new ActionListener()
+    {
 
-            @Override
-            public void actionPerformed(ActionEvent e)
-            {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        AnnotationColumnChooser.displayFor(ap.av, ap, alignmentAnnotation);
+      };
+    });
+    pop.add(item);
+  }
 
-                ap.alignFrame.showContactMapTree(aa[selectedRow],cm);
+  static void addContactMatrixOptions(final AlignmentPanel ap,
+          final AlignmentAnnotation alignmentAnnotation,
+          final JPopupMenu pop)
+  {
 
-            }
-          });
-          pop.addSeparator();
-          pop.add(item);
-        }
+    final ContactMatrixI cm = ap.av.getContactMatrix(alignmentAnnotation);
+    JMenuItem item;
+    if (cm != null)
+    {
+      pop.addSeparator();
+
+      if (cm.hasGroups())
+      {
+        JCheckBoxMenuItem chitem = new JCheckBoxMenuItem(
+                MessageManager.getString("action.show_groups_on_matrix"));
+        chitem.setToolTipText(MessageManager
+                .getString("action.show_groups_on_matrix_tooltip"));
+        boolean showGroups = alignmentAnnotation
+                .isShowGroupsForContactMatrix();
+        final AlignmentAnnotation sel_row = alignmentAnnotation;
+        chitem.setState(showGroups);
+        chitem.addActionListener(new ActionListener()
+        {
+
+          @Override
+          public void actionPerformed(ActionEvent e)
+          {
+            sel_row.setShowGroupsForContactMatrix(chitem.getState());
+            // so any annotation colour changes are propagated - though they
+            // probably won't be unless the annotation row colours are removed
+            // too!
+            ap.alignmentChanged();
+          }
+        });
+        pop.add(chitem);
+      }
+      if (cm.hasTree())
+      {
+        item = new JMenuItem(
+                MessageManager.getString("action.show_tree_for_matrix"));
+        item.setToolTipText(MessageManager
+                .getString("action.show_tree_for_matrix_tooltip"));
+        item.addActionListener(new ActionListener()
+        {
+
+          @Override
+          public void actionPerformed(ActionEvent e)
+          {
 
+            ap.alignFrame.showContactMapTree(alignmentAnnotation, cm);
+
+          }
+        });
+        pop.add(item);
+      }
+      else
+      {
+        item = new JMenuItem(
+                MessageManager.getString("action.cluster_matrix"));
+        item.setToolTipText(
+                MessageManager.getString("action.cluster_matrix_tooltip"));
+        item.addActionListener(new ActionListener()
+        {
+          @Override
+          public void actionPerformed(ActionEvent e)
+          {
+            new Thread(new Runnable()
+            {
+              @Override
+              public void run()
+              {
+                final long progBar;
+                ap.alignFrame.setProgressBar(
+                        MessageManager.formatMessage(
+                                "action.clustering_matrix_for",
+                                cm.getAnnotDescr(), 5f),
+                        progBar = System.currentTimeMillis());
+                cm.setGroupSet(GroupSet.makeGroups(cm, true));
+                cm.randomlyReColourGroups();
+                cm.transferGroupColorsTo(alignmentAnnotation);
+                ap.alignmentChanged();
+                ap.alignFrame.showContactMapTree(alignmentAnnotation, cm);
+                ap.alignFrame.setProgressBar(null, progBar);
+              }
+            }).start();
+          }
+        });
+        pop.add(item);
       }
     }
-    pop.show(this, evt.getX(), evt.getY());
   }
 
   /**
@@ -1038,8 +1168,7 @@ public class AnnotationLabels extends JPanel
               RenderingHints.VALUE_ANTIALIAS_ON);
     }
 
-    drawComponent(g2, true, width);
-
+    drawComponent(g2, true, width, true);
   }
 
   /**
@@ -1054,7 +1183,7 @@ public class AnnotationLabels extends JPanel
    */
   public void drawComponent(Graphics g, int width)
   {
-    drawComponent(g, false, width);
+    drawComponent(g, false, width, true);
   }
 
   /**
@@ -1069,32 +1198,148 @@ public class AnnotationLabels extends JPanel
    * @param width
    *          Width for scaling labels
    */
-  public void drawComponent(Graphics g, boolean clip, int width)
+  public void drawComponent(Graphics g, boolean clip, int givenWidth, boolean forGUI)
   {
-    if (av.getFont().getSize() < 10)
+    int width = givenWidth;
+    IdwidthAdjuster iwa = null;
+    if (ap != null)
     {
-      g.setFont(font);
+      iwa = ap.idwidthAdjuster;
+      if ((Cache.getDefault(ADJUST_ANNOTATION_LABELS_WIDTH_PREF, true)
+              || Jalview.isHeadlessMode()))
+      {
+        Graphics2D g2d = (Graphics2D) g;
+        Graphics dummy = g2d.create();
+        int newAnnotationIdWidth = drawLabels(dummy, clip, width, false, forGUI,
+                null);
+        dummy.dispose();
+        Dimension d = ap.calculateDefaultAlignmentIdWidth();
+        int alignmentIdWidth = d.width;
+        if (iwa != null && !iwa.manuallyAdjusted())
+        {
+          // If no manual adjustment to ID column with has been made then adjust
+          // width match widest of alignment or annotation id widths
+          boolean allowShrink = Cache.getDefault("ALLOW_SHRINK_ID_WIDTH",
+                  false);
+          width = Math.max(alignmentIdWidth, newAnnotationIdWidth);
+          if (clip && width < givenWidth && !allowShrink)
+          {
+            width = givenWidth;
+          }
+        }
+        else if (newAnnotationIdWidth != annotationIdWidth
+                && newAnnotationIdWidth > givenWidth
+                && newAnnotationIdWidth > alignmentIdWidth)
+        {
+          // otherwise if the annotation id width has become larger than the
+          // current id width, increase
+          width = newAnnotationIdWidth;
+          annotationIdWidth = newAnnotationIdWidth;
+        }
+        // set the width if it's changed
+        if (width != ap.av.getIdWidth())
+        {
+          iwa.setWidth(width);
+        }
+      }
     }
     else
     {
-      g.setFont(av.getFont());
+      int newAnnotationIdWidth = drawLabels(g, clip, width, false, forGUI, null);
+      width = Math.max(newAnnotationIdWidth, givenWidth);
     }
+    drawLabels(g, clip, width, true, forGUI, null);
+  }
 
-    FontMetrics fm = g.getFontMetrics(g.getFont());
-    g.setColor(Color.white);
-    g.fillRect(0, 0, getWidth(), getHeight());
+  /**
+   * Render the full set of annotation Labels for the alignment at the given
+   * cursor. If actuallyDraw is false or g is null then no actual drawing will
+   * occur, but the widest label width will be returned. If g is null then
+   * fmetrics must be supplied.
+   * 
+   * Returns the width of the annotation labels.
+   * 
+   * @param g
+   *          Graphics2D instance (used for rendering and font scaling if no fmetrics supplied) 
+   * @param clip
+   *          - true indicates that only current visible area needs to be
+   *          rendered
+   * @param width
+   *          Width for scaling labels
+   * @param actuallyDraw - when false, no graphics are rendered to g0
+   * @param forGUI - when false, GUI relevant marks like indicators for dragging annotation panel height are not rendered
+   * @param fmetrics
+   *          FontMetrics if Graphics object g is null
+   */
+  public int drawLabels(Graphics g0, boolean clip, int width,
+          boolean actuallyDraw, boolean forGUI, FontMetrics fmetrics)
+  {
+    if (clip)
+    {
+      clip = Cache.getDefault("MOVE_SEQUENCE_ID_WITH_VISIBLE_ANNOTATIONS",
+              true);
+    }
+    Graphics g = null;
+    // create a dummy Graphics object if not drawing and one is supplied
+    if (g0 != null)
+    {
+      if (!actuallyDraw)
+      {
+        Graphics2D g2d = (Graphics2D) g0;
+        g = g2d.create();
+      }
+      else
+      {
+        g = g0;
+      }
+    }
+    int actualWidth = 0;
+    if (g != null)
+    {
+      if (av.getFont().getSize() < 10)
+      {
+        g.setFont(font);
+      }
+      else
+      {
+        g.setFont(av.getFont());
+      }
+    }
+
+    FontMetrics fm = fmetrics == null ? g.getFontMetrics(g.getFont())
+            : fmetrics;
+    if (actuallyDraw)
+    {
+      g.setColor(Color.white);
+      g.fillRect(0, 0, getWidth(), getHeight());
+
+      if (!Cache.getDefault(RESIZE_MARGINS_MARK_PREF, false)
+              && !av.getWrapAlignment() && forGUI)
+      {
+        g.setColor(Color.LIGHT_GRAY);
+        g.drawLine(0, HEIGHT_ADJUSTER_HEIGHT / 4, HEIGHT_ADJUSTER_WIDTH / 4,
+                HEIGHT_ADJUSTER_HEIGHT / 4);
+        g.drawLine(0, 3 * HEIGHT_ADJUSTER_HEIGHT / 4,
+                HEIGHT_ADJUSTER_WIDTH / 4, 3 * HEIGHT_ADJUSTER_HEIGHT / 4);
+
+      }
+    }
 
-    g.translate(0, getScrollOffset());
-    g.setColor(Color.black);
+    if (actuallyDraw)
+    {
+      g.translate(0, getScrollOffset());
+      g.setColor(Color.black);
+    }
     SequenceI lastSeqRef = null;
     String lastLabel = null;
     AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation();
-    int fontHeight = g.getFont().getSize();
+    int fontHeight = g != null ? g.getFont().getSize()
+            : fm.getFont().getSize();
     int y = 0;
     int x = 0;
     int graphExtras = 0;
     int offset = 0;
-    Font baseFont = g.getFont();
+    Font baseFont = g != null ? g.getFont() : fm.getFont();
     FontMetrics baseMetrics = fm;
     int ofontH = fontHeight;
     int sOffset = 0;
@@ -1123,7 +1368,8 @@ public class AnnotationLabels extends JPanel
         }
         olY = y;
         // look ahead to next annotation
-        for (nexAA=i+1; nexAA<aa.length && !aa[nexAA].visible; nexAA++)
+        for (nexAA = i + 1; nexAA < aa.length
+                && !aa[nexAA].visible; nexAA++)
           ;
         y += aa[i].height;
         if (clip)
@@ -1134,7 +1380,7 @@ public class AnnotationLabels extends JPanel
             {
               if (debugRedraw)
               {
-                System.out.println("before vis: " + i);
+                jalview.bin.Console.outPrintln("before vis: " + i);
               }
               before = true;
             }
@@ -1148,7 +1394,7 @@ public class AnnotationLabels extends JPanel
             {
               if (debugRedraw)
               {
-                System.out.println(
+                jalview.bin.Console.outPrintln(
                         "Scroll offset: " + sOffset + " after vis: " + i);
               }
               after = true;
@@ -1157,8 +1403,10 @@ public class AnnotationLabels extends JPanel
             continue;
           }
         }
-        g.setColor(Color.black);
-
+        if (actuallyDraw && g != null)
+        {
+          g.setColor(Color.black);
+        }
         offset = -aa[i].height / 2;
 
         if (aa[i].hasText)
@@ -1203,7 +1451,9 @@ public class AnnotationLabels extends JPanel
             vertBar = true;
           }
         }
-        x = width - fm.stringWidth(label) - 3;
+
+        int labelWidth = fm.stringWidth(label) + 3;
+        x = width - labelWidth;
 
         if (aa[i].graphGroup > -1)
         {
@@ -1236,10 +1486,15 @@ public class AnnotationLabels extends JPanel
               s = ((float) fontHeight) / (float) ofontH;
               Font f = baseFont
                       .deriveFont(AffineTransform.getScaleInstance(s, s));
-              g.setFont(f);
-              fm = g.getFontMetrics();
-              graphExtras = (aa[i].height - (groupSize * (fontHeight + 8)))
-                      / 2;
+              Canvas c = new Canvas();
+              fm = c.getFontMetrics(f);
+              if (actuallyDraw && g != null)
+              {
+                g.setFont(f);
+                // fm = g.getFontMetrics();
+                graphExtras = (aa[i].height
+                        - (groupSize * (fontHeight + 8))) / 2;
+              }
             }
           }
           if (visible)
@@ -1248,57 +1503,81 @@ public class AnnotationLabels extends JPanel
             {
               if (aa[gg].graphGroup == aa[i].graphGroup)
               {
-                x = width - fm.stringWidth(aa[gg].label) - 3;
-                g.drawString(aa[gg].label, x, y - graphExtras);
-
-                if (aa[gg]._linecolour != null)
+                labelWidth = fm.stringWidth(aa[gg].label) + 3;
+                x = width - labelWidth;
+                if (actuallyDraw && g != null)
                 {
+                  g.drawString(aa[gg].label, x, y - graphExtras);
 
-                  g.setColor(aa[gg]._linecolour);
-                  g.drawLine(x, y - graphExtras + 3,
-                          x + fm.stringWidth(aa[gg].label),
-                          y - graphExtras + 3);
-                }
+                  if (aa[gg]._linecolour != null)
+                  {
+
+                    g.setColor(aa[gg]._linecolour);
+                    g.drawLine(x, y - graphExtras + 3,
+                            x + fm.stringWidth(aa[gg].label),
+                            y - graphExtras + 3);
+                  }
 
-                g.setColor(Color.black);
+                  g.setColor(Color.black);
+                }
                 graphExtras += fontHeight + 8;
               }
             }
           }
-          g.setFont(baseFont);
+          if (actuallyDraw && g != null)
+          {
+            g.setFont(baseFont);
+          }
           fm = baseMetrics;
           fontHeight = ofontH;
         }
         else
         {
-          if (vertBar)
+          if (actuallyDraw && g != null)
           {
-            g.drawLine(width-3, y + offset-fontHeight, width-3, (int)(y - 1.5*aa[i].height-offset-fontHeight));
-            // g.drawLine(20, y + offset, x - 20, y + offset);
+            if (vertBar)
+            {
+              g.drawLine(width - 3, y + offset - fontHeight, width - 3,
+                      (int) (y - 1.5 * aa[i].height - offset - fontHeight));
+              // g.drawLine(20, y + offset, x - 20, y + offset);
 
+            }
+            g.drawString(label, x, y + offset);
           }
-          g.drawString(label, x, y + offset);
         }
         lastSeqRef = aa[i].sequenceRef;
+
+        if (labelWidth > actualWidth)
+        {
+          actualWidth = labelWidth;
+        }
       }
     }
 
     if (!resizePanel && dragEvent != null && aa != null)
     {
-      g.setColor(Color.lightGray);
-      g.drawString(
-              (aa[selectedRow].sequenceRef == null ? ""
-                      : aa[selectedRow].sequenceRef.getName())
-                      + aa[selectedRow].label,
-              dragEvent.getX(), dragEvent.getY() - getScrollOffset());
+      if (actuallyDraw && g != null)
+      {
+        g.setColor(Color.lightGray);
+        g.drawString(
+                (aa[selectedRow].sequenceRef == null ? ""
+                        : aa[selectedRow].sequenceRef.getName())
+                        + aa[selectedRow].label,
+                dragEvent.getX(), dragEvent.getY() - getScrollOffset());
+      }
     }
 
     if (!av.getWrapAlignment() && ((aa == null) || (aa.length < 1)))
     {
-      g.drawString(MessageManager.getString("label.right_click"), 2, 8);
-      g.drawString(MessageManager.getString("label.to_add_annotation"), 2,
-              18);
+      if (actuallyDraw && g != null)
+      {
+        g.drawString(MessageManager.getString("label.right_click"), 2, 8);
+        g.drawString(MessageManager.getString("label.to_add_annotation"), 2,
+                18);
+      }
     }
+
+    return actualWidth;
   }
 
   public int getScrollOffset()
@@ -1310,4 +1589,9 @@ public class AnnotationLabels extends JPanel
   public void mouseEntered(MouseEvent e)
   {
   }
+
+  public void drawComponentNotGUI(Graphics idGraphics, int idWidth)
+  {
+    drawComponent(idGraphics, false, idWidth, false);
+  }
 }
index eeda585..8a957bc 100755 (executable)
@@ -72,6 +72,7 @@ import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.viewmodel.ViewportListenerI;
 import jalview.viewmodel.ViewportRanges;
+import jalview.ws.datamodel.MappableContactMatrixI;
 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 
 /**
@@ -605,7 +606,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     }
     else
     {
-      // no row (or row that can be adjusted) was pressed. Simulate a ruler click
+      // no row (or row that can be adjusted) was pressed. Simulate a ruler
+      // click
       ap.getScalePanel().mousePressed(evt);
     }
   }
@@ -655,7 +657,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       fr = Math.min(cXci.cStart, cXci.cEnd);
       to = Math.max(cXci.cStart, cXci.cEnd);
 
-      if (evt.isControlDown())
+      // double click selects the whole group
+      if (evt.getClickCount() == 2)
       {
         ContactMatrixI matrix = av.getContactMatrix(clicked);
 
@@ -665,23 +668,48 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
           if (matrix.hasGroups())
           {
             SequenceI rseq = clicked.sequenceRef;
-            BitSet grp = matrix.getGroupsFor(currentX);
+            BitSet grp = new BitSet();
+            grp.or(matrix.getGroupsFor(currentX));
+            // TODO: cXci needs to be mapped to real groups
             for (int c = fr; c <= to; c++)
             {
               BitSet additionalGrp = matrix.getGroupsFor(c);
               grp.or(additionalGrp);
             }
+
             HiddenColumns hc = av.getAlignment().getHiddenColumns();
-            for (int p = grp.nextSetBit(0); p >= 0; p = grp
+            ColumnSelection cs = av.getColumnSelection();
+            
+            for (int p=grp.nextSetBit(0); p >= 0; p = grp
                     .nextSetBit(p + 1))
             {
-              int offp = (rseq != null)
-                      ? rseq.findIndex(rseq.getStart() - 1 + p)
-                      : p;
-
-              if (!av.hasHiddenColumns() || hc.isVisible(offp))
+              if (matrix instanceof MappableContactMatrixI)
               {
-                av.getColumnSelection().addElement(offp);
+                // find the end of this run of set bits
+                int nextp = grp.nextClearBit(p)-1;
+                int[] pos = ((MappableContactMatrixI)matrix).getMappedPositionsFor(rseq, p,nextp);
+                p=nextp;
+                
+                if (pos!=null)
+                {
+                  for (int pos_p = pos[0];pos_p<=pos[1];pos_p++)
+                  {
+                    int col = rseq.findIndex(pos_p)-1;
+                    if (col>=0 && (!av.hasHiddenColumns() || hc.isVisible(col)))
+                    {
+                      cs.addElement(col);
+                    }
+                  }
+                }
+              } else {
+                int offp = (rseq != null)
+                        ? rseq.findIndex(rseq.getStart() - 1 + p)
+                        : p;
+  
+                if (!av.hasHiddenColumns() || hc.isVisible(offp))
+                {
+                  cs.addElement(offp);
+                }
               }
             }
           }
@@ -696,18 +724,20 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       {
         // select corresponding range in segment under mouse
         {
-          for (int c = fr; c <= to; c++)
+          int[] rng = forCurrentX.getMappedPositionsFor(fr, to);
+          if (rng != null)
           {
-            av.getColumnSelection().addElement(c);
+            av.getColumnSelection().addRangeOfElements(rng, true);
           }
           av.getColumnSelection().addElement(currentX);
         }
         // PAE SPECIFIC
         // and also select everything lower than the max range adjacent
         // (kind of works)
-        if (PAEContactMatrix.PAEMATRIX.equals(clicked.getCalcId()))
+        if (evt.isControlDown()
+                && PAEContactMatrix.PAEMATRIX.equals(clicked.getCalcId()))
         {
-          int c = fr - 1;
+          int c = fr;
           ContactRange cr = forCurrentX.getRangeFor(fr, to);
           double cval;
           // TODO: could use GraphLine instead of arbitrary picking
@@ -717,18 +747,23 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
           // controls feathering - what other elements in row/column
           // should we select
           double thresh = cr.getMean() + (cr.getMax() - cr.getMean()) * .15;
-          while (c > 0)
+          while (c >= 0)
           {
             cval = forCurrentX.getContactAt(c);
             if (// cr.getMin() <= cval &&
             cval <= thresh)
             {
-              av.getColumnSelection().addElement(c--);
-            }
-            else
-            {
-              break;
+              int[] cols = forCurrentX.getMappedPositionsFor(c, c);
+              if (cols != null)
+              {
+                av.getColumnSelection().addRangeOfElements(cols, true);
+              }
+              else
+              {
+                break;
+              }
             }
+            c--;
           }
           c = to;
           while (c < forCurrentX.getContactHeight())
@@ -737,12 +772,18 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
             if (// cr.getMin() <= cval &&
             cval <= thresh)
             {
-              av.getColumnSelection().addElement(c++);
+              int[] cols = forCurrentX.getMappedPositionsFor(c, c);
+              if (cols != null)
+              {
+                av.getColumnSelection().addRangeOfElements(cols, true);
+              }
             }
             else
             {
               break;
             }
+            c++;
+
           }
         }
       }
@@ -752,6 +793,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     av.sendSelection();
     return true;
   }
+
   /**
    * Construct and display a context menu at the right-click position
    * 
@@ -1016,7 +1058,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     }
     if (rowIndex[0] != toRowIndex[0])
     {
-      jalview.bin.Console.trace("Drag went to another row. needs to be clipped");
+      jalview.bin.Console
+              .trace("Drag went to another row. needs to be clipped");
     }
 
     // rectangular selection on matrix style annotation
@@ -1035,46 +1078,65 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       ContactGeometry lastXcgeom = new ContactGeometry(forFromX,
               cma.graphHeight);
       ContactGeometry.contactInterval lastXci = lastXcgeom
-              .mapFor(rowIndex[1], rowIndex[1] - deltaY);
+              .mapFor(rowIndex[1], rowIndex[1] + deltaY);
 
       ContactGeometry cXcgeom = new ContactGeometry(forToX,
               cma.graphHeight);
       ContactGeometry.contactInterval cXci = cXcgeom.mapFor(rowIndex[1],
-              rowIndex[1] - deltaY);
+              rowIndex[1] + deltaY);
 
       // mark rectangular region formed by drag
-      jalview.bin.Console.trace("Matrix Selection from last(" + fromXc + ",["
-              + lastXci.cStart + "," + lastXci.cEnd + "]) to cur(" + toXc
-              + ",[" + cXci.cStart + "," + cXci.cEnd + "])");
+      jalview.bin.Console.trace("Matrix Selection from last(" + fromXc
+              + ",[" + lastXci.cStart + "," + lastXci.cEnd + "]) to cur("
+              + toXc + ",[" + cXci.cStart + "," + cXci.cEnd + "])");
       int fr, to;
       fr = Math.min(lastXci.cStart, lastXci.cEnd);
       to = Math.max(lastXci.cStart, lastXci.cEnd);
-      jalview.bin.Console.trace("Marking " + fr + " to " + to);
-      for (int c = fr; c <= to; c++)
+      int[] mappedPos = forFromX.getMappedPositionsFor(fr, to);
+      if (mappedPos != null)
       {
-        if (cma.sequenceRef != null)
+        jalview.bin.Console.trace("Marking " + fr + " to " + to
+                + " mapping to sequence positions " + mappedPos[0] + " to "
+                + mappedPos[1]);
+        for (int pair = 0; pair < mappedPos.length; pair += 2)
         {
-          int col = cma.sequenceRef.findIndex(c);
-          av.getColumnSelection().addElement(col);
-        }
-        else
-        {
-          av.getColumnSelection().addElement(c);
+          for (int c = mappedPos[pair]; c <= mappedPos[pair + 1]; c++)
+          // {
+          // if (cma.sequenceRef != null)
+          // {
+          // int col = cma.sequenceRef.findIndex(cma.sequenceRef.getStart()+c);
+          // av.getColumnSelection().addElement(col);
+          // }
+          // else
+          {
+            av.getColumnSelection().addElement(c);
+          }
         }
       }
+      // and again for most recent corner of drag
       fr = Math.min(cXci.cStart, cXci.cEnd);
       to = Math.max(cXci.cStart, cXci.cEnd);
-      jalview.bin.Console.trace("Marking " + fr + " to " + to);
-      for (int c = fr; c <= to; c++)
+      mappedPos = forFromX.getMappedPositionsFor(fr, to);
+      if (mappedPos != null)
       {
-        if (cma.sequenceRef != null)
+        for (int pair = 0; pair < mappedPos.length; pair += 2)
         {
-          int col = cma.sequenceRef.findIndex(c);
-          av.getColumnSelection().addElement(col);
-        }
-        else
-        {
-          av.getColumnSelection().addElement(c);
+          jalview.bin.Console.trace("Marking " + fr + " to " + to
+                  + " mapping to sequence positions " + mappedPos[pair]
+                  + " to " + mappedPos[pair + 1]);
+          for (int c = mappedPos[pair]; c <= mappedPos[pair + 1]; c++)
+          {
+            // if (cma.sequenceRef != null)
+            // {
+            // int col =
+            // cma.sequenceRef.findIndex(cma.sequenceRef.getStart()+c);
+            // av.getColumnSelection().addElement(col);
+            // }
+            // else
+            {
+              av.getColumnSelection().addElement(c);
+            }
+          }
         }
       }
       fr = Math.min(lastX, currentX);
@@ -1185,7 +1247,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       {
         row = i;
         res[0] = row;
-        res[1] = height - yPos;
+        res[1] = yPos-lheight;
         break;
       }
     }
@@ -1239,6 +1301,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     // TODO abstract tooltip generator so different implementations can be built
     if (ann.graph == AlignmentAnnotation.CONTACT_MAP)
     {
+      if (rowAndOffset>=ann.graphHeight)
+      {
+        return null;
+      }
       ContactListI clist = av.getContactList(ann, column);
       if (clist != null)
       {
@@ -1247,12 +1313,28 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         ContactRange cr = clist.getRangeFor(ci.cStart, ci.cEnd);
         tooltip = "Contact from " + clist.getPosition() + ", [" + ci.cStart
                 + " - " + ci.cEnd + "]" + "<br/>Mean:" + cr.getMean();
+
         int col = ann.sequenceRef.findPosition(column);
+        int[][] highlightPos;
+        int[] mappedPos = clist.getMappedPositionsFor(ci.cStart, ci.cEnd);
+        if (mappedPos != null)
+        {
+          highlightPos = new int[1 + mappedPos.length][2];
+          highlightPos[0] = new int[] { col, col };
+          for (int p = 0, h = 0; p < mappedPos.length; h++, p += 2)
+          {
+            highlightPos[h][0] = ann.sequenceRef
+                    .findPosition(mappedPos[p] - 1);
+            highlightPos[h][1] = ann.sequenceRef
+                    .findPosition(mappedPos[p + 1] - 1);
+          }
+        }
+        else
+        {
+          highlightPos = new int[][] { new int[] { col, col } };
+        }
         ap.getStructureSelectionManager()
-                .highlightPositionsOn(ann.sequenceRef, new int[][]
-                { new int[] { col, col },
-                    new int[]
-                    { ci.cStart, ci.cEnd } }, null);
+                .highlightPositionsOn(ann.sequenceRef, highlightPos, null);
       }
     }
     return tooltip;
@@ -1404,8 +1486,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         return;
       }
     }
-    imgWidth = (av.getRanges().getEndRes() - av.getRanges().getStartRes()
-            + 1) * av.getCharWidth();
+    updateFadedImageWidth();
     if (imgWidth < 1)
     {
       return;
@@ -1426,7 +1507,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
           tried = true;
         } catch (IllegalArgumentException exc)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Serious issue with viewport geometry imgWidth requested was "
                           + imgWidth);
           return;
@@ -1473,6 +1554,13 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     g.drawImage(image, 0, 0, this);
   }
 
+  public void updateFadedImageWidth()
+  {
+    imgWidth = (av.getRanges().getEndRes() - av.getRanges().getStartRes()
+            + 1) * av.getCharWidth();
+
+  }
+
   /**
    * set true to enable redraw timing debug output on stderr
    */
@@ -1562,7 +1650,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
               && (fadedImage == null || fadedImage.getWidth() != imgWidth
                       || fadedImage.getHeight() != image.getHeight()))
       {
-        // System.err.println("redraw faded image ("+(fadedImage==null ?
+        // jalview.bin.Console.errPrintln("redraw faded image ("+(fadedImage==null ?
         // "null image" : "") + " lastGood="+lastImageGood+")");
         fadedImage = new BufferedImage(imgWidth, image.getHeight(),
                 BufferedImage.TYPE_INT_RGB);
@@ -1648,6 +1736,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
   @Override
   public int getFadedImageWidth()
   {
+    updateFadedImageWidth();
     return imgWidth;
   }
 
index 2447a2f..950f129 100644 (file)
  */
 package jalview.gui;
 
-import java.util.Locale;
-
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
 import java.io.File;
+import java.lang.reflect.InvocationTargetException;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
 
 import javax.swing.JPanel;
 import javax.swing.JSplitPane;
@@ -43,15 +51,17 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.StructureViewerModel;
 import jalview.datamodel.StructureViewerModel.StructureData;
-import jalview.fts.service.alphafold.AlphafoldRestClient;
 import jalview.gui.ImageExporter.ImageWriterI;
 import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.structure.StructureCommand;
 import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.BrowserLauncher;
 import jalview.util.ImageMaker;
+import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.util.imagemaker.BitmapImageSizing;
 
 public class AppJmol extends StructureViewerBase
 {
@@ -361,9 +371,9 @@ public class AppJmol extends StructureViewerBase
       }
       if (waitTotal > waitMax)
       {
-        System.err.println("Timed out waiting for Jmol to load files after "
+        jalview.bin.Console.errPrintln("Timed out waiting for Jmol to load files after "
                 + waitTotal + "ms");
-        // System.err.println("finished: " + jmb.isFinishedInit()
+        // jalview.bin.Console.errPrintln("finished: " + jmb.isFinishedInit()
         // + "; loaded: " + Arrays.toString(jmb.getPdbFile())
         // + "; files: " + files.toString());
         jmb.getStructureFiles();
@@ -424,21 +434,93 @@ public class AppJmol extends StructureViewerBase
   @Override
   public void makePDBImage(ImageMaker.TYPE type)
   {
+    try {
+    makePDBImage(null, type, null,
+            BitmapImageSizing.nullBitmapImageSizing());
+    } catch (ImageOutputException ioex) {
+      Console.error("Unexpected error whilst writing "+type.toString(),ioex);
+    }
+  }
+
+  public void makePDBImage(File file, ImageMaker.TYPE type, String renderer,
+          BitmapImageSizing userBis) throws ImageOutputException
+  {
     int width = getWidth();
     int height = getHeight();
+
+    BitmapImageSizing bis = ImageMaker.getScaleWidthHeight(width, height,
+            userBis);
+    float usescale = bis.scale;
+    int usewidth = bis.width;
+    int useheight = bis.height;
+
     ImageWriterI writer = new ImageWriterI()
     {
       @Override
       public void exportImage(Graphics g) throws Exception
       {
-        jmb.jmolViewer.renderScreenImage(g, width, height);
+        Graphics2D ig2 = (Graphics2D) g;
+        ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+        if (type == TYPE.PNG && usescale > 0.0f)
+        {
+          // for a scaled image, this scales down a bigger image to give the
+          // right resolution
+          if (usescale > 0.0f)
+          {
+            ig2.scale(1 / usescale, 1 / usescale);
+          }
+        }
+
+        jmb.jmolViewer.antialiased = true;
+        jmb.jmolViewer.requestRepaintAndWait("image export");
+        jmb.jmolViewer.renderScreenImage(ig2, usewidth, useheight);
       }
     };
     String view = MessageManager.getString("action.view")
             .toLowerCase(Locale.ROOT);
-    ImageExporter exporter = new ImageExporter(writer,
+    final ImageExporter exporter = new ImageExporter(writer,
             getProgressIndicator(), type, getTitle());
-    exporter.doExport(null, this, width, height, view);
+    
+    final Throwable[] exceptions = new Throwable[1];
+    exceptions[0] = null;
+    final AppJmol us = this;
+    try
+    {
+      Thread runner = Executors.defaultThreadFactory().newThread(new Runnable()
+      {
+        @Override
+        public void run()
+        {
+          try
+          {
+            exporter.doExport(file, us, width, height, view, renderer,
+                    userBis);
+          } catch (Throwable t)
+          {
+            exceptions[0] = t;
+          }
+        }
+      });
+      runner.start();
+      do { Thread.sleep(25); } while (runner.isAlive());
+    } catch (Throwable e)
+    {
+      throw new ImageOutputException(
+              "Unexpected error when generating image", e);
+    }
+    if (exceptions[0] != null)
+    {
+      if (exceptions[0] instanceof ImageOutputException)
+      {
+        throw ((ImageOutputException) exceptions[0]);
+      }
+      else
+      {
+        throw new ImageOutputException(
+                "Unexpected error when generating image", exceptions[0]);
+      }
+    }
   }
 
   @Override
@@ -450,7 +532,7 @@ public class AppJmol extends StructureViewerBase
               .openURL("http://wiki.jmol.org");// http://jmol.sourceforge.net/docs/JmolUserGuide/");
     } catch (Exception ex)
     {
-      System.err.println("Show Jmol help failed with: " + ex.getMessage());
+      jalview.bin.Console.errPrintln("Show Jmol help failed with: " + ex.getMessage());
     }
   }
 
index 3f8175d..158bb54 100644 (file)
@@ -34,7 +34,7 @@ import org.openscience.jmol.app.jmolpanel.console.AppConsole;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Console;
-import jalview.datamodel.AlignmentI;
+import jalview.bin.Jalview;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JalviewJmolBinding;
@@ -42,9 +42,6 @@ import jalview.io.DataSourceType;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
-import jalview.ws.dbsources.EBIAlfaFold;
-import jalview.ws.dbsources.Pdb;
-import jalview.ws.utils.UrlDownloadClient;
 import javajs.util.BS;
 
 public class AppJmolBinding extends JalviewJmolBinding
@@ -156,7 +153,7 @@ public class AppJmolBinding extends JalviewJmolBinding
   {
     jmolViewer.setJmolCallbackListener(this);
     // BH comment: can't do this yet [for JS only, or generally?]
-    return Platform.isJS() ? null
+    return Platform.isJS() || Jalview.isHeadlessMode() ? null
             : new AppConsole(jmolViewer, consolePanel, buttonsToShow);
   }
 
index 6fac8fc..eb2368d 100644 (file)
@@ -476,7 +476,7 @@ public class AppVarna extends JInternalFrame
       if (shift != null)
       {
         int i = shift.shift(newBase.getIndex());
-        // System.err.println("shifted "+(arg1.getIndex())+" to "+i);
+        // jalview.bin.Console.errPrintln("shifted "+(arg1.getIndex())+" to "+i);
         ssm.mouseOverVamsasSequence(seq, i, this);
       }
       else
index 5cfe72a..8951df0 100644 (file)
@@ -574,7 +574,7 @@ public class AppVarnaBinding extends JalviewVarnaBinding
     } catch (ExceptionNAViewAlgorithm e)
     {
       // only throwable for draw mode = 3 NAView
-      System.err.println("Error drawing RNA: " + e.getMessage());
+      jalview.bin.Console.errPrintln("Error drawing RNA: " + e.getMessage());
     }
   }
 }
index 420e2cb..c9951f5 100644 (file)
@@ -49,19 +49,20 @@ public class AssociatePdbFileWithSeq
           StructureSelectionManagerProvider ssmp)
   {
     return associatePdbWithSeq(choice, file, sequence, prompt, ssmp,
-            TFType.DEFAULT, null);
+            TFType.DEFAULT, null, true);
   }
 
   public PDBEntry associatePdbWithSeq(String choice, DataSourceType file,
           SequenceI sequence, boolean prompt,
           StructureSelectionManagerProvider ssmp, TFType tft,
-          String paeFilename)
+          String paeFilename, boolean doXferSettings)
   {
     PDBEntry entry = new PDBEntry();
     StructureFile pdbfile = StructureSelectionManager
             .getStructureSelectionManager(ssmp)
             .setMapping(false, new SequenceI[]
-            { sequence }, null, choice, file, tft, paeFilename);
+            { sequence }, null, choice, file, tft, paeFilename,
+                    doXferSettings);
     if (pdbfile == null)
     {
       // stacktrace already thrown so just return
index af59ca7..c120a1b 100644 (file)
@@ -772,7 +772,7 @@ public class BlogReader extends JPanel
       String formattedDate = Cache.setDateProperty(
               "JALVIEW_NEWS_RSS_LASTMODIFIED", lastread.getTime());
       BlogReader me = new BlogReader();
-      System.out.println("Set last date to " + formattedDate);
+      jalview.bin.Console.outPrintln("Set last date to " + formattedDate);
       if (me.isNewsNew())
       {
         Console.debug("There is news to read.");
index cc6a785..f13e151 100644 (file)
@@ -343,7 +343,7 @@ public class ChimeraViewFrame extends StructureViewerBase
       boolean opened = jmb.openSession(chimeraSessionFile);
       if (!opened)
       {
-        System.err.println("An error occurred opening Chimera session file "
+        jalview.bin.Console.errPrintln("An error occurred opening Chimera session file "
                 + chimeraSessionFile);
       }
     }
index c1c75f1..574ba28 100644 (file)
@@ -304,7 +304,7 @@ public class ColourMenuHelper
         }
       } catch (Exception ex)
       {
-        System.out.println("Error loading User ColourFile\n" + ex);
+        jalview.bin.Console.outPrintln("Error loading User ColourFile\n" + ex);
       }
     }
 
index 5a23048..6a6cb56 100644 (file)
@@ -433,20 +433,20 @@ public class Console extends WindowAdapter
     // you may omit this part for your application
     //
 
-    System.out.println("Hello World 2");
-    System.out.println("All fonts available to Graphic2D:\n");
+    jalview.bin.Console.outPrintln("Hello World 2");
+    jalview.bin.Console.outPrintln("All fonts available to Graphic2D:\n");
     GraphicsEnvironment ge = GraphicsEnvironment
             .getLocalGraphicsEnvironment();
     String[] fontNames = ge.getAvailableFontFamilyNames();
     for (int n = 0; n < fontNames.length; n++)
     {
-      System.out.println(fontNames[n]);
+      jalview.bin.Console.outPrintln(fontNames[n]);
     }
     // Testing part: simple an error thrown anywhere in this JVM will be printed
     // on the Console
     // We do it with a seperate Thread becasue we don't wan't to break a Thread
     // used by the Console.
-    System.out.println("\nLets throw an error on this console");
+    jalview.bin.Console.outPrintln("\nLets throw an error on this console");
     errorThrower = new Thread(this);
     errorThrower.setDaemon(true);
     errorThrower.start();
index c15cf2d..6cb59c3 100644 (file)
@@ -432,7 +432,7 @@ public class CrossRefAction implements Runnable
                 MessageManager.getString("label.cant_map_cds"),
                 MessageManager.getString("label.operation_failed"),
                 JvOptionPane.OK_OPTION);
-        System.err.println("Failed to make CDS alignment");
+        jalview.bin.Console.errPrintln("Failed to make CDS alignment");
         return null;
       }
 
@@ -466,7 +466,7 @@ public class CrossRefAction implements Runnable
 
     if (copyAlignment.getHeight() <= 0)
     {
-      System.err.println("No Sequences generated for xRef type " + source);
+      jalview.bin.Console.errPrintln("No Sequences generated for xRef type " + source);
       return null;
     }
 
index 1521d0a..035da25 100644 (file)
@@ -51,6 +51,7 @@ import java.awt.event.WindowEvent;
 import java.awt.geom.AffineTransform;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.beans.PropertyVetoException;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
@@ -63,8 +64,8 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Vector;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Semaphore;
@@ -122,6 +123,7 @@ import jalview.io.FormatAdapter;
 import jalview.io.IdentifyFile;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.jbgui.GSplitFrame;
 import jalview.jbgui.GStructureViewer;
 import jalview.project.Jalview2XML;
@@ -435,9 +437,14 @@ public class Desktop extends jalview.jbgui.GDesktop
     {
       if (LaunchUtils.getJavaVersion() >= 11)
       {
-        jalview.bin.Console.info(
+        /*
+         * Send this message to stderr as the warning that follows (due to
+         * reflection) also goes to stderr.
+         */
+        jalview.bin.Console.errPrintln(
                 "Linux platform only! You may have the following warning next: \"WARNING: An illegal reflective access operation has occurred\"\nThis is expected and cannot be avoided, sorry about that.");
       }
+      final String awtAppClassName = "awtAppClassName";
       try
       {
         Toolkit xToolkit = Toolkit.getDefaultToolkit();
@@ -445,10 +452,10 @@ public class Desktop extends jalview.jbgui.GDesktop
         Field awtAppClassNameField = null;
 
         if (Arrays.stream(declaredFields)
-                .anyMatch(f -> f.getName().equals("awtAppClassName")))
+                .anyMatch(f -> f.getName().equals(awtAppClassName)))
         {
           awtAppClassNameField = xToolkit.getClass()
-                  .getDeclaredField("awtAppClassName");
+                  .getDeclaredField(awtAppClassName);
         }
 
         String title = ChannelProperties.getProperty("app_name");
@@ -459,11 +466,12 @@ public class Desktop extends jalview.jbgui.GDesktop
         }
         else
         {
-          jalview.bin.Console.debug("XToolkit: awtAppClassName not found");
+          jalview.bin.Console
+                  .debug("XToolkit: " + awtAppClassName + " not found");
         }
       } catch (Exception e)
       {
-        jalview.bin.Console.debug("Error setting awtAppClassName");
+        jalview.bin.Console.debug("Error setting " + awtAppClassName);
         jalview.bin.Console.trace(Cache.getStackTraceString(e));
       }
     }
@@ -530,6 +538,9 @@ public class Desktop extends jalview.jbgui.GDesktop
       setBounds(xPos, yPos, 900, 650);
     }
 
+    // start dialogue queue for single dialogues
+    startDialogQueue();
+
     if (!Platform.isJS())
     /**
      * Java only
@@ -563,15 +574,16 @@ public class Desktop extends jalview.jbgui.GDesktop
       }
 
       // Thread off a new instance of the file chooser - this reduces the time
-      // it
-      // takes to open it later on.
+      // it takes to open it later on.
       new Thread(new Runnable()
       {
         @Override
         public void run()
         {
           jalview.bin.Console.debug("Filechooser init thread started.");
-          String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+          String fileFormat = FileLoader.getUseDefaultFileFormat()
+                  ? Cache.getProperty("DEFAULT_FILE_FORMAT")
+                  : null;
           JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
                   fileFormat);
           jalview.bin.Console.debug("Filechooser init thread finished.");
@@ -617,6 +629,12 @@ public class Desktop extends jalview.jbgui.GDesktop
       }
     });
     desktop.addMouseListener(ma);
+
+    if (Platform.isJS())
+    {
+      // used for jalviewjsTest
+      jalview.bin.Console.info("JALVIEWJS: CREATED DESKTOP");
+    }
   }
 
   /**
@@ -808,7 +826,7 @@ public class Desktop extends jalview.jbgui.GDesktop
     // TODO - write tests and fix AlignFrame.paste() which doesn't track if
     // clipboard has come from a different alignment window than the one where
     // paste has been called! JAL-4151
-    
+
     if (Desktop.jalviewClipboard != null)
     {
       // The clipboard was filled from within Jalview, we must use the
@@ -835,30 +853,32 @@ public class Desktop extends jalview.jbgui.GDesktop
       }
 
       Desktop.addInternalFrame(af, newtitle, AlignFrame.DEFAULT_WIDTH,
-            AlignFrame.DEFAULT_HEIGHT);
+              AlignFrame.DEFAULT_HEIGHT);
 
-    } else {
-    try
+    }
+    else
     {
-      Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
-      Transferable contents = c.getContents(this);
-
-      if (contents != null)
+      try
       {
-        String file = (String) contents
-                .getTransferData(DataFlavor.stringFlavor);
+        Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
+        Transferable contents = c.getContents(this);
+
+        if (contents != null)
+        {
+          String file = (String) contents
+                  .getTransferData(DataFlavor.stringFlavor);
 
-        FileFormatI format = new IdentifyFile().identify(file,
-                DataSourceType.PASTE);
+          FileFormatI format = new IdentifyFile().identify(file,
+                  DataSourceType.PASTE);
 
-        new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
+          new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
 
+        }
+      } catch (Exception ex)
+      {
+        jalview.bin.Console.outPrintln(
+                "Unable to paste alignment from system clipboard:\n" + ex);
       }
-    } catch (Exception ex)
-    {
-      System.out.println(
-              "Unable to paste alignment from system clipboard:\n" + ex);
-    }
     }
   }
 
@@ -1061,7 +1081,36 @@ public class Desktop extends jalview.jbgui.GDesktop
 
     setKeyBindings(frame);
 
-    desktop.add(frame);
+    // Since the latest FlatLaf patch, we occasionally have problems showing structureViewer frames...
+    int tries=3;
+    boolean shown=false;
+    Exception last=null;
+    do
+    {
+      try
+      {
+        desktop.add(frame);
+        shown=true;
+      } catch (IllegalArgumentException iaex)
+      {
+        last=iaex;
+        tries--;
+        jalview.bin.Console.info(
+                "Squashed IllegalArgument Exception (" + tries + " left) for "+frame.getTitle(),
+                iaex);
+        try
+        {
+          Thread.sleep(5);
+        } catch (InterruptedException iex)
+        {
+        }
+        ;
+      }
+    } while (!shown && tries > 0);
+    if (!shown)
+    {
+      jalview.bin.Console.error("Serious Problem whilst showing window "+frame.getTitle(),last);
+    }
 
     windowMenu.add(menuItem);
 
@@ -1221,7 +1270,9 @@ public class Desktop extends jalview.jbgui.GDesktop
   @Override
   public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
   {
-    String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+    String fileFormat = FileLoader.getUseDefaultFileFormat()
+            ? Cache.getProperty("DEFAULT_FILE_FORMAT")
+            : null;
     JalviewFileChooser chooser = JalviewFileChooser.forRead(
             Cache.getProperty("LAST_DIRECTORY"), fileFormat,
             BackupFiles.getEnabled());
@@ -1256,7 +1307,6 @@ public class Desktop extends jalview.jbgui.GDesktop
 
       new FileLoader().LoadFile(viewport, selectedFile, DataSourceType.FILE,
               format);
-      return null;
     });
     chooser.showOpenDialog(this);
   }
@@ -1312,7 +1362,7 @@ public class Desktop extends jalview.jbgui.GDesktop
 
     Object[] options = new Object[] { MessageManager.getString("action.ok"),
         MessageManager.getString("action.cancel") };
-    Callable<Void> action = () -> {
+    Runnable action = () -> {
       @SuppressWarnings("unchecked")
       String url = (history instanceof JTextField
               ? ((JTextField) history).getText()
@@ -1351,8 +1401,7 @@ public class Desktop extends jalview.jbgui.GDesktop
           JvOptionPane.showInternalMessageDialog(Desktop.desktop, msg,
                   MessageManager.getString("label.url_not_found"),
                   JvOptionPane.WARNING_MESSAGE);
-
-          return null; // Void
+          return;
         }
 
         if (viewport != null)
@@ -1365,7 +1414,6 @@ public class Desktop extends jalview.jbgui.GDesktop
           new FileLoader().LoadFile(url, DataSourceType.URL, format);
         }
       }
-      return null; // Void
     };
     String dialogOption = MessageManager
             .getString("label.input_alignment_from_url");
@@ -1404,7 +1452,7 @@ public class Desktop extends jalview.jbgui.GDesktop
 
   public QuitHandler.QResponse desktopQuit(boolean ui, boolean disposeFlag)
   {
-    final Callable<Void> doDesktopQuit = () -> {
+    final Runnable doDesktopQuit = () -> {
       Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
       Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
       Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
@@ -1430,7 +1478,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       if (QuitHandler.quitCancelled())
       {
         jalview.bin.Console.debug("Desktop aborting quit");
-        return null;
+        return;
       }
 
       if (dialogExecutor != null)
@@ -1459,8 +1507,6 @@ public class Desktop extends jalview.jbgui.GDesktop
         // instance.dispose();
       }
       instance.quit();
-
-      return null; // Void
     };
 
     return QuitHandler.getQuitResponse(ui, doDesktopQuit, doDesktopQuit,
@@ -1476,7 +1522,7 @@ public class Desktop extends jalview.jbgui.GDesktop
     // this will run the shutdownHook but QuitHandler.getQuitResponse() should
     // not run a second time if gotQuitResponse flag has been set (i.e. user
     // confirmed quit of some kind).
-    System.exit(0);
+    Jalview.exit("Desktop exiting.", 0);
   }
 
   private void storeLastKnownDimensions(String string, Rectangle jc)
@@ -1589,7 +1635,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       }
     } catch (Exception ex)
     {
-      System.err.println("Error opening help: " + ex.getMessage());
+      jalview.bin.Console.errPrintln("Error opening help: " + ex.getMessage());
     }
   }
 
@@ -1608,7 +1654,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       }
     }
     Jalview.setCurrentAlignFrame(null);
-    System.out.println("ALL CLOSED");
+    jalview.bin.Console.info("ALL CLOSED");
 
     /*
      * reset state of singleton objects as appropriate (clear down session state
@@ -1820,7 +1866,7 @@ public class Desktop extends jalview.jbgui.GDesktop
     boolean autoSave = projectFile != null && !saveAs
             && BackupFiles.getEnabled();
 
-    // System.out.println("autoSave="+autoSave+", projectFile='"+projectFile+"',
+    // jalview.bin.Console.outPrintln("autoSave="+autoSave+", projectFile='"+projectFile+"',
     // saveAs="+saveAs+", Backups
     // "+(BackupFiles.getEnabled()?"enabled":"disabled"));
 
@@ -1959,7 +2005,6 @@ public class Desktop extends jalview.jbgui.GDesktop
           }
         }
       }, "Project Loader").start();
-      return null;
     });
 
     chooser.showOpenDialog(this);
@@ -3049,7 +3094,7 @@ public class Desktop extends jalview.jbgui.GDesktop
   /**
    * pause the queue
    */
-  private java.util.concurrent.Semaphore block = new Semaphore(0);
+  private Semaphore block = new Semaphore(0);
 
   private static groovy.ui.Console groovyConsole;
 
@@ -3067,12 +3112,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       {
         if (dialogPause)
         {
-          try
-          {
-            block.acquire();
-          } catch (InterruptedException x)
-          {
-          }
+          acquireDialogQueue();
         }
         if (instance == null)
         {
@@ -3090,12 +3130,41 @@ public class Desktop extends jalview.jbgui.GDesktop
     });
   }
 
+  private boolean dialogQueueStarted = false;
+
   public void startDialogQueue()
   {
+    if (dialogQueueStarted)
+    {
+      return;
+    }
     // set the flag so we don't pause waiting for another permit and semaphore
     // the current task to begin
-    dialogPause = false;
+    releaseDialogQueue();
+    dialogQueueStarted = true;
+  }
+
+  public void acquireDialogQueue()
+  {
+    try
+    {
+      block.acquire();
+      dialogPause = true;
+    } catch (InterruptedException e)
+    {
+      jalview.bin.Console.debug("Interruption when acquiring DialogueQueue",
+              e);
+    }
+  }
+
+  public void releaseDialogQueue()
+  {
+    if (!dialogPause)
+    {
+      return;
+    }
     block.release();
+    dialogPause = false;
   }
 
   /**
@@ -3130,7 +3199,15 @@ public class Desktop extends jalview.jbgui.GDesktop
     String title = "View of desktop";
     ImageExporter exporter = new ImageExporter(writer, null, TYPE.EPS,
             title);
-    exporter.doExport(of, this, width, height, title);
+    try
+    {
+      exporter.doExport(of, this, width, height, title);
+    } catch (ImageOutputException ioex)
+    {
+      jalview.bin.Console.error(
+              "Unexpected error whilst writing Jalview desktop snapshot as EPS",
+              ioex);
+    }
   }
 
   /**
@@ -3338,7 +3415,7 @@ public class Desktop extends jalview.jbgui.GDesktop
         {
           if (Platform.isAMacAndNotJS())
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Please ignore plist error - occurs due to problem with java 8 on OSX");
           }
         }
@@ -3570,4 +3647,87 @@ public class Desktop extends jalview.jbgui.GDesktop
       jalview.bin.Console.debug(Cache.getStackTraceString(e));
     }
   }
+
+  /**
+   * closes the current instance window, disposes and forgets about it.
+   */
+  public static void closeDesktop()
+  {
+    if (Desktop.instance != null)
+    {
+      Desktop.instance.closeAll_actionPerformed(null);
+      Desktop.instance.setVisible(false);
+      Desktop us = Desktop.instance;
+      Desktop.instance = null;
+      // call dispose in a separate thread - try to avoid indirect deadlocks
+      new Thread(new Runnable() {
+        @Override
+        public void run()
+        {
+          ExecutorService dex = us.dialogExecutor;
+          if (dex!=null) {
+            dex.shutdownNow();
+            us.dialogExecutor=null;
+            us.block.drainPermits();
+          }
+          us.dispose();
+        }
+      }).start();
+    }
+  }
+
+  /**
+   * checks if any progress bars are being displayed in any of the windows
+   * managed by the desktop
+   * 
+   * @return
+   */
+  public boolean operationsAreInProgress()
+  {
+    JInternalFrame[] frames = getAllFrames();
+    for (JInternalFrame frame : frames)
+    {
+      if (frame instanceof IProgressIndicator)
+      {
+        if (((IProgressIndicator) frame).operationInProgress())
+        {
+          return true;
+        }
+      }
+    }
+    return operationInProgress();
+  }
+
+  /**
+   * keep track of modal JvOptionPanes open as modal dialogs for AlignFrames.
+   * The way the modal JInternalFrame is made means it cannot be a child of an
+   * AlignFrame, so closing the AlignFrame might leave the modal open :(
+   */
+  private static Map<AlignFrame, JInternalFrame> alignFrameModalMap = new HashMap<>();
+
+  protected static void addModal(AlignFrame af, JInternalFrame jif)
+  {
+    alignFrameModalMap.put(af, jif);
+  }
+
+  protected static void closeModal(AlignFrame af)
+  {
+    if (!alignFrameModalMap.containsKey(af))
+    {
+      return;
+    }
+    JInternalFrame jif = alignFrameModalMap.get(af);
+    if (jif != null)
+    {
+      try
+      {
+        jif.setClosed(true);
+      } catch (PropertyVetoException e)
+      {
+        e.printStackTrace();
+      }
+    }
+    alignFrameModalMap.remove(af);
+  }
+
 }
index ff0fe3a..6d5cb46 100644 (file)
@@ -22,7 +22,6 @@ package jalview.gui;
 
 import java.awt.FlowLayout;
 import java.awt.Font;
-import java.util.concurrent.Callable;
 
 import javax.swing.BoxLayout;
 import javax.swing.JButton;
@@ -87,7 +86,7 @@ public class EditNameDialog
     panel.add(descriptionPanel);
 
     JLabel nameLabel = new JLabel(label1);
-    nameLabel.setFont(COURIER_12);
+    // nameLabel.setFont(COURIER_12);
     namePanel.add(nameLabel);
 
     id = new JTextField(name, 40);
@@ -101,7 +100,7 @@ public class EditNameDialog
     if (desc != null || label2 != null)
     {
       JLabel descLabel = new JLabel(label2);
-      descLabel.setFont(COURIER_12);
+      // descLabel.setFont(COURIER_12);
       descriptionPanel.add(descLabel);
       descriptionPanel.add(description);
     }
@@ -112,14 +111,24 @@ public class EditNameDialog
    * 
    * @param action
    */
-  public void showDialog(JComponent parent, String title, Callable action)
+  public void showDialog(JComponent parent, String title, Runnable action)
   {
-    Object[] options = new Object[] { MessageManager.getString("action.ok"),
-        MessageManager.getString("action.cancel") };
-    JvOptionPane.newOptionDialog(parent).setResponseHandler(0, action)
-            .showInternalDialog(panel, title,
-                    JvOptionPane.YES_NO_CANCEL_OPTION,
-                    JvOptionPane.PLAIN_MESSAGE, null, options,
-                    MessageManager.getString("action.ok"));
+    String ok = MessageManager.getString("action.ok");
+    String cancel = MessageManager.getString("action.cancel");
+    String[] options = new String[] { ok, cancel };
+
+    JvOptionPane.newOptionDialog(parent)
+            .setResponseHandler(JvOptionPane.OK_OPTION, action)
+            .showInternalDialog(panel, title, JvOptionPane.OK_CANCEL_OPTION,
+                    JvOptionPane.PLAIN_MESSAGE, null, options, ok);
+
+    /*
+    List<Runnable> actions = new ArrayList<>();
+    actions.add(action);
+    actions.add(JvOptionPane.NULLCALLABLE);
+    
+    JvOptionPane.frameDialog(panel, title, JvOptionPane.PLAIN_MESSAGE,
+            options, ok, actions, false);
+    */
   }
 }
index ba9da67..7117508 100644 (file)
@@ -33,7 +33,6 @@ import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.Callable;
 
 import javax.swing.JComboBox;
 import javax.swing.JLabel;
@@ -428,9 +427,8 @@ public class FeatureEditor
    */
   public void showDialog()
   {
-    Callable<Void> okAction = forCreate ? getCreateAction()
-            : getAmendAction();
-    Callable<Void> cancelAction = getCancelAction();
+    Runnable okAction = forCreate ? getCreateAction() : getAmendAction();
+    Runnable cancelAction = getCancelAction();
 
     /*
      * set dialog action handlers for OK (create/Amend) and Cancel options
@@ -476,12 +474,11 @@ public class FeatureEditor
    * 
    * @return
    */
-  protected Callable getCancelAction()
+  protected Runnable getCancelAction()
   {
-    Callable<Void> okAction = () -> {
+    Runnable okAction = () -> {
       ap.highlightSearchResults(null);
       ap.paintAlignment(false, false);
-      return null;
     };
     return okAction;
   }
@@ -496,14 +493,14 @@ public class FeatureEditor
    * 
    * @return
    */
-  protected Callable getCreateAction()
+  protected Runnable getCreateAction()
   {
-    Callable<Void> okAction = new Callable()
+    Runnable okAction = new Runnable()
     {
       boolean useLastDefaults = features.get(0).getType() == null;
 
       @Override
-      public Void call()
+      public void run()
       {
         final String enteredType = name.getText().trim();
         final String enteredGroup = group.getText().trim();
@@ -543,7 +540,6 @@ public class FeatureEditor
 
           repaintPanel();
         }
-        return null;
       }
     };
     return okAction;
@@ -556,15 +552,14 @@ public class FeatureEditor
    * 
    * @return
    */
-  protected Callable getDeleteAction()
+  protected Runnable getDeleteAction()
   {
-    Callable<Void> deleteAction = () -> {
+    Runnable deleteAction = () -> {
       SequenceFeature sf = features.get(featureIndex);
       sequences.get(0).getDatasetSequence().deleteFeature(sf);
       fr.featuresAdded();
       ap.getSeqPanel().seqCanvas.highlightSearchResults(null);
       ap.paintAlignment(true, true);
-      return null;
     };
     return deleteAction;
   }
@@ -655,9 +650,9 @@ public class FeatureEditor
    * 
    * @return
    */
-  protected Callable getAmendAction()
+  protected Runnable getAmendAction()
   {
-    Callable<Void> okAction = new Callable()
+    Runnable okAction = new Runnable()
     {
       boolean useLastDefaults = features.get(0).getType() == null;
 
@@ -666,7 +661,7 @@ public class FeatureEditor
       String featureGroup = group.getText();
 
       @Override
-      public Void call()
+      public void run()
       {
         final String enteredType = name.getText().trim();
         final String enteredGroup = group.getText().trim();
@@ -729,7 +724,6 @@ public class FeatureEditor
           fr.featuresAdded();
         }
         repaintPanel();
-        return null;
       }
     };
     return okAction;
index 2c8f47a..184fdc5 100644 (file)
@@ -951,7 +951,6 @@ public class FeatureSettings extends JPanel
     chooser.setResponseHandler(0, () -> {
       File file = chooser.getSelectedFile();
       load(file);
-      return null;
     });
     chooser.showOpenDialog(this);
   }
@@ -1020,7 +1019,7 @@ public class FeatureSettings extends JPanel
       }
     } catch (Exception ex)
     {
-      System.out.println("Error loading User Colour File\n" + ex);
+      jalview.bin.Console.outPrintln("Error loading User Colour File\n" + ex);
     }
   }
 
@@ -1609,7 +1608,7 @@ public class FeatureSettings extends JPanel
     {
       Color newColor = gcol.getMaxColour();
       comp.setBackground(newColor);
-      // System.err.println("Width is " + w / 2);
+      // jalview.bin.Console.errPrintln("Width is " + w / 2);
       Icon ficon = new FeatureIcon(gcol, comp.getBackground(), w, h, thr);
       comp.setIcon(ficon);
       // tt+="RGB value: Max (" + newColor.getRed() + ", "
index 09bb2a3..327f6ca 100644 (file)
@@ -1096,7 +1096,7 @@ public class FeatureTypeSettings extends JalviewDialog
   {
     if (featureSettings != null)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "IMPLEMENTATION ISSUE: overwriting action listener for FeatureColourChooser");
     }
     featureSettings = listener;
index 658b34f..8829be9 100644 (file)
@@ -133,7 +133,7 @@ public class Help
         hb.setCurrentID(id.getId());
       } catch (BadIDException bad)
       {
-        System.out.println("Bad help link: " + id.getId()
+        jalview.bin.Console.outPrintln("Bad help link: " + id.getId()
                 + ": must match a target in help.jhm");
         throw bad;
       }
index 68a7a1e..2faea01 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.gui;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
+import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
@@ -201,7 +202,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
 
     gg.translate(0, transY);
 
-    drawIds(gg, av, ss, es, searchResults);
+    drawIds(gg, av, ss, es, searchResults,true);
 
     gg.translate(0, -transY);
 
@@ -258,7 +259,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
     gg.fillRect(0, 0, getWidth(), imgHeight);
 
     drawIds(gg, av, av.getRanges().getStartSeq(),
-            av.getRanges().getEndSeq(), searchResults);
+            av.getRanges().getEndSeq(), searchResults,true);
 
     gg.dispose();
 
@@ -278,7 +279,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
    * @param selection
    */
   void drawIds(Graphics2D g, AlignViewport alignViewport,
-          final int startSeq, final int endSeq, List<SequenceI> selection)
+          final int startSeq, final int endSeq, List<SequenceI> selection, boolean forGUI)
   {
     Font font = alignViewport.getFont();
     if (alignViewport.isSeqNameItalics())
@@ -424,6 +425,25 @@ public class IdCanvas extends JPanel implements ViewportListenerI
   void drawIdsWrapped(Graphics2D g, AlignViewport alignViewport,
           int startSeq, int pageHeight)
   {
+    drawIdsWrapped(g, alignViewport, startSeq, pageHeight, -1, true);
+  }
+
+  /**
+   * render sequence IDs and annotation labels when wrapped - without GUI junk
+   * @param g
+   * @param av2
+   * @param i
+   * @param totalHeight
+   */
+  public void drawIdsWrappedNoGUI(Graphics2D g, AlignViewport av2, int i,
+          int totalHeight)
+  {
+    drawIdsWrapped(g, av2, totalHeight, totalHeight, i,false);
+  }
+
+  void drawIdsWrapped(Graphics2D g, AlignViewport alignViewport,
+          int startSeq, int pageHeight, int idWidth, boolean forGUI)
+  {
     int alignmentWidth = alignViewport.getAlignment().getWidth();
     final int alheight = alignViewport.getAlignment().getHeight();
 
@@ -470,8 +490,23 @@ public class IdCanvas extends JPanel implements ViewportListenerI
 
       if (labels != null && alignViewport.isShowAnnotation())
       {
+        int getWidth = getWidth();
+        int thisIdWidth = getWidth;
         g.translate(0, ypos + (alheight * charHeight));
-        labels.drawComponent(g, getWidth());
+        if (!manuallyAdjusted())
+        {
+          int getAnnotationsIdWidth = labels.drawLabels(g, false, -1, false,forGUI,
+                  null);
+          thisIdWidth = idWidth < 0 ? getAnnotationsIdWidth : idWidth;
+          if (thisIdWidth > getWidth)
+          {
+            this.setPreferredSize(
+                    new Dimension(thisIdWidth, this.getHeight()));
+            this.repaint();
+            alignViewport.setIdWidth(thisIdWidth);
+          }
+        }
+        labels.drawComponent(g, false, thisIdWidth, forGUI);
         g.translate(0, -ypos - (alheight * charHeight));
       }
 
@@ -627,4 +662,17 @@ public class IdCanvas extends JPanel implements ViewportListenerI
       repaint();
     }
   }
+
+  private boolean manuallyAdjusted = false;
+
+  public boolean manuallyAdjusted()
+  {
+    return manuallyAdjusted;
+  }
+
+  public void setManuallyAdjusted(boolean b)
+  {
+    manuallyAdjusted = b;
+  }
+
 }
index 4ba0699..762612e 100755 (executable)
@@ -20,8 +20,6 @@
  */
 package jalview.gui;
 
-import jalview.api.AlignViewportI;
-
 import java.awt.Color;
 import java.awt.Cursor;
 import java.awt.Graphics;
@@ -31,6 +29,9 @@ import java.awt.event.MouseMotionListener;
 
 import javax.swing.JPanel;
 
+import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
+
 /**
  * DOCUMENT ME!
  * 
@@ -136,6 +137,18 @@ public class IdwidthAdjuster extends JPanel
       return;
     }
 
+    /*
+     * don't allow residue width to be < 1 in wrapped format
+     */
+    if (viewport.getWrapAlignment())
+    {
+      SeqCanvas sc = ap.getSeqPanel().seqCanvas;
+      if (sc != null && sc.getWrappedCanvasWidth(sc.getWidth() - dif) < 1)
+      {
+        return;
+      }
+    }
+
     oldX = evt.getX();
 
     /*
@@ -145,10 +158,41 @@ public class IdwidthAdjuster extends JPanel
     {
       return;
     }
+    
+    // TODO JAL-4260 - work out how to trigger recomputation of wrapped pages !
+    int curCol = viewport.getRanges().getStartRes()
+            + viewport.getRanges().getViewportWidth();
+    
+    viewport.setIdWidth(newWidth);
+
+    ap.validateAnnotationDimensions(false);
+    if (viewport.getWrapAlignment())
+    {
+      viewport.getRanges().scrollToWrappedVisible(
+              curCol - viewport.getRanges().getViewportWidth());
+    }
+    ap.paintAlignment(true, false);
+    
+    ap.getIdPanel().getIdCanvas().setManuallyAdjusted(true);
+  }
+
+  public void setWidth(int newWidth)
+  {
+    if (newWidth < MIN_ID_WIDTH
+            || ap.getIdPanel().getIdCanvas().manuallyAdjusted())
+    {
+      return;
+    }
+    final AlignViewportI viewport = ap.getAlignViewport();
     viewport.setIdWidth(newWidth);
     ap.paintAlignment(true, false);
   }
 
+  public boolean manuallyAdjusted()
+  {
+    return ap.getIdPanel().getIdCanvas().manuallyAdjusted();
+  }
+
   @Override
   public void mouseMoved(MouseEvent evt)
   {
@@ -167,8 +211,21 @@ public class IdwidthAdjuster extends JPanel
   @Override
   public void paintComponent(Graphics g)
   {
+    int width = getWidth();
+    int height = getHeight();
     g.setColor(Color.white);
-    g.fillRect(0, 0, getWidth(), getHeight());
+    g.fillRect(0, 0, width, height);
+
+    if (!Cache.getDefault(AnnotationLabels.RESIZE_MARGINS_MARK_PREF, false))
+    // && !ap.getAlignViewport().getWrapAlignment()) // now allowing adjustment
+    // in wrap mode
+    {
+      int spacer = Math.max(2, AnnotationLabels.HEIGHT_ADJUSTER_HEIGHT / 4);
+      g.setColor(Color.LIGHT_GRAY);
+      g.drawLine(width - 3 * spacer, 0, width - 3 * spacer, height / 2);
+      g.drawLine(width - spacer, 0, width - spacer, height / 2);
+    }
+
     setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
   }
 }
index d849ba2..8d28b1b 100644 (file)
@@ -23,17 +23,19 @@ package jalview.gui;
 import java.awt.Component;
 import java.awt.Graphics;
 import java.io.File;
-import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.util.ImageMaker;
 import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.util.StringUtils;
+import jalview.util.imagemaker.BitmapImageSizing;
 
 /**
  * A class that marshals steps in exporting a view in image graphics format
@@ -103,7 +105,15 @@ public class ImageExporter
    *          what the image is of e.g. Tree, Alignment
    */
   public void doExport(File file, Component parent, int width, int height,
-          String imageSource)
+          String imageSource) throws ImageOutputException
+  {
+    doExport(file, parent, width, height, imageSource, null,
+            BitmapImageSizing.nullBitmapImageSizing());
+  }
+
+  public void doExport(File file, Component parent, int width, int height,
+          String imageSource, String renderer, BitmapImageSizing userBis)
+          throws ImageOutputException
   {
     final long messageId = System.currentTimeMillis();
     setStatus(
@@ -116,6 +126,12 @@ public class ImageExporter
      */
     if (file == null && !Jalview.isHeadlessMode())
     {
+      if (Desktop.instance.isInBatchMode())
+      {
+        // defensive error report - we could wait for user input.. I guess ?
+        throw (new ImageOutputException(
+                "Need an output file to render to when exporting images in batch mode!"));
+      }
       JalviewFileChooser chooser = imageType.getFileChooser();
       chooser.setFileView(new JalviewFileView());
       MessageManager.formatMessage("label.create_image_of",
@@ -142,37 +158,31 @@ public class ImageExporter
      * for this as EPS_RENDERING / SVG_RENDERING
      * Always set to Text for JalviewJS as Lineart (glyph fonts) not available
      */
-    String renderStyle = Cache.getDefault(
-            imageType.getName() + "_RENDERING",
-            LineartOptions.PROMPT_EACH_TIME);
+    String renderStyle = renderer == null
+            ? Cache.getDefault(imageType.getName() + "_RENDERING",
+                    LineartOptions.PROMPT_EACH_TIME)
+            : renderer;
     if (Platform.isJS())
     {
       renderStyle = "Text";
     }
     AtomicBoolean textSelected = new AtomicBoolean(
-            !"Lineart".equals(renderStyle));
-    if ((imageType == TYPE.EPS || imageType == TYPE.SVG)
-            && LineartOptions.PROMPT_EACH_TIME.equals(renderStyle)
+            !StringUtils.equalsIgnoreCase("lineart", renderStyle));
+    if ((imageType == TYPE.EPS || imageType == TYPE.SVG) && StringUtils
+            .equalsIgnoreCase(LineartOptions.PROMPT_EACH_TIME, renderStyle)
             && !Jalview.isHeadlessMode())
     {
       final File chosenFile = file;
-      Callable<Void> okAction = () -> {
+      Runnable okAction = () -> {
         exportImage(chosenFile, !textSelected.get(), width, height,
-                messageId);
-        return null;
+                messageId, userBis);
       };
       LineartOptions epsOption = new LineartOptions(TYPE.EPS.getName(),
               textSelected);
-      epsOption.setResponseAction(1, new Callable<Void>()
-      {
-        @Override
-        public Void call()
-        {
-          setStatus(MessageManager.formatMessage(
-                  "status.cancelled_image_export_operation",
-                  imageType.getName()), messageId);
-          return null;
-        }
+      epsOption.setResponseAction(1, () -> {
+        setStatus(MessageManager.formatMessage(
+                "status.cancelled_image_export_operation",
+                imageType.getName()), messageId);
       });
       epsOption.setResponseAction(0, okAction);
       epsOption.showDialog();
@@ -181,10 +191,11 @@ public class ImageExporter
     else
     {
       /*
-       * character rendering not required, or preference already set 
-       * - just do the export
+       * character rendering not required, or preference already set
+       * or we're in headless mode - just do the export
        */
-      exportImage(file, !textSelected.get(), width, height, messageId);
+      exportImage(file, !textSelected.get(), width, height, messageId,
+              userBis);
     }
   }
 
@@ -200,7 +211,7 @@ public class ImageExporter
    * @param messageId
    */
   protected void exportImage(File chosenFile, boolean asLineart, int width,
-          int height, long messageId)
+          int height, long messageId, BitmapImageSizing userBis)
   {
     String type = imageType.getName();
     try
@@ -210,7 +221,7 @@ public class ImageExporter
       // "status.exporting_alignment_as_x_file", type),
       // messageId);
       ImageMaker im = new ImageMaker(imageType, width, height, chosenFile,
-              title, asLineart);
+              title, asLineart, userBis);
       imageWriter.exportImage(im.getGraphics());
       im.writeImage();
       setStatus(
@@ -218,8 +229,8 @@ public class ImageExporter
               messageId);
     } catch (Exception e)
     {
-      System.out.println(String.format("Error creating %s file: %s", type,
-              e.toString()));
+      jalview.bin.Console.error(String.format("Error creating %s file: %s",
+              type, e.toString()), e);
       setStatus(MessageManager.formatMessage("info.error_creating_file",
               type), messageId);
     }
index 327eade..9ae764e 100644 (file)
@@ -122,7 +122,7 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
         }
         else
         {
-          System.err.println("dupe ig for : " + dbs[i] + " \t"
+          jalview.bin.Console.errPrintln("dupe ig for : " + dbs[i] + " \t"
                   + dbp.getDbName() + " (" + dbp.getDbSource() + ")");
           source.remove(tn);
         }
@@ -552,7 +552,7 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
   @Override
   public void setVisible(boolean arg0)
   {
-    System.out.println("setVisible: " + arg0);
+    jalview.bin.Console.outPrintln("setVisible: " + arg0);
     super.setVisible(arg0);
   }
 }
index 020890b..5b926c3 100644 (file)
@@ -32,16 +32,17 @@ import java.awt.Toolkit;
 import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseMotionAdapter;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.beans.PropertyVetoException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -51,8 +52,11 @@ import javax.swing.JDialog;
 import javax.swing.JFrame;
 import javax.swing.JInternalFrame;
 import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
+import javax.swing.JRootPane;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
 import javax.swing.event.InternalFrameEvent;
@@ -60,6 +64,7 @@ import javax.swing.event.InternalFrameListener;
 
 import jalview.bin.Console;
 import jalview.util.ChannelProperties;
+import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.util.dialogrunner.DialogRunnerI;
 
@@ -72,13 +77,16 @@ public class JvOptionPane extends JOptionPane
 
   private static boolean interactiveMode = true;
 
+  public static final Runnable NULLCALLABLE = () -> {
+  };
+
   private Component parentComponent;
 
   private ExecutorService executor = Executors.newCachedThreadPool();
 
   private JDialog dialog = null;
 
-  private Map<Object, Callable<Void>> callbacks = new HashMap<>();
+  private Map<Object, Runnable> callbacks = new HashMap<>();
 
   /*
    * JalviewJS reports user choice in the dialog as the selected option (text);
@@ -714,7 +722,7 @@ public class JvOptionPane extends JOptionPane
 
   private static void outputMessage(Object message)
   {
-    System.out.println(">>> JOption Message : " + message.toString());
+    jalview.bin.Console.outPrintln(">>> JOption Message : " + message.toString());
   }
 
   public static Object getMockResponse()
@@ -855,7 +863,7 @@ public class JvOptionPane extends JOptionPane
             initialValueButton = jb;
 
           int buttonAction = buttonActions[i];
-          Callable<Void> action = callbacks.get(buttonAction);
+          Runnable action = callbacks.get(buttonAction);
           jb.setText((String) o);
           jb.addActionListener(new ActionListener()
           {
@@ -884,7 +892,7 @@ public class JvOptionPane extends JOptionPane
               JOptionPane joptionpane = (JOptionPane) joptionpaneObject;
               joptionpane.setValue(buttonAction);
               if (action != null)
-                getExecutor().submit(action);
+                new Thread(action).start();
               joptionpane.transferFocusBackward();
               joptionpane.setVisible(false);
               // put focus and raise parent window if possible, unless cancel or
@@ -980,7 +988,7 @@ public class JvOptionPane extends JOptionPane
         {
           Object o = options[i];
           int buttonAction = buttonActions[i];
-          Callable<Void> action = callbacks.get(buttonAction);
+          Runnable action = callbacks.get(buttonAction);
           JButton jb = new JButton();
           jb.setText((String) o);
           jb.addActionListener(new ActionListener()
@@ -991,7 +999,7 @@ public class JvOptionPane extends JOptionPane
             {
               joptionpane.setValue(buttonAction);
               if (action != null)
-                getExecutor().submit(action);
+                new Thread(action).start();
               // joptionpane.transferFocusBackward();
               joptionpane.transferFocusBackward();
               joptionpane.setVisible(false);
@@ -1047,7 +1055,7 @@ public class JvOptionPane extends JOptionPane
     }
   }
 
-  public void showInternalDialog(JPanel mainPanel, String title,
+  public void showInternalDialog(Object mainPanel, String title,
           int yesNoCancelOption, int questionMessage, Icon icon,
           Object[] options, String initresponse)
   {
@@ -1065,13 +1073,19 @@ public class JvOptionPane extends JOptionPane
     this.setMessage(mainPanel);
 
     ourOptions = Arrays.asList(options);
-    int response;
     if (parentComponent != this
             && !(parentComponent == null && Desktop.instance == null))
     {
+      // note the parent goes back to a JRootPane so is probably
+      // Desktop.getDesktop()
       JInternalFrame jif = this.createInternalFrame(
               parentComponent != null ? parentComponent : Desktop.instance,
               title);
+      // connect to the alignFrame using a map in Desktop
+      if (parentComponent instanceof AlignFrame)
+      {
+        Desktop.addModal((AlignFrame) parentComponent, jif);
+      }
       jif.setFrameIcon(null);
       jif.addInternalFrameListener(new InternalFrameListener()
       {
@@ -1127,7 +1141,13 @@ public class JvOptionPane extends JOptionPane
 
   private void internalDialogHandleResponse()
   {
-    String responseString = (String) this.getValue();
+    Object value = this.getValue();
+    if (value == null
+            || (value instanceof Integer && (Integer) value == -1))
+    {
+      return;
+    }
+    String responseString = value.toString();
     int response = ourOptions.indexOf(responseString);
 
     if (!Platform.isJS())
@@ -1149,25 +1169,16 @@ public class JvOptionPane extends JOptionPane
    * }
    */
   @Override
-  public JvOptionPane setResponseHandler(Object response,
-          Callable<Void> action)
+  public JvOptionPane setResponseHandler(Object response, Runnable action)
   {
+    if (action == null)
+    {
+      action = NULLCALLABLE;
+    }
     callbacks.put(response, action);
     return this;
   }
 
-  public ExecutorService getExecutor()
-  {
-    if (executor == null)
-      executor = Executors.newSingleThreadExecutor();
-    return executor;
-  }
-
-  public void setExecutor(ExecutorService es)
-  {
-    executor = es;
-  }
-
   public void setDialog(JDialog d)
   {
     dialog = d;
@@ -1311,12 +1322,12 @@ public class JvOptionPane extends JOptionPane
     {
       return;
     }
-    Callable<Void> action = callbacks.get(response);
+    Runnable action = callbacks.get(response);
     if (action != null)
     {
       try
       {
-        getExecutor().submit(action).get();
+        new Thread(action).start();
         // action.call();
       } catch (Exception e)
       {
@@ -1395,7 +1406,7 @@ public class JvOptionPane extends JOptionPane
       {
         Object o = options[i];
         int buttonAction = buttonActions[i];
-        Callable<Void> action = callbacks.get(buttonAction);
+        Runnable action = callbacks.get(buttonAction);
         JButton jb;
         if (buttons != null && buttons.length > i && buttons[i] != null)
         {
@@ -1413,7 +1424,7 @@ public class JvOptionPane extends JOptionPane
           {
             joptionpane.setValue(buttonAction);
             if (action != null)
-              getExecutor().submit(action);
+              new Thread(action).start();
             // joptionpane.transferFocusBackward();
             joptionpane.transferFocusBackward();
             joptionpane.setVisible(false);
@@ -1506,11 +1517,26 @@ public class JvOptionPane extends JOptionPane
     lp.add(modalInterceptor);
     f.toFront();
 
+    // disable the main menu bar if in Linux
+    JMenuBar menubar = null;
+    if (Platform.isLinux())
+    {
+      JRootPane rootpane = Desktop.getDesktop().getRootPane();
+      menubar = rootpane.getJMenuBar();
+    }
+
     // We need to explicitly dispatch events when we are blocking the event
     // dispatch thread.
     EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
     try
     {
+      if (menubar != null)
+      {
+        // don't allow clicks on main menu on linux due to a hanging bug.
+        // see JAL-4214.
+        setMenusEnabled(menubar, false);
+      }
+
       while (!f.isClosed())
       {
         if (EventQueue.isDispatchThread())
@@ -1522,11 +1548,25 @@ public class JvOptionPane extends JOptionPane
           // EventQueue.dispatchEvent() directly, because it is
           // protected, unfortunately.
           if (ev instanceof ActiveEvent)
+          {
             ((ActiveEvent) ev).dispatch();
-          else if (ev.getSource() instanceof Component)
+          }
+          else if (ev instanceof KeyEvent && ((KeyEvent) ev).isControlDown()
+                  && menubar != null)
+          {
+            // temporarily enable menus to send Ctrl+? KeyEvents
+            setMenusEnabled(menubar, true);
             ((Component) ev.getSource()).dispatchEvent(ev);
+            setMenusEnabled(menubar, false);
+          }
           else if (ev.getSource() instanceof MenuComponent)
+          {
             ((MenuComponent) ev.getSource()).dispatchEvent(ev);
+          }
+          else if (ev.getSource() instanceof Component)
+          {
+            ((Component) ev.getSource()).dispatchEvent(ev);
+          }
           // Other events are ignored as per spec in
           // EventQueue.dispatchEvent
         }
@@ -1541,23 +1581,56 @@ public class JvOptionPane extends JOptionPane
       // If we get interrupted, then leave the modal state.
     } finally
     {
+      // re-enable the main menu bar
+      if (menubar != null)
+      {
+        setMenusEnabled(menubar, true);
+      }
+
       // Clean up the modal interceptor.
       lp.remove(modalInterceptor);
 
+      // unpaint the frame
+      f.setVisible(false);
+
+      // close the frame
+      try
+      {
+        f.setClosed(true);
+      } catch (PropertyVetoException e)
+      {
+        f.doDefaultCloseAction();
+      }
+
       // Remove the internal frame from its parent, so it is no longer
       // lurking around and clogging memory.
       Container parent = f.getParent();
       if (parent != null)
+      {
         parent.remove(f);
+      }
     }
   }
 
-  public static JvOptionPane frameDialog(String message, String title,
-          int messageType, String[] buttonsText, String defaultButton,
-          Callable<Void>[] handlers, boolean modal)
+  public static JvOptionPane frameDialog(Object message, String title,
+          int messageType, String[] buttonsTextS, String defaultButtonS,
+          List<Runnable> handlers, boolean modal)
   {
     JFrame parent = new JFrame();
     JvOptionPane jvop = JvOptionPane.newOptionDialog();
+    final String[] buttonsText;
+    final String defaultButton;
+    if (buttonsTextS == null)
+    {
+      String ok = MessageManager.getString("action.ok");
+      buttonsText = new String[] { ok };
+      defaultButton = ok;
+    }
+    else
+    {
+      buttonsText = buttonsTextS;
+      defaultButton = defaultButtonS;
+    }
     JButton[] buttons = new JButton[buttonsText.length];
     for (int i = 0; i < buttonsText.length; i++)
     {
@@ -1581,23 +1654,39 @@ public class JvOptionPane extends JOptionPane
     {
       dialogType = JOptionPane.YES_NO_CANCEL_OPTION;
     }
-    jvop.setResponseHandler(JOptionPane.YES_OPTION, handlers[0]);
+    jvop.setResponseHandler(JOptionPane.YES_OPTION,
+            (handlers != null && handlers.size() > 0) ? handlers.get(0)
+                    : NULLCALLABLE);
     if (dialogType == JOptionPane.YES_NO_OPTION
             || dialogType == JOptionPane.YES_NO_CANCEL_OPTION)
     {
-      jvop.setResponseHandler(JOptionPane.NO_OPTION, handlers[1]);
+      jvop.setResponseHandler(JOptionPane.NO_OPTION,
+              (handlers != null && handlers.size() > 1) ? handlers.get(1)
+                      : NULLCALLABLE);
     }
     if (dialogType == JOptionPane.YES_NO_CANCEL_OPTION)
     {
-      jvop.setResponseHandler(JOptionPane.CANCEL_OPTION, handlers[2]);
+      jvop.setResponseHandler(JOptionPane.CANCEL_OPTION,
+              (handlers != null && handlers.size() > 2) ? handlers.get(2)
+                      : NULLCALLABLE);
     }
 
     final int dt = dialogType;
-    jvop.getExecutor().execute(() -> {
+    new Thread(() -> {
       jvop.showDialog(message, title, dt, messageType, null, buttonsText,
               defaultButton, modal, buttons);
-    });
+    }).start();
 
     return jvop;
   }
+
+  private static void setMenusEnabled(JMenuBar menubar, boolean b)
+  {
+    for (int i = 0; i < menubar.getMenuCount(); i++)
+    {
+      JMenu menu = menubar.getMenu(i);
+      menu.setEnabled(b);
+    }
+  }
+
 }
index 8a530ac..2a96eb4 100644 (file)
@@ -23,7 +23,6 @@ package jalview.gui;
 import java.awt.FlowLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.swing.BorderFactory;
@@ -42,7 +41,7 @@ import jalview.util.MessageManager;
  */
 public class LineartOptions extends JPanel
 {
-  static final String PROMPT_EACH_TIME = "Prompt each time";
+  public static final String PROMPT_EACH_TIME = "Prompt each time";
 
   JvOptionPane dialog;
 
@@ -96,7 +95,7 @@ public class LineartOptions extends JPanel
    * 
    * @param action
    */
-  public void setResponseAction(Object response, Callable action)
+  public void setResponseAction(Object response, Runnable action)
   {
     dialog.setResponseHandler(response, action);
   }
index e0427cc..f05110f 100644 (file)
@@ -713,7 +713,7 @@ public class OptsAndParamsPage
             }
           } catch (NumberFormatException e)
           {
-            System.err.println(e.toString());
+            jalview.bin.Console.errPrintln(e.toString());
           }
           if (minValue != null || maxValue != null)
           {
@@ -750,7 +750,7 @@ public class OptsAndParamsPage
             }
           } catch (NumberFormatException e)
           {
-            System.err.println(e.toString());
+            jalview.bin.Console.errPrintln(e.toString());
           }
           if (minValue != null && maxValue != null)
           {
index 99dba3d..0827208 100644 (file)
@@ -95,8 +95,9 @@ public class OverviewCanvas extends JPanel
             OVERVIEW_DEFAULT_GAP);
     Color hiddenCol = Cache.getDefaultColour(Preferences.HIDDEN_COLOUR,
             OVERVIEW_DEFAULT_HIDDEN);
-    Color residueCol = useLegacy ? OVERVIEW_DEFAULT_LEGACY_RESIDUE : OVERVIEW_DEFAULT_RESIDUE;
-    
+    Color residueCol = useLegacy ? OVERVIEW_DEFAULT_LEGACY_RESIDUE
+            : OVERVIEW_DEFAULT_RESIDUE;
+
     cf = new OverviewResColourFinder(gapCol, residueCol, hiddenCol);
 
     setSize(od.getWidth(), od.getHeight());
index 26db8c3..211c370 100644 (file)
@@ -49,6 +49,7 @@ import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.SequenceI;
 import jalview.gui.ImageExporter.ImageWriterI;
 import jalview.gui.JalviewColourChooser.ColourChooserListener;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.jbgui.GPCAPanel;
 import jalview.math.RotatableMatrix.Axis;
 import jalview.util.ImageMaker;
@@ -438,7 +439,11 @@ public class PCAPanel extends GPCAPanel
     };
     String pca = MessageManager.getString("label.pca");
     ImageExporter exporter = new ImageExporter(writer, null, type, pca);
-    exporter.doExport(null, this, width, height, pca);
+    try {
+      exporter.doExport(null, this, width, height, pca);
+    } catch (ImageOutputException ioex) {
+      Console.error("Unexpected error whilst writing "+type.toString(),ioex);
+    }
   }
 
   @Override
index 953fdc5..36849b0 100755 (executable)
@@ -194,7 +194,7 @@ public class PaintRefresher
           {
             // raise an implementation warning here - not sure if this situation
             // will ever occur
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "IMPLEMENTATION PROBLEM: DATASET out of sync due to an insert whilst calling PaintRefresher.validateSequences(AlignmentI, ALignmentI)");
           }
           List<SequenceI> alsq = comp.getSequences();
index c4b5367..b5b6ffc 100755 (executable)
@@ -104,7 +104,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel
 
         if (!first)
         {
-          System.out.println(DASHES);
+          jalview.bin.Console.outPrintln(DASHES);
           textarea.append(DASHES);
         }
         first = false;
@@ -139,7 +139,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel
 
     for (int i = 0; i < seqs.length; i++)
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               String.format("%3d %s", i + 1, seqs[i].getDisplayId(true)));
     }
 
@@ -151,7 +151,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel
     {
       System.out.print(String.format("%7d", i + 1));
     }
-    System.out.println();
+    jalview.bin.Console.outPrintln();
 
     for (int i = 0; i < seqs.length; i++)
     {
@@ -163,10 +163,10 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel
          */
         System.out.print(String.format("%7.3f", scores[i][j] / totscore));
       }
-      System.out.println();
+      jalview.bin.Console.outPrintln();
     }
 
-    System.out.println("\n");
+    jalview.bin.Console.outPrintln("\n");
   }
 
   /**
index f50b72b..ca0fb7f 100644 (file)
@@ -937,6 +937,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     if (Platform.isJS())
     {
       details = new JInternalFrame();
+      details.setFrameIcon(null);
       JPanel panel = new JPanel(new BorderLayout());
       panel.setOpaque(true);
       panel.setBackground(Color.white);
@@ -1765,10 +1766,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   protected void addReferenceAnnotations_actionPerformed(
           Map<SequenceI, List<AlignmentAnnotation>> candidates)
   {
-    final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup();
     final AlignmentI alignment = this.ap.getAlignment();
     AlignmentUtils.addReferenceAnnotations(candidates, alignment,
-            selectionGroup);
+            null);
     refresh();
   }
 
@@ -1866,6 +1866,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       pane.setBackground(Color.WHITE);
       pane.add(textLabel, BorderLayout.NORTH);
       frame = new JInternalFrame();
+      frame.setFrameIcon(null);
       frame.getContentPane().add(new JScrollPane(pane));
     }
     else
@@ -2021,7 +2022,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
               sg.setName(dialog.getName());
               sg.setDescription(dialog.getDescription());
               refresh();
-              return null;
             });
   }
 
@@ -2059,12 +2059,17 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
               {
                 if (dialog.getName().indexOf(" ") > -1)
                 {
-                  JvOptionPane.showMessageDialog(ap,
-                          MessageManager.getString(
-                                  "label.spaces_converted_to_underscores"),
-                          MessageManager.getString(
-                                  "label.no_spaces_allowed_sequence_name"),
-                          JvOptionPane.WARNING_MESSAGE);
+                  String ok = MessageManager.getString("action.ok");
+                  String cancel = MessageManager.getString("action.cancel");
+                  String message = MessageManager.getString(
+                          "label.spaces_converted_to_underscores");
+                  String title = MessageManager.getString(
+                          "label.no_spaces_allowed_sequence_name");
+                  Object[] options = new Object[] { ok, cancel };
+
+                  JvOptionPane.frameDialog(message, title,
+                          JvOptionPane.WARNING_MESSAGE, null, null, null,
+                          false);
                 }
                 sequence.setName(dialog.getName().replace(' ', '_'));
                 ap.paintAlignment(false, false);
@@ -2072,7 +2077,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
               sequence.setDescription(dialog.getDescription());
               ap.av.firePropertyChange("alignment", null,
                       ap.av.getAlignment().getSequences());
-              return null;
             });
   }
 
@@ -2218,7 +2222,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
 
     String[] omitHidden = null;
 
-    System.out.println("PROMPT USER HERE"); // TODO: decide if a prompt happens
+    jalview.bin.Console.outPrintln("PROMPT USER HERE"); // TODO: decide if a prompt happens
     // or we simply trust the user wants
     // wysiwig behaviour
 
@@ -2307,7 +2311,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
                 ap.alignFrame.addHistoryItem(editCommand);
                 ap.av.firePropertyChange("alignment", null,
                         ap.av.getAlignment().getSequences());
-                return null;
               });
     }
   }
index 493deee..c4f32c3 100755 (executable)
@@ -156,6 +156,9 @@ public class Preferences extends GPreferences
   public static List<String> groupURLLinks;
   static
   {
+    // don't populate with session properties
+    Cache.disableSessionProperties();
+
     // get links selected to be in the menu (SEQUENCE_LINKS)
     // and links entered by the user but not selected (STORED_LINKS)
     String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
@@ -180,6 +183,9 @@ public class Preferences extends GPreferences
      */
 
     groupURLLinks = new ArrayList<>();
+
+    // reenable
+    Cache.enableSessionProperties();
   }
 
   JInternalFrame frame;
@@ -188,7 +194,7 @@ public class Preferences extends GPreferences
 
   private OptionsParam promptEachTimeOpt = new OptionsParam(
           MessageManager.getString("label.prompt_each_time"),
-          "Prompt each time");
+          LineartOptions.PROMPT_EACH_TIME);
 
   private OptionsParam lineArtOpt = new OptionsParam(
           MessageManager.getString("label.lineart"), "Lineart");
@@ -248,6 +254,9 @@ public class Preferences extends GPreferences
   private Preferences()
   {
     super();
+    // don't populate with session properties
+    Cache.disableSessionProperties();
+
     frame = new JInternalFrame();
     frame.setFrameIcon(null);
     frame.setContentPane(this);
@@ -689,6 +698,8 @@ public class Preferences extends GPreferences
      * Set Startup tab defaults
      */
 
+    // re-enable
+    Cache.enableSessionProperties();
   }
 
   /**
@@ -701,6 +712,8 @@ public class Preferences extends GPreferences
   protected void setupOutputCombo(JComboBox<Object> comboBox,
           String propertyKey)
   {
+    Cache.disableSessionProperties();
+
     comboBox.addItem(promptEachTimeOpt);
     comboBox.addItem(lineArtOpt);
     comboBox.addItem(textOpt);
@@ -722,6 +735,8 @@ public class Preferences extends GPreferences
     {
       comboBox.setSelectedItem(promptEachTimeOpt);
     }
+
+    Cache.enableSessionProperties();
   }
 
   /**
@@ -733,6 +748,8 @@ public class Preferences extends GPreferences
   @Override
   public void ok_actionPerformed(ActionEvent e)
   {
+    Cache.disableSessionProperties();
+
     if (!validateSettings())
     {
       return;
@@ -746,6 +763,7 @@ public class Preferences extends GPreferences
     /*
      * Save Visual settings
      */
+
     Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
             Boolean.toString(seqLimit.isSelected()));
     Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
@@ -1020,10 +1038,14 @@ public class Preferences extends GPreferences
     } catch (Exception ex)
     {
     }
+
+    Cache.enableSessionProperties();
   }
 
   public void saveProxySettings()
   {
+    Cache.disableSessionProperties();
+
     String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
             : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
                     : Cache.PROXYTYPE_SYSTEM;
@@ -1044,6 +1066,8 @@ public class Preferences extends GPreferences
       wsPrefs.update++;
     }
     previousProxyType = newProxyType;
+
+    Cache.enableSessionProperties();
   }
 
   /**
@@ -1075,6 +1099,8 @@ public class Preferences extends GPreferences
   @Override
   public void startupFileTextfield_mouseClicked()
   {
+    Cache.disableSessionProperties();
+
     // TODO: JAL-3048 not needed for Jalview-JS
     String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
     JalviewFileChooser chooser = JalviewFileChooser
@@ -1096,6 +1122,8 @@ public class Preferences extends GPreferences
       startupFileTextfield
               .setText(chooser.getSelectedFile().getAbsolutePath());
     }
+
+    Cache.enableSessionProperties();
   }
 
   /**
@@ -1405,6 +1433,7 @@ public class Preferences extends GPreferences
      */
     String viewerPath = "";
     List<String> paths = null;
+    Cache.disableSessionProperties();
     try
     {
       ViewerType viewerType = ViewerType.valueOf(selectedItem);
@@ -1430,6 +1459,7 @@ public class Preferences extends GPreferences
     {
       // only valid entries should be in the drop-down
     }
+    Cache.enableSessionProperties();
     structureViewerPath.setText(viewerPath);
 
     paths.add(0, structureViewerPath.getText());
index 011d810..d68d95f 100644 (file)
@@ -231,7 +231,7 @@ public class ProgressBar implements IProgressIndicator
         final JPanel progressPanel = progressBars.get(id);
         if (progressPanel == null)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "call setProgressBar before registering the progress bar's handler.");
           return;
         }
index 705102a..62dce24 100644 (file)
@@ -121,7 +121,7 @@ public class PymolBindingModel extends AAStructureBindingModel
   protected List<String> executeCommand(StructureCommandI command,
           boolean getReply)
   {
-    // System.out.println(command.toString()); // debug
+    // jalview.bin.Console.outPrintln(command.toString()); // debug
     return pymolManager.sendCommand(command, getReply);
   }
 
index 9a44306..ad7684e 100644 (file)
@@ -2,7 +2,7 @@ package jalview.gui;
 
 import java.io.File;
 import java.util.List;
-import java.util.concurrent.Callable;
+import java.util.Locale;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -17,6 +17,7 @@ import javax.swing.JOptionPane;
 import javax.swing.JTextPane;
 
 import com.formdev.flatlaf.extras.FlatDesktop;
+import com.formdev.flatlaf.extras.FlatDesktop.QuitResponse;
 
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.Cache;
@@ -36,6 +37,8 @@ public class QuitHandler
 
   private static boolean interactive = true;
 
+  private static QuitResponse flatlafResponse = null;
+
   public static enum QResponse
   {
     NULL, QUIT, CANCEL_QUIT, FORCE_QUIT
@@ -55,29 +58,17 @@ public class QuitHandler
 
   private static ExecutorService executor = Executors.newFixedThreadPool(3);
 
-  public static QResponse setQuitHandler()
+  public static void setQuitHandler()
   {
     FlatDesktop.setQuitHandler(response -> {
-      Callable<Void> performQuit = () -> {
-        response.performQuit();
-        setResponse(QResponse.QUIT);
-        return null;
-      };
-      Callable<Void> performForceQuit = () -> {
-        response.performQuit();
-        setResponse(QResponse.FORCE_QUIT);
-        return null;
-      };
-      Callable<Void> cancelQuit = () -> {
-        response.cancelQuit();
-        // reset
-        setResponse(QResponse.NULL);
-        return null;
-      };
-      getQuitResponse(true, performQuit, performForceQuit, cancelQuit);
+      flatlafResponse = response;
+      Desktop.instance.desktopQuit();
     });
+  }
 
-    return gotQuitResponse();
+  public static void startForceQuit()
+  {
+    setResponse(QResponse.FORCE_QUIT);
   }
 
   private static QResponse gotQuitResponse = QResponse.NULL;
@@ -85,6 +76,11 @@ public class QuitHandler
   protected static QResponse setResponse(QResponse qresponse)
   {
     gotQuitResponse = qresponse;
+    if ((qresponse == QResponse.CANCEL_QUIT || qresponse == QResponse.NULL)
+            && flatlafResponse != null)
+    {
+      flatlafResponse.cancelQuit();
+    }
     return qresponse;
   }
 
@@ -93,25 +89,22 @@ public class QuitHandler
     return gotQuitResponse;
   }
 
-  public static final Callable<Void> defaultCancelQuit = () -> {
+  public static final Runnable defaultCancelQuit = () -> {
     Console.debug("QuitHandler: (default) Quit action CANCELLED by user");
     // reset
     setResponse(QResponse.CANCEL_QUIT);
-    return null;
   };
 
-  public static final Callable<Void> defaultOkQuit = () -> {
+  public static final Runnable defaultOkQuit = () -> {
     Console.debug("QuitHandler: (default) Quit action CONFIRMED by user");
     setResponse(QResponse.QUIT);
-    return null;
   };
 
-  public static final Callable<Void> defaultForceQuit = () -> {
+  public static final Runnable defaultForceQuit = () -> {
     Console.debug("QuitHandler: (default) Quit action FORCED by user");
     // note that shutdown hook will not be run
     Runtime.getRuntime().halt(0);
     setResponse(QResponse.FORCE_QUIT); // this line never reached!
-    return null;
   };
 
   public static QResponse getQuitResponse(boolean ui)
@@ -120,8 +113,8 @@ public class QuitHandler
             defaultCancelQuit);
   }
 
-  public static QResponse getQuitResponse(boolean ui, Callable<Void> okQuit,
-          Callable<Void> forceQuit, Callable<Void> cancelQuit)
+  public static QResponse getQuitResponse(boolean ui, Runnable okQuit,
+          Runnable forceQuit, Runnable cancelQuit)
   {
     QResponse got = gotQuitResponse();
     if (got != QResponse.NULL && got != QResponse.CANCEL_QUIT)
@@ -186,6 +179,8 @@ public class QuitHandler
       int count = Desktop.instance.structureViewersStillRunningCount();
       if (count > 0)
       {
+        String alwaysCloseExternalViewers = Cache
+                .getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", "ask");
         String prompt = MessageManager
                 .formatMessage(count == 1 ? "label.confirm_quit_viewer"
                         : "label.confirm_quit_viewers");
@@ -196,11 +191,22 @@ public class QuitHandler
         String[] buttonsText = { MessageManager.getString("action.yes"),
             MessageManager.getString("action.no"), cancelQuitText };
 
-        int confirmResponse = JvOptionPane.showOptionDialog(
-                Desktop.instance, prompt, title,
-                JvOptionPane.YES_NO_CANCEL_OPTION,
-                JvOptionPane.WARNING_MESSAGE, null, buttonsText,
-                cancelQuit);
+        int confirmResponse = -1;
+        if (alwaysCloseExternalViewers == null || "ask".equals(
+                alwaysCloseExternalViewers.toLowerCase(Locale.ROOT)))
+        {
+          confirmResponse = JvOptionPane.showOptionDialog(Desktop.instance,
+                  prompt, title, JvOptionPane.YES_NO_CANCEL_OPTION,
+                  JvOptionPane.WARNING_MESSAGE, null, buttonsText,
+                  cancelQuit);
+        }
+        else
+        {
+          confirmResponse = Cache
+                  .getDefault("ALWAYS_CLOSE_EXTERNAL_VIEWERS", false)
+                          ? JvOptionPane.YES_OPTION
+                          : JvOptionPane.NO_OPTION;
+        }
 
         if (confirmResponse == JvOptionPane.CANCEL_OPTION)
         {
@@ -239,7 +245,7 @@ public class QuitHandler
       }
     }
 
-    Callable<Void> next = null;
+    Runnable next = null;
     switch (gotQuitResponse())
     {
     case QUIT:
@@ -280,9 +286,8 @@ public class QuitHandler
     return gotQuitResponse();
   }
 
-  private static QResponse waitQuit(boolean interactive,
-          Callable<Void> okQuit, Callable<Void> forceQuit,
-          Callable<Void> cancelQuit)
+  private static QResponse waitQuit(boolean interactive, Runnable okQuit,
+          Runnable forceQuit, Runnable cancelQuit)
   {
     // check for saves in progress
     if (!BackupFiles.hasSavesInProgress())
index 8d66a44..f487011 100755 (executable)
@@ -184,7 +184,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
 
     validate();
     sliderValueChanged();
-    // System.out.println((System.currentTimeMillis()-start));
+    // jalview.bin.Console.outPrintln((System.currentTimeMillis()-start));
   }
 
   void sliderValueChanged()
index 8ae5408..9b199fd 100644 (file)
@@ -53,7 +53,7 @@ public class RestInputParamEditDialog extends GRestInputParamEditDialog
               .newInstance());
     } catch (Throwable x)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Unexpected exception when instantiating rest input type.");
       x.printStackTrace();
     }
@@ -166,7 +166,7 @@ public class RestInputParamEditDialog extends GRestInputParamEditDialog
           updated = true;
         } catch (InvalidArgumentException ex)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "IMPLEMENTATION ERROR: Invalid argument for type : "
                           + typeList.getSelectedValue() + "\n");
           ex.printStackTrace();
@@ -215,7 +215,7 @@ public class RestInputParamEditDialog extends GRestInputParamEditDialog
         types.add(jtype.getURLtokenPrefix());
       } catch (Throwable x)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Unexpected exception when instantiating rest input type.");
         x.printStackTrace();
       }
index cda76d9..8953626 100644 (file)
@@ -363,7 +363,7 @@ public class RestServiceEditorPane extends GRestServiceEditorPane
                 mtch.group(2) + ":" + mtch.group(3), mtch.group(1),
                 mtch.group(2), mtch.group(3), inputTypes, warnings))
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "IMPLEMENTATION PROBLEM: Cannot parse RestService input parameter string '"
                           + its + "'" + "\n" + warnings);
         }
@@ -389,7 +389,7 @@ public class RestServiceEditorPane extends GRestServiceEditorPane
         } catch (Throwable x)
         {
 
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "IMPLEMENTATION PROBLEM: Cannot parse RestService output parameter string '"
                           + its + "'" + "\n" + warnings);
         }
@@ -399,7 +399,7 @@ public class RestServiceEditorPane extends GRestServiceEditorPane
     }
     else
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "IMPLEMENTATION PROBLEM: Restservice generated from GUI is invalid\n"
                       + warnings);
 
index 930ba79..422601d 100755 (executable)
@@ -269,6 +269,7 @@ public class ScalePanel extends JPanel
     }
     av.setSelectionGroup(sg);
     ap.paintAlignment(false, false);
+    PaintRefresher.Refresh(this,av.getSequenceSetId());
     av.sendSelection();
   }
 
@@ -367,6 +368,7 @@ public class ScalePanel extends JPanel
       stretchingGroup = true;
       cs.stretchGroup(res, sg, min, max);
       ap.paintAlignment(false, false);
+      PaintRefresher.Refresh(ap, av.getSequenceSetId());
     }
   }
 
index d15cdcf..537af58 100755 (executable)
@@ -35,6 +35,7 @@ import java.util.List;
 
 import javax.swing.JPanel;
 
+import jalview.api.SequenceRenderer;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.SearchResultsI;
@@ -107,7 +108,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
   {
     this.av = ap.av;
     fr = new FeatureRenderer(ap);
-    seqRdr = new SequenceRenderer(av);
+    seqRdr = new jalview.gui.SequenceRenderer(av);
     setLayout(new BorderLayout());
     PaintRefresher.Register(this, av.getSequenceSetId());
     setBackground(Color.white);
@@ -343,7 +344,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         }
       }
 
-      // System.err.println(">>> FastPaint to " + transX + " " + transY + " "
+      // jalview.bin.Console.errPrintln(">>> FastPaint to " + transX + " " + transY + " "
       // + horizontal + " " + vertical + " " + startRes + " " + endRes
       // + " " + startSeq + " " + endSeq);
 
@@ -355,14 +356,14 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       /** @j2sNative xxi = this.img */
 
       gg.translate(transX, transY);
-      drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
+      drawPanel(seqRdr, gg, startRes, endRes, startSeq, endSeq, 0);
       gg.translate(-transX, -transY);
       gg.dispose();
 
       // Call repaint on alignment panel so that repaints from other alignment
       // panel components can be aggregated. Otherwise performance of the
       // overview window and others may be adversely affected.
-      // System.out.println("SeqCanvas fastPaint() repaint() request...");
+      // jalview.bin.Console.outPrintln("SeqCanvas fastPaint() repaint() request...");
       av.getAlignPanel().repaint();
     } finally
     {
@@ -455,11 +456,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
       if (av.getWrapAlignment())
       {
-        drawWrappedPanel(gg, getWidth(), getHeight(), ranges.getStartRes());
+        drawWrappedPanel(seqRdr, gg, getWidth(), getHeight(), ranges.getStartRes());
       }
       else
       {
-        drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
+        drawPanel(seqRdr,gg, startRes, endRes, startSeq, endSeq, 0);
       }
 
       drawSelectionGroup(gg, startRes, endRes, startSeq, endSeq);
@@ -491,7 +492,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
   public void drawPanelForPrinting(Graphics g1, int startRes, int endRes,
           int startSeq, int endSeq)
   {
-    drawPanel(g1, startRes, endRes, startSeq, endSeq, 0);
+    SequenceRenderer localSeqR = new jalview.gui.SequenceRenderer(av);
+    drawPanel(localSeqR,g1, startRes, endRes, startSeq, endSeq, 0);
 
     drawSelectionGroup((Graphics2D) g1, startRes, endRes, startSeq, endSeq);
   }
@@ -511,7 +513,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
   public void drawWrappedPanelForPrinting(Graphics g, int canvasWidth,
           int canvasHeight, int startRes)
   {
-    drawWrappedPanel(g, canvasWidth, canvasHeight, startRes);
+    SequenceRenderer localSeqR = new jalview.gui.SequenceRenderer(av);
+    drawWrappedPanel(localSeqR, g, canvasWidth, canvasHeight, startRes);
 
     SequenceGroup group = av.getSelectionGroup();
     if (group != null)
@@ -550,6 +553,20 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     return (canvasWidth - labelWidthEast - labelWidthWest) / charWidth;
   }
 
+  public int getMinimumWrappedCanvasWidth()
+  {
+    int charWidth = av.getCharWidth();
+    FontMetrics fm = getFontMetrics(av.getFont());
+    int labelWidth = 0;
+    if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
+    {
+      labelWidth = getLabelWidth(fm);
+    }
+    labelWidthEast = av.getScaleRightWrapped() ? labelWidth : 0;
+    labelWidthWest = av.getScaleLeftWrapped() ? labelWidth : 0;
+    return labelWidthEast + labelWidthWest + charWidth;
+  }
+
   /**
    * Returns a pixel width sufficient to show the largest sequence coordinate
    * (end position) in the alignment, calculated as the FontMetrics width of
@@ -594,7 +611,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
    * @param startColumn
    *          the first column (0...) of the alignment to draw
    */
-  public void drawWrappedPanel(Graphics g, int canvasWidth,
+  public void drawWrappedPanel(SequenceRenderer seqRdr, Graphics g, int canvasWidth,
           int canvasHeight, final int startColumn)
   {
     int wrappedWidthInResidues = calculateWrappedGeometry(canvasWidth,
@@ -623,7 +640,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     {
       int endColumn = Math.min(maxWidth,
               start + wrappedWidthInResidues - 1);
-      drawWrappedWidth(g, ypos, start, endColumn, canvasHeight);
+      drawWrappedWidth(seqRdr, g, ypos, start, endColumn, canvasHeight);
       ypos += wrappedRepeatHeightPx;
       start += wrappedWidthInResidues;
       currentWidth++;
@@ -716,7 +733,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
    * @param endColumn
    * @param canvasHeight
    */
-  protected void drawWrappedWidth(Graphics g, final int ypos,
+  protected void drawWrappedWidth(SequenceRenderer seqRdr, Graphics g, final int ypos,
           final int startColumn, final int endColumn,
           final int canvasHeight)
   {
@@ -745,7 +762,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     g.fillRect(0, ypos, (endx - startColumn + 1) * charWidth,
             wrappedRepeatHeightPx);
 
-    drawPanel(g, startColumn, endx, 0, av.getAlignment().getHeight() - 1,
+    drawPanel(seqRdr, g, startColumn, endx, 0, av.getAlignment().getHeight() - 1,
             ypos);
 
     int cHeight = av.getAlignment().getHeight() * av.getCharHeight();
@@ -949,6 +966,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
    * are hidden column markers in the visible region, then each sub-region
    * between the markers is drawn separately, followed by the hidden column
    * marker.
+   * @param localSeqR - sequence renderer implementation - when null, uses the one used for rendering interactive GUI
    * 
    * @param g1
    *          the graphics context, positioned at the first residue to be drawn
@@ -963,15 +981,19 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
    * @param yOffset
    *          vertical offset at which to draw (for wrapped alignments)
    */
-  public void drawPanel(Graphics g1, final int startRes, final int endRes,
+  public void drawPanel(SequenceRenderer localSeqR, Graphics g1, final int startRes, final int endRes,
           final int startSeq, final int endSeq, final int yOffset)
   {
     int charHeight = av.getCharHeight();
     int charWidth = av.getCharWidth();
 
+    if (localSeqR==null)
+    {
+      localSeqR = seqRdr;
+    }
     if (!av.hasHiddenColumns())
     {
-      draw(g1, startRes, endRes, startSeq, endSeq, yOffset);
+      draw(localSeqR, g1, startRes, endRes, startSeq, endSeq, yOffset);
     }
     else
     {
@@ -995,7 +1017,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
          */
         g1.translate(screenY * charWidth, 0);
 
-        draw(g1, blockStart, blockEnd, startSeq, endSeq, yOffset);
+        draw(localSeqR, g1, blockStart, blockEnd, startSeq, endSeq, yOffset);
 
         /*
          * draw the downline of the hidden column marker (ScalePanel draws the
@@ -1020,6 +1042,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
   /**
    * Draws a region of the visible alignment
+   * @param seqRdr 
    * 
    * @param g1
    * @param startRes
@@ -1033,7 +1056,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
    * @param yOffset
    *          vertical offset at which to draw (for wrapped alignments)
    */
-  private void draw(Graphics g, int startRes, int endRes, int startSeq,
+  private void draw(SequenceRenderer seqRdr, Graphics g, int startRes, int endRes, int startSeq,
           int endSeq, int offset)
   {
     int charHeight = av.getCharHeight();
@@ -1375,8 +1398,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         }
         else if (inGroup)
         {
-          drawVerticals(g, sx, xwidth, visWidth, oldY, sy);
-          drawHorizontals(g, sx, xwidth, visWidth, top, bottom);
+          drawVerticals(g, sx, xwidth, visWidth, oldY, bottom);
+          drawHorizontals(g, sx, xwidth, visWidth, top, bottom+1);
 
           // reset top and bottom
           top = -1;
@@ -1387,8 +1410,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       if (inGroup)
       {
         sy = verticalOffset + ((i - startSeq) * charHeight);
-        drawVerticals(g, sx, xwidth, visWidth, oldY, sy);
-        drawHorizontals(g, sx, xwidth, visWidth, top, bottom);
+        drawVerticals(g, sx, xwidth, visWidth, oldY, bottom);
+        drawHorizontals(g, sx, xwidth, visWidth, top, bottom+1);
       }
     }
   }
@@ -1653,7 +1676,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
       Graphics gg = img.getGraphics();
       gg.translate(transX, transY);
-      drawPanel(gg, firstCol, lastCol, firstSeq, lastSeq, 0);
+      drawPanel(seqRdr, gg, firstCol, lastCol, firstSeq, lastSeq, 0);
       gg.translate(-transX, -transY);
       gg.dispose();
     }
@@ -1665,7 +1688,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
   public void propertyChange(PropertyChangeEvent evt)
   {
     String eventName = evt.getPropertyName();
-    // System.err.println(">>SeqCanvas propertyChange " + eventName);
+    // jalview.bin.Console.errPrintln(">>SeqCanvas propertyChange " + eventName);
     if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
     {
       fastPaint = true;
@@ -1675,7 +1698,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
     {
       fastPaint = false;
-      // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
+      // jalview.bin.Console.errPrintln("!!!! fastPaint false from MOVE_VIEWPORT");
       repaint();
       return;
     }
@@ -1805,7 +1828,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       if (scrollX < 0)
       {
         int startRes = ranges.getStartRes();
-        drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes,
+        drawWrappedWidth(seqRdr,gg, wrappedSpaceAboveAlignment, startRes,
                 startRes - scrollX - 1, getHeight());
       }
       else
@@ -1879,7 +1902,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
               wrappedRepeatHeightPx);
       gg.translate(-xOffset, 0);
 
-      drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
+      drawWrappedWidth(seqRdr, gg, ypos, startRes, endRes, canvasHeight);
 
     }
 
@@ -1912,7 +1935,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
     if (startRes < ranges.getVisibleAlignmentWidth())
     {
-      drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
+      drawWrappedWidth(seqRdr, gg, ypos, startRes, endRes, canvasHeight);
     }
 
     /*
@@ -2133,7 +2156,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
               {
                 matchFound = true;
                 gg.translate(transX, transY);
-                drawPanel(gg, displayColumn, displayColumn, seqNo, seqNo,
+                drawPanel(seqRdr,gg, displayColumn, displayColumn, seqNo, seqNo,
                         yOffset);
                 gg.translate(-transX, -transY);
               }
index c0a86df..3560efd 100755 (executable)
@@ -377,7 +377,7 @@ public class SeqCanvas extends JComponent
       } catch (OutOfMemoryError er)
       {
         System.gc();
-        System.err.println("SeqCanvas OutOfMemory Redraw Error.\n" + er);
+        jalview.bin.Console.errPrintln("SeqCanvas OutOfMemory Redraw Error.\n" + er);
         new OOMWarning("Creating alignment image for display", er);
 
         return;
index 55f06fc..ce60be6 100644 (file)
@@ -137,7 +137,7 @@ public class SeqPanel extends JPanel
       MousePos o = (MousePos) obj;
       boolean b = (column == o.column && seqIndex == o.seqIndex
               && annotationIndex == o.annotationIndex);
-      // System.out.println(obj + (b ? "= " : "!= ") + this);
+      // jalview.bin.Console.outPrintln(obj + (b ? "= " : "!= ") + this);
       return b;
     }
 
@@ -881,7 +881,7 @@ public class SeqPanel extends JPanel
 
     if (lastMessage == null || !lastMessage.equals(tmp))
     {
-      // System.err.println("mouseOver Sequence: "+tmp);
+      // jalview.bin.Console.errPrintln("mouseOver Sequence: "+tmp);
       ssm.mouseOverSequence(sequence, index, pos, av);
     }
     lastMessage = tmp;
@@ -1006,7 +1006,7 @@ public class SeqPanel extends JPanel
   @Override
   public void updateColours(SequenceI seq, int index)
   {
-    System.out.println("update the seqPanel colours");
+    jalview.bin.Console.outPrintln("update the seqPanel colours");
     // repaint();
   }
 
@@ -2861,7 +2861,7 @@ public class SeqPanel extends JPanel
     if (copycolsel && av.hasHiddenColumns()
             && (av.getAlignment().getHiddenColumns() == null))
     {
-      System.err.println("Bad things");
+      jalview.bin.Console.errPrintln("Bad things");
     }
     if (repaint) // always true!
     {
index 6b4c74a..137655f 100755 (executable)
@@ -599,7 +599,7 @@ public class SequenceFetcher extends JPanel implements Runnable
                 + ((StringPair) database.getSelectedItem()).getDisplay());
         // error
         // +="Couldn't retrieve sequences from "+database.getSelectedItem();
-        System.err.println("Retrieval failed for source ='"
+        jalview.bin.Console.errPrintln("Retrieval failed for source ='"
                 + ((StringPair) database.getSelectedItem()).getDisplay()
                 + "' and query\n'" + textArea.getText() + "'\n");
         e.printStackTrace();
index 43fef15..fedcc37 100755 (executable)
@@ -70,6 +70,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
    * @param b
    *          DOCUMENT ME!
    */
+  @Override
   public void prepare(Graphics g, boolean renderGaps)
   {
     graphics = g;
index 61273c7..ff409e0 100755 (executable)
@@ -113,6 +113,7 @@ public class SplashScreen extends JPanel
    */
   public SplashScreen(boolean isTransient)
   {
+    Desktop.instance.acquireDialogQueue();
     this.transientDialog = isTransient;
 
     if (Platform.isJS()) // BH 2019
@@ -171,7 +172,7 @@ public class SplashScreen extends JPanel
           }
           if (mt.isErrorAny())
           {
-            System.err.println("Error when loading images!");
+            jalview.bin.Console.errPrintln("Error when loading images!");
           }
         } while (!mt.checkAll());
         Desktop.instance.setIconImages(ChannelProperties.getIconList());
@@ -227,7 +228,7 @@ public class SplashScreen extends JPanel
   protected boolean refreshText()
   {
     String newtext = Desktop.instance.getAboutMessage();
-    // System.err.println("Text found: \n"+newtext+"\nEnd of newtext.");
+    // jalview.bin.Console.errPrintln("Text found: \n"+newtext+"\nEnd of newtext.");
     if (oldTextLength != newtext.length())
     {
       iframe.setVisible(false);
@@ -323,7 +324,7 @@ public class SplashScreen extends JPanel
     }
 
     closeSplash();
-    Desktop.instance.startDialogQueue();
+    Desktop.instance.releaseDialogQueue();
   }
 
   /**
index 08d6e03..73744b3 100644 (file)
@@ -900,6 +900,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
       });
       featureSettingsUI = new JInternalFrame(MessageManager.getString(
               "label.sequence_feature_settings_for_CDS_and_Protein"));
+      featureSettingsUI.setFrameIcon(null);
       featureSettingsPanels.setOpaque(true);
 
       JPanel dialog = new JPanel();
index 3fce931..a72e221 100644 (file)
@@ -28,10 +28,11 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
-import java.util.concurrent.Callable;
+import java.util.Map;
 import java.util.concurrent.Executors;
 
 import javax.swing.JCheckBox;
@@ -45,11 +46,16 @@ import javax.swing.table.AbstractTableModel;
 
 import com.stevesoft.pat.Regex;
 
+import jalview.analysis.AlignmentUtils;
+import jalview.api.AlignmentViewPanel;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Console;
 import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
 import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JmolParser;
 import jalview.fts.api.FTSData;
@@ -60,6 +66,7 @@ import jalview.fts.core.FTSRestRequest;
 import jalview.fts.core.FTSRestResponse;
 import jalview.fts.service.pdb.PDBFTSRestClient;
 import jalview.fts.service.threedbeacons.TDB_FTSData;
+import jalview.gui.StructureViewer.ViewerType;
 import jalview.gui.structurechooser.PDBStructureChooserQuerySource;
 import jalview.gui.structurechooser.StructureChooserQuerySource;
 import jalview.gui.structurechooser.ThreeDBStructureChooserQuerySource;
@@ -76,6 +83,7 @@ import jalview.util.Platform;
 import jalview.util.StringUtils;
 import jalview.ws.DBRefFetcher;
 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
+import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 import jalview.ws.seqfetcher.DbSourceProxy;
 import jalview.ws.sifts.SiftsSettings;
 
@@ -131,6 +139,10 @@ public class StructureChooser extends GStructureChooser
   List<SequenceI> seqsWithoutSourceDBRef = null;
 
   private boolean showChooserGUI = true;
+  /**
+   * when true, queries to external services are supressed (no SIFTs, no PDBe, no 3D-Beacons, etc)
+   */
+  private boolean dontQueryServices = false;
 
   private static StructureViewer lastTargetedView = null;
 
@@ -143,6 +155,13 @@ public class StructureChooser extends GStructureChooser
   public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq,
           AlignmentPanel ap, boolean showGUI)
   {
+    this(selectedSeqs, selectedSeq, ap, showGUI, false);
+  }
+  
+  public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq,
+          AlignmentPanel ap, boolean showGUI, boolean dontQueryServices)
+  {
+
     // which FTS engine to use
     data = StructureChooserQuerySource.getQuerySourceFor(selectedSeqs);
     initDialog();
@@ -152,6 +171,7 @@ public class StructureChooser extends GStructureChooser
     this.selectedSequences = selectedSeqs;
     this.progressIndicator = (ap == null) ? null : ap.alignFrame;
     this.showChooserGUI = showGUI;
+    this.dontQueryServices = dontQueryServices;
     init();
 
   }
@@ -223,17 +243,21 @@ public class StructureChooser extends GStructureChooser
       }
     });
 
-    Executors.defaultThreadFactory().newThread(new Runnable()
+    if (!dontQueryServices)
     {
-      @Override
-      public void run()
+      Executors.defaultThreadFactory().newThread(new Runnable()
       {
-        populateSeqsWithoutSourceDBRef();
-        initialStructureDiscovery();
-      }
-
-    }).start();
+        @Override
+        public void run()
+        {
+          populateSeqsWithoutSourceDBRef();
+          initialStructureDiscovery();
+        }
 
+      }).start();
+    } else {
+      Console.debug("Structure chooser not querying services to discover metadata.");
+    }
   }
 
   // called by init
@@ -339,7 +363,7 @@ public class StructureChooser extends GStructureChooser
     };
 
     // fetch db refs if OK pressed
-    final Callable discoverCanonicalDBrefs = () -> {
+    final Runnable discoverCanonicalDBrefs = () -> {
       btn_queryTDB.setEnabled(false);
       populateSeqsWithoutSourceDBRef();
 
@@ -361,14 +385,12 @@ public class StructureChooser extends GStructureChooser
         // call finished action directly
         afterDbRefFetch.finished();
       }
-      return null;
     };
-    final Callable revertview = () -> {
+    final Runnable revertview = () -> {
       if (lastSelected != null)
       {
         cmb_filterOption.setSelectedItem(lastSelected);
       }
-      return null;
     };
     int threshold = Cache.getDefault("UNIPROT_AUTOFETCH_THRESHOLD",
             THRESHOLD_WARN_UNIPROT_FETCH_NEEDED);
@@ -500,7 +522,7 @@ public class StructureChooser extends GStructureChooser
         }
       } catch (Exception e)
       {
-        e.printStackTrace();
+        Console.printStackTrace(e);
         errors.add(e.getMessage());
         continue;
       }
@@ -537,9 +559,18 @@ public class StructureChooser extends GStructureChooser
         {
           errorMsg.append(error).append("\n");
         }
-        JvOptionPane.showMessageDialog(this, errorMsg.toString(),
-                MessageManager.getString("label.pdb_web-service_error"),
-                JvOptionPane.ERROR_MESSAGE);
+        if (!Jalview.isHeadlessMode())
+        {
+          JvOptionPane.showMessageDialog(this, errorMsg.toString(),
+                  MessageManager.getString("label.pdb_web-service_error"),
+                  JvOptionPane.ERROR_MESSAGE);
+        }
+        else
+        {
+          Console.error(
+                  MessageManager.getString("label.pdb_web-service_error"));
+          Console.debug(errorMsg.toString());
+        }
       }
     }
   }
@@ -600,7 +631,7 @@ public class StructureChooser extends GStructureChooser
 
           } catch (Exception e)
           {
-            e.printStackTrace();
+            Console.debugPrintStackTrace(e);
             errors.add(e.getMessage());
             continue;
           }
@@ -699,7 +730,7 @@ public class StructureChooser extends GStructureChooser
   }
 
   /**
-   * Handles action event for btn_pdbFromFile
+   * Handles action event for btn_paeMatrixFile
    */
   @Override
   protected void paeMatrixFile_actionPerformed()
@@ -728,10 +759,26 @@ public class StructureChooser extends GStructureChooser
             "label.load_pae_matrix_file_associate_with_structure",
             pdbFile.getName()));
 
+    // TODO convert to Callable/Promise
     int value = chooser.showOpenDialog(null);
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
-      localPdbPaeMatrixFileName = chooser.getSelectedFile().getPath();
+      String fileName = chooser.getSelectedFile().getPath();
+      try
+      {
+        PAEContactMatrix.validateContactMatrixFile(fileName);
+      } catch (Exception thr)
+      {
+        JvOptionPane.showInternalMessageDialog(this, MessageManager
+                .formatMessage("label.couldnt_load_file", new Object[]
+                { fileName }) + "<br>" + thr.getLocalizedMessage(),
+                MessageManager.getString("label.error_loading_file"),
+                JvOptionPane.WARNING_MESSAGE);
+        Console.error("Couldn't import " + fileName + " as a PAE matrix",
+                thr);
+        return;
+      }
+      localPdbPaeMatrixFileName = fileName;
       Cache.setProperty("LAST_DIRECTORY", localPdbPaeMatrixFileName);
     }
     validateAssociationFromFile();
@@ -1053,11 +1100,13 @@ public class StructureChooser extends GStructureChooser
       {
         pdbFileString = MessageManager.getString("label.none");
         pdbFileTooltip = MessageManager.getString("label.nothing_selected");
+        setPdbOptionsEnabled(false);
       }
     }
     else
     {
       btn_pdbFromFile.setEnabled(false);
+      setPdbOptionsEnabled(false);
       // lbl_fromFileStatus.setIcon(errorImage);
       pdbFileString = MessageManager.getString("label.none");
       pdbFileTooltip = MessageManager.getString("label.nothing_selected");
@@ -1182,7 +1231,14 @@ public class StructureChooser extends GStructureChooser
     final StructureSelectionManager ssm = ap.getStructureSelectionManager();
 
     final int preferredHeight = pnl_filter.getHeight();
+    btn_add.setEnabled(false);
+    btn_newView.setEnabled(false);
+    btn_cancel.setEnabled(false);
+    actionsPanel.setEnabled(false);
 
+    final String progress = MessageManager
+            .getString("label.working_ellipsis");
+    setProgressBar(progress, progress.hashCode());
     Runnable viewStruc = new Runnable()
     {
       @Override
@@ -1273,17 +1329,21 @@ public class StructureChooser extends GStructureChooser
                   .getCmb_assSeq().getSelectedItem();
           SequenceI userSelectedSeq = assSeqOpt.getSequence();
           if (userSelectedSeq != null)
+          {
             selectedSequence = userSelectedSeq;
+          }
           String pdbFilename = selectedPdbFileName;
 
           StructureChooser.openStructureFileForSequence(ssm, sc, ap,
-                  selectedSequence, true, pdbFilename, tft, paeFilename);
+                  selectedSequence, true, pdbFilename, tft, paeFilename,
+                  true);
         }
         SwingUtilities.invokeLater(new Runnable()
         {
           @Override
           public void run()
           {
+            setProgressBar("Complete.", progress.hashCode());
             closeAction(preferredHeight);
             mainFrame.dispose();
           }
@@ -1336,6 +1396,15 @@ public class StructureChooser extends GStructureChooser
           StructureSelectionManager ssm, final PDBEntry[] pdbEntriesToView,
           final AlignmentPanel alignPanel, SequenceI[] sequences)
   {
+    return launchStructureViewer(ssm, pdbEntriesToView, alignPanel,
+            sequences, null);
+  }
+
+  private StructureViewer launchStructureViewer(
+          StructureSelectionManager ssm, final PDBEntry[] pdbEntriesToView,
+          final AlignmentPanel alignPanel, SequenceI[] sequences,
+          ViewerType viewerType)
+  {
     long progressId = sequences.hashCode();
     setProgressBar(MessageManager
             .getString("status.launching_3d_structure_viewer"), progressId);
@@ -1343,6 +1412,12 @@ public class StructureChooser extends GStructureChooser
     boolean superimpose = chk_superpose.isSelected();
     theViewer.setSuperpose(superimpose);
 
+    // if we're running in --headless mode make this viewer synchronous
+    if (Jalview.isHeadlessMode())
+    {
+      theViewer.setAsync(false);
+    }
+
     /*
      * remember user's choice of superimpose or not
      */
@@ -1400,7 +1475,8 @@ public class StructureChooser extends GStructureChooser
               MessageManager.getString(
                       "status.fetching_3d_structures_for_selected_entries"),
               progressId);
-      theViewer.viewStructures(pdbEntriesToView, sequences, alignPanel);
+      theViewer.viewStructures(pdbEntriesToView, sequences, alignPanel,
+              viewerType);
     }
     else
     {
@@ -1408,7 +1484,8 @@ public class StructureChooser extends GStructureChooser
               "status.fetching_3d_structures_for",
               pdbEntriesToView[0].getId()), progressId);
       // Can we pass a pre-computeMappinged pdbFile?
-      theViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
+      theViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel,
+              viewerType);
     }
     setProgressBar(null, progressId);
     // remember the last viewer we used...
@@ -1477,7 +1554,8 @@ public class StructureChooser extends GStructureChooser
             // for moment, it will work fine as is because it is self-contained
             String searchTerm = text.toLowerCase(Locale.ROOT);
             searchTerm = searchTerm.split(":")[0];
-            // System.out.println(">>>>> search term : " + searchTerm);
+            // jalview.bin.Console.outPrintln(">>>>> search term : " +
+            // searchTerm);
             List<FTSDataColumnI> wantedFields = new ArrayList<>();
             FTSRestRequest pdbRequest = new FTSRestRequest();
             pdbRequest.setAllowEmptySeq(false);
@@ -1649,20 +1727,21 @@ public class StructureChooser extends GStructureChooser
   @Override
   public void setProgressBar(String message, long id)
   {
-    if (!Platform.isHeadless())
+    if (!Platform.isHeadless() && progressBar != null)
       progressBar.setProgressBar(message, id);
   }
 
   @Override
   public void registerHandler(long id, IProgressIndicatorHandler handler)
   {
-    progressBar.registerHandler(id, handler);
+    if (progressBar != null)
+      progressBar.registerHandler(id, handler);
   }
 
   @Override
   public boolean operationInProgress()
   {
-    return progressBar.operationInProgress();
+    return progressBar == null ? false : progressBar.operationInProgress();
   }
 
   public JalviewStructureDisplayI getOpenedStructureViewer()
@@ -1709,26 +1788,76 @@ public class StructureChooser extends GStructureChooser
   public static void openStructureFileForSequence(
           StructureSelectionManager ssm, StructureChooser sc,
           AlignmentPanel ap, SequenceI seq, boolean prompt,
-          String sFilename, TFType tft, String paeFilename)
+          String sFilename, TFType tft, String paeFilename,
+          boolean doXferSettings)
+  {
+    openStructureFileForSequence(ssm, sc, ap, seq, prompt, sFilename, tft,
+            paeFilename, false, true, doXferSettings, null);
+  }
+
+  public static StructureViewer openStructureFileForSequence(
+          StructureSelectionManager ssm, StructureChooser sc,
+          AlignmentPanel ap, SequenceI seq, boolean prompt,
+          String sFilename, TFType tft, String paeFilename,
+          boolean forceHeadless, boolean showRefAnnotations,
+          boolean doXferSettings, ViewerType viewerType)
   {
-    boolean headless = false;
+    StructureViewer sv = null;
+    boolean headless = forceHeadless;
     if (sc == null)
     {
-      headless = true;
-      sc = new StructureChooser(new SequenceI[] { seq }, seq, ap, false);
+      // headless = true;
+      prompt = false;
+      // suppress structure viewer's external service queries
+      sc = new StructureChooser(new SequenceI[] { seq }, seq, ap, false,true);
     }
     if (ssm == null)
+    {
       ssm = ap.getStructureSelectionManager();
+    }
 
     PDBEntry fileEntry = new AssociatePdbFileWithSeq().associatePdbWithSeq(
             sFilename, DataSourceType.FILE, seq, prompt, Desktop.instance,
-            tft, paeFilename);
+            tft, paeFilename, doXferSettings);
+
+    // if headless, "false" in the sc constructor above will avoid GUI behaviour
+    // in sc.launchStructureViewer()
+    if (!headless && !(viewerType == null))
+    {
+      sv = sc.launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
+              new SequenceI[]
+              { seq }, viewerType);
+    }
+
+    sc.mainFrame.dispose();
 
-    StructureViewer sViewer = sc.launchStructureViewer(ssm,
-            new PDBEntry[]
-            { fileEntry }, ap, new SequenceI[] { seq });
+    if (showRefAnnotations)
+    {
+      showReferenceAnnotationsForSequence(ap.alignFrame, seq);
+    }
+
+    return sv;
+  }
+
+  public static void showReferenceAnnotationsForSequence(AlignFrame af,
+          SequenceI sequence)
+  {
+    AlignViewport av = af.getCurrentView();
+    AlignmentI al = av.getAlignment();
+
+    List<SequenceI> forSequences = new ArrayList<>();
+    forSequences.add(sequence);
+    final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
+    AlignmentUtils.findAddableReferenceAnnotations(forSequences, null,
+            candidates, al);
+    final SequenceGroup selectionGroup = av.getSelectionGroup();
+    AlignmentUtils.addReferenceAnnotations(candidates, al, selectionGroup);
+    for (AlignmentViewPanel ap : af.getAlignPanels())
+    {
+      // required to readjust the height and position of the PAE
+      // annotation
+      ap.adjustAnnotationHeight();
+    }
 
-    if (headless)
-      sc.mainFrame.dispose();
   }
 }
index 5effa1a..ad3fc6a 100644 (file)
 package jalview.gui;
 
 import java.util.ArrayList;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -54,9 +56,39 @@ public class StructureViewer
    */
   private boolean superposeAdded = true;
 
+  /**
+   * whether to open structures in their own thread or not
+   */
+  private boolean async = true;
+
+  public void setAsync(boolean b)
+  {
+    async = b;
+  }
+
   public enum ViewerType
   {
-    JMOL, CHIMERA, CHIMERAX, PYMOL
+    JMOL, CHIMERA, CHIMERAX, PYMOL;
+
+    public static ViewerType getFromString(String viewerString)
+    {
+      ViewerType viewerType = null;
+      if (!"none".equals(viewerString))
+      {
+        for (ViewerType v : EnumSet.allOf(ViewerType.class))
+        {
+          String name = v.name().toLowerCase(Locale.ROOT).replaceAll(" ",
+                  "");
+          if (viewerString.equals(name))
+          {
+            viewerType = v;
+            break;
+          }
+        }
+      }
+      return viewerType;
+    }
+
   };
 
   /**
@@ -119,6 +151,12 @@ public class StructureViewer
   public JalviewStructureDisplayI viewStructures(PDBEntry[] pdbs,
           SequenceI[] seqs, AlignmentPanel ap)
   {
+    return viewStructures(pdbs, seqs, ap, null);
+  }
+
+  public JalviewStructureDisplayI viewStructures(PDBEntry[] pdbs,
+          SequenceI[] seqs, AlignmentPanel ap, ViewerType viewerType)
+  {
     JalviewStructureDisplayI viewer = onlyOnePdb(pdbs, seqs, ap);
     if (viewer != null)
     {
@@ -128,7 +166,8 @@ public class StructureViewer
       return viewer;
     }
 
-    ViewerType viewerType = getViewerType();
+    if (viewerType == null)
+      viewerType = getViewerType();
 
     Map<PDBEntry, SequenceI[]> seqsForPdbs = getSequencesForPdbs(pdbs,
             seqs);
@@ -139,7 +178,8 @@ public class StructureViewer
     if (sview != null)
     {
       sview.setAlignAddedStructures(superposeAdded);
-      new Thread(new Runnable()
+
+      Runnable viewRunnable = new Runnable()
       {
         @Override
         public void run()
@@ -158,7 +198,15 @@ public class StructureViewer
 
           sview.updateTitleAndMenus();
         }
-      }).start();
+      };
+      if (async)
+      {
+        new Thread(viewRunnable).start();
+      }
+      else
+      {
+        viewRunnable.run();
+      }
       return sview;
     }
 
@@ -296,9 +344,20 @@ public class StructureViewer
 
   JalviewStructureDisplayI sview = null;
 
+  public JalviewStructureDisplayI getJalviewStructureDisplay()
+  {
+    return sview;
+  }
+
   public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
           SequenceI[] seqsForPdb, AlignmentPanel ap)
   {
+    return viewStructures(pdb, seqsForPdb, ap, null);
+  }
+
+  public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
+          SequenceI[] seqsForPdb, AlignmentPanel ap, ViewerType viewerType)
+  {
     if (sview != null)
     {
       sview.setAlignAddedStructures(superposeAdded);
@@ -311,7 +370,8 @@ public class StructureViewer
       sview.raiseViewer();
       return sview;
     }
-    ViewerType viewerType = getViewerType();
+    if (viewerType == null)
+      viewerType = getViewerType();
     if (viewerType.equals(ViewerType.JMOL))
     {
       sview = new AppJmol(pdb, seqsForPdb, null, ap);
index 01a3c2d..ed42ffa 100644 (file)
@@ -47,6 +47,7 @@ import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
 
 import jalview.api.AlignmentViewPanel;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Console;
 import jalview.datamodel.AlignmentI;
@@ -88,6 +89,29 @@ public abstract class StructureViewerBase extends GStructureViewer
   }
 
   /**
+   * Singleton list of all (open) instances of structureViewerBase
+   * TODO: JAL-3362 - review and adopt the swingJS-safe singleton pattern so each structure viewer base instance is kept to its own JalviewJS parent
+   */
+  private static List<JalviewStructureDisplayI> svbs = new ArrayList<>();
+
+  /**
+   * 
+   * @return list with all existing StructureViewers instance
+   */
+  public static List<JalviewStructureDisplayI> getAllStructureViewerBases()
+  {
+    List<JalviewStructureDisplayI> goodSvbs = new ArrayList<>();
+    for (JalviewStructureDisplayI s : svbs)
+    {
+      if (s != null && !goodSvbs.contains(s))
+      {
+        goodSvbs.add(s);
+      }
+    }
+    return goodSvbs;
+  }
+
+  /**
    * list of sequenceSet ids associated with the view
    */
   protected List<String> _aps = new ArrayList<>();
@@ -137,6 +161,7 @@ public abstract class StructureViewerBase extends GStructureViewer
   {
     super();
     setFrameIcon(null);
+    svbs.add(this);
   }
 
   /**
@@ -180,6 +205,7 @@ public abstract class StructureViewerBase extends GStructureViewer
     return _aps.contains(ap2.av.getSequenceSetId());
   }
 
+  @Override
   public boolean isUsedforaligment(AlignmentViewPanel ap2)
   {
 
@@ -1197,7 +1223,7 @@ public abstract class StructureViewerBase extends GStructureViewer
       }
     } catch (Exception e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error retrieving PDB id " + pdbid + ": " + e.getMessage());
     } finally
     {
@@ -1336,6 +1362,13 @@ public abstract class StructureViewerBase extends GStructureViewer
     // TODO: check for memory leaks where instance isn't finalised because jmb
     // holds a reference to the window
     // jmb = null;
+    
+    try {
+      svbs.remove(this);
+    } catch (Throwable t)
+    {
+      Console.info("Unexpected exception when deregistering structure viewer",t);
+    }
     dispose();
   }
 
index e72a084..5bc6563 100644 (file)
@@ -27,7 +27,6 @@ import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.Callable;
 
 import javax.swing.BorderFactory;
 import javax.swing.JLabel;
@@ -152,10 +151,9 @@ public class TextColourChooser
         MessageManager.getString("action.cancel") };
     String title = MessageManager
             .getString("label.adjust_foreground_text_colour_threshold");
-    Callable<Void> action = () -> // response for 1 = Cancel
+    Runnable action = () -> // response for 1 = Cancel
     {
       restoreInitialSettings();
-      return null;
     };
     JvOptionPane.newOptionDialog(alignPanel.alignFrame)
             .setResponseHandler(1, action).showInternalDialog(bigpanel,
index 29826f0..6fbd422 100755 (executable)
@@ -53,7 +53,9 @@ import javax.swing.ToolTipManager;
 import jalview.analysis.Conservation;
 import jalview.analysis.TreeModel;
 import jalview.api.AlignViewportI;
+import jalview.bin.Console;
 import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
 import jalview.datamodel.BinaryNode;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.ContactMatrixI;
@@ -65,8 +67,10 @@ import jalview.datamodel.SequenceNode;
 import jalview.gui.JalviewColourChooser.ColourChooserListener;
 import jalview.schemes.ColourSchemeI;
 import jalview.structure.SelectionSource;
+import jalview.util.ColorUtils;
 import jalview.util.Format;
 import jalview.util.MessageManager;
+import jalview.ws.datamodel.MappableContactMatrixI;
 
 /**
  * DOCUMENT ME!
@@ -141,9 +145,43 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     scrollPane = scroller;
     addMouseListener(this);
     addMouseMotionListener(this);
+    
     ToolTipManager.sharedInstance().registerComponent(this);
   }
 
+  public void clearSelectedLeaves()
+  {
+    Vector<BinaryNode> leaves = tp.getTree()
+            .findLeaves(tp.getTree().getTopNode());
+    if (tp.isColumnWise())
+    {
+      markColumnsFor(getAssociatedPanels(), leaves, Color.white, true);
+    }
+    else
+    {
+      for (AlignmentPanel ap : getAssociatedPanels())
+      {
+        SequenceGroup selected = ap.av.getSelectionGroup();
+        if (selected != null)
+        {
+          {
+            for (int i = 0; i < leaves.size(); i++)
+            {
+              SequenceI seq = (SequenceI) leaves.elementAt(i).element();
+              if (selected.contains(seq))
+              {
+                selected.addOrRemove(seq, false);
+              }
+            }
+            selected.recalcConservation();
+          }
+        }
+        ap.av.sendSelection();
+      }
+    }
+    PaintRefresher.Refresh(tp, av.getSequenceSetId());
+    repaint();
+  }
   /**
    * DOCUMENT ME!
    * 
@@ -185,11 +223,18 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     boolean has_placeholders = false;
     longestName = "";
 
+    AlignmentAnnotation aa = tp.getAssocAnnotation();
+    ContactMatrixI cm = (aa!=null) ? av.getContactMatrix(aa) : null;
+    if (cm!=null && cm.hasCutHeight())
+    {
+      threshold=(float) cm.getCutHeight();
+    }
+    
     for (int i = 0; i < leaves.size(); i++)
     {
       BinaryNode lf = leaves.elementAt(i);
 
-      if (lf instanceof SequenceNode && ((SequenceNode)lf).isPlaceholder())
+      if (lf instanceof SequenceNode && ((SequenceNode) lf).isPlaceholder())
       {
         has_placeholders = true;
       }
@@ -200,6 +245,14 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
         longestName = TreeCanvas.PLACEHOLDER
                 + ((Sequence) lf.element()).getName();
       }
+      if (tp.isColumnWise() && cm!=null)
+      {
+        // get color from group colours, if they are set for the matrix
+        try {
+          Color col = cm.getGroupColorForPosition(parseColumnNode(lf));
+          setColor(lf,col.brighter());
+        } catch (NumberFormatException ex) {};
+      }
     }
 
     setMarkPlaceholders(has_placeholders);
@@ -223,7 +276,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
    * @param offy
    *          DOCUMENT ME!
    */
-  public void drawNode(Graphics g, BinaryNode node, float chunk,
+  public void drawNode(Graphics g, BinaryNode node, double chunk,
           double wscale, int width, int offx, int offy)
   {
     if (node == null)
@@ -285,9 +338,10 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
         g.drawString(nodeLabel, xstart + 2, ypos - 2);
       }
 
-      String name = (markPlaceholders && ((node instanceof SequenceNode && ((SequenceNode)node).isPlaceholder())))
-              ? (PLACEHOLDER + node.getName())
-              : node.getName();
+      String name = (markPlaceholders && ((node instanceof SequenceNode
+              && ((SequenceNode) node).isPlaceholder())))
+                      ? (PLACEHOLDER + node.getName())
+                      : node.getName();
 
       int charWidth = fm.stringWidth(name) + 3;
       int charHeight = font.getSize();
@@ -354,8 +408,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       int ystart = (node.left() == null ? 0
               : (int) (((BinaryNode) node.left()).ycount * chunk)) + offy;
       int yend = (node.right() == null ? 0
-              : (int) (((BinaryNode) node.right()).ycount * chunk))
-              + offy;
+              : (int) (((BinaryNode) node.right()).ycount * chunk)) + offy;
 
       Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);
       nodeHash.put(node, pos);
@@ -742,7 +795,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
               + ((BinaryNode) top.right()).count;
     }
 
-    float chunk = (float) (height - (offy)) / top.count;
+    double chunk = (double) (height - (offy)) / (double)top.count;
 
     drawNode(g2, tree.getTopNode(), chunk, wscale, width, offx, offy);
 
@@ -826,14 +879,17 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     else
     {
       Vector<BinaryNode> leaves = tree.findLeaves(highlightNode);
-      if (tp.isColumnWise()) {
-        markColumnsFor(getAssociatedPanels(), leaves, Color.red);
-      } else {
-      for (int i = 0; i < leaves.size(); i++)
+      if (tp.isColumnWise())
       {
-        SequenceI seq = (SequenceI) leaves.elementAt(i).element();
-        treeSelectionChanged(seq);
+        markColumnsFor(getAssociatedPanels(), leaves, Color.red,false);
       }
+      else
+      {
+        for (int i = 0; i < leaves.size(); i++)
+        {
+          SequenceI seq = (SequenceI) leaves.elementAt(i).element();
+          treeSelectionChanged(seq);
+        }
       }
       av.sendSelection();
     }
@@ -986,7 +1042,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
           threshold = 0f;
         }
       }
-
+      Console.log.debug("Tree cut threshold set at:" + threshold);
       PaintRefresher.Refresh(tp,
               getAssociatedPanel().av.getSequenceSetId());
       repaint();
@@ -998,18 +1054,21 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
   {
     AlignmentPanel[] aps = getAssociatedPanels();
     List<BitSet> colGroups = new ArrayList<>();
-    Map<BitSet,Color> colors=new HashMap();
+    Map<BitSet, Color> colors = new HashMap();
     for (int i = 0; i < groups.size(); i++)
     {
-      Color col = new Color((int) (Math.random() * 255),
-              (int) (Math.random() * 255), (int) (Math.random() * 255));
+      Color col = ColorUtils.getARandomColor();
+      
       setColor(groups.get(i), col.brighter());
 
       Vector<BinaryNode> l = tree.findLeaves(groups.get(i));
-      if (!tp.isColumnWise()) {
+      if (!tp.isColumnWise())
+      {
         createSeqGroupFor(aps, l, col);
-      } else {
-        BitSet gp=createColumnGroupFor(l,col);
+      }
+      else
+      {
+        BitSet gp = createColumnGroupFor(l, col);
 
         colGroups.add(gp);
         colors.put(gp, col);
@@ -1018,16 +1077,18 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     if (tp.isColumnWise())
     {
       AlignmentAnnotation aa = tp.getAssocAnnotation();
-      if (aa!=null) {
+      if (aa != null)
+      {
         ContactMatrixI cm = av.getContactMatrix(aa);
-        if (cm!=null)
+        if (cm != null)
         {
           cm.updateGroups(colGroups);
-          for (BitSet gp:colors.keySet())
+          for (BitSet gp : colors.keySet())
           {
             cm.setColorForGroup(gp, colors.get(gp));
           }
         }
+        cm.transferGroupColorsTo(aa);
       }
     }
 
@@ -1045,59 +1106,89 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       }
     }
   }
-
+  private int parseColumnNode(BinaryNode bn) throws NumberFormatException
+  {
+    return Integer.parseInt(
+            bn.getName().substring(bn.getName().indexOf("c") + 1));
+  }
   private boolean isColumnForNodeSelected(BinaryNode bn)
   {
     SequenceI rseq = tp.assocAnnotation.sequenceRef;
     int colm = -1;
     try
     {
-      colm = Integer.parseInt(
-              bn.getName().substring(bn.getName().indexOf("c") + 1));
+      colm = parseColumnNode(bn);
     } catch (Exception e)
     {
       return false;
     }
-    if (av==null||av.getAlignment()==null)
+    if (av == null || av.getAlignment() == null)
     {
       // alignment is closed
       return false;
     }
     ColumnSelection cs = av.getColumnSelection();
-    
     HiddenColumns hc = av.getAlignment().getHiddenColumns();
-    int offp = (rseq != null) ? rseq.findIndex(rseq.getStart() + colm)
-            : colm;
+    AlignmentAnnotation aa = tp.getAssocAnnotation();
+    int offp=-1;
+    if (aa != null)
+    {
+      ContactMatrixI cm = av.getContactMatrix(aa);
+      // generally, we assume cm has 1:1 mapping to annotation row - probably wrong
+      // but.. if
+      if (cm instanceof MappableContactMatrixI)
+      {
+        int[] pos;
+          // use the mappable's mapping - always the case for PAE Matrices so good
+        // for 2.11.3
+        MappableContactMatrixI mcm = (MappableContactMatrixI) cm;
+        pos = mcm.getMappedPositionsFor(rseq, colm + 1);
+        // finally, look up the position of the column
+        if (pos != null)
+        {
+          offp = rseq.findIndex(pos[0]);
+        }
+      } else {
+        offp = colm;
+      }
+    }
+    if (offp<=0)
+    {
+      return false;
+    }
 
+    offp-=2;
     if (!av.hasHiddenColumns())
     {
-      return cs.contains(offp-1);
+      return cs.contains(offp);
     }
-    if (hc.isVisible(offp-1))
+    if (hc.isVisible(offp))
     {
-      return cs.contains(offp-1);
-//      return cs.contains(hc.absoluteToVisibleColumn(offp));
+      return cs.contains(offp);
+      // return cs.contains(hc.absoluteToVisibleColumn(offp));
     }
     return false;
   }
-  
-  private BitSet createColumnGroupFor(Vector<BinaryNode> l,
-          Color col)
+  private BitSet createColumnGroupFor(Vector<BinaryNode> l, Color col)
   {
-    BitSet gp=new BitSet();
-    for (BinaryNode bn:l)
+    BitSet gp = new BitSet();
+    for (BinaryNode bn : l)
     {
-      int colm=-1;
-      if (bn.element()!=null && bn.element()instanceof Integer)
-      { colm = (Integer)bn.element();
-      } else {
-        // parse out from nodename
-      try {
-        colm = Integer.parseInt(bn.getName().substring(bn.getName().indexOf("c")+1));
-      } catch (Exception e)
+      int colm = -1;
+      if (bn.element() != null && bn.element() instanceof Integer)
       {
-        continue;
+        colm = (Integer) bn.element();
       }
+      else
+      {
+        // parse out from nodename
+        try
+        {
+          colm = parseColumnNode(bn);
+        } catch (Exception e)
+        {
+          continue;
+        }
       }
       gp.set(colm);
     }
@@ -1105,40 +1196,66 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
   }
 
   private void markColumnsFor(AlignmentPanel[] aps, Vector<BinaryNode> l,
-          Color col)
+          Color col, boolean clearSelected)
   {
     SequenceI rseq = tp.assocAnnotation.sequenceRef;
-    if (av==null||av.getAlignment()==null)
+    if (av == null || av.getAlignment() == null)
     {
       // alignment is closed
       return;
     }
 
-    for (BinaryNode bn:l)
+    // TODO - sort indices for faster lookup
+    ColumnSelection cs = av.getColumnSelection();
+    HiddenColumns hc = av.getAlignment().getHiddenColumns();
+    ContactMatrixI cm = av.getContactMatrix(tp.assocAnnotation);
+    MappableContactMatrixI mcm = null;
+    int offp;
+    if (cm instanceof MappableContactMatrixI)
+    {
+      mcm = (MappableContactMatrixI) cm;
+    }
+    for (BinaryNode bn : l)
     {
-      int colm=-1;
-      try {
-        colm = Integer.parseInt(bn.getName().substring(bn.getName().indexOf("c")+1));
+      int colm = -1;
+      try
+      {
+        colm = Integer.parseInt(
+                bn.getName().substring(bn.getName().indexOf("c") + 1));
       } catch (Exception e)
       {
         continue;
       }
-      ColumnSelection cs = av.getColumnSelection();
-      HiddenColumns hc = av.getAlignment().getHiddenColumns();
+      if (mcm!=null)
       {
-        int offp = (rseq!=null) ? rseq.findIndex(rseq.getStart()+colm) : colm;
-        
-        if (!av.hasHiddenColumns() || hc.isVisible(offp-1))
-        { 
-          if (cs.contains(offp-1))
-          {
-            cs.removeElement(offp-1);
-          } else {
-            cs.addElement(offp-1);
-          }
+        int[] seqpos = mcm.getMappedPositionsFor(
+                rseq, colm);
+        if (seqpos == null)
+        {
+          // no mapping for this column.
+          continue;
+        }
+        // TODO: handle ranges...
+        offp = rseq.findIndex(seqpos[0])-1;
+      }
+      else
+      {
+        offp = (rseq != null) ? rseq.findIndex(rseq.getStart() + colm)
+                : colm;
+      }
+      if (!av.hasHiddenColumns() || hc.isVisible(offp))
+      {
+        if (clearSelected || cs.contains(offp))
+        {
+          cs.removeElement(offp);
+        }
+        else
+        {
+          cs.addElement(offp);
         }
       }
-    } 
+    }
+    PaintRefresher.Refresh(tp, av.getSequenceSetId());
   }
 
   public void createSeqGroupFor(AlignmentPanel[] aps, Vector<BinaryNode> l,
index 30e4305..0a0c1b8 100755 (executable)
@@ -24,6 +24,8 @@ import java.awt.Font;
 import java.awt.Graphics;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
@@ -67,6 +69,7 @@ import jalview.gui.ImageExporter.ImageWriterI;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
 import jalview.io.NewickFile;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.jbgui.GTreePanel;
 import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
@@ -136,20 +139,24 @@ public class TreePanel extends GTreePanel
           AlignmentAnnotation aa, String title)
   {
     super();
-    columnWise=true;
+    columnWise = true;
     assocAnnotation = aa;
     this.setFrameIcon(null);
     this.treeTitle = title;
     initTreePanel(alignPanel, null, null, fin, null);
   }
-  
-  boolean columnWise=false;
-  AlignmentAnnotation assocAnnotation=null;
+
+  boolean columnWise = false;
+
+  AlignmentAnnotation assocAnnotation = null;
+
   public boolean isColumnWise()
   {
     return columnWise;
   }
-  public AlignmentAnnotation getAssocAnnotation() {
+
+  public AlignmentAnnotation getAssocAnnotation()
+  {
     return assocAnnotation;
   }
 
@@ -172,18 +179,35 @@ public class TreePanel extends GTreePanel
     this.treeType = type;
     this.scoreModelName = modelName;
 
+    treeCanvas = new TreeCanvas(this, ap, scrollPane);
+    scrollPane.setViewportView(treeCanvas);
+    
     if (columnWise)
     {
       bootstrapMenu.setVisible(false);
-      placeholdersMenu.setSelected(false);
+      placeholdersMenu.setState(false);
       placeholdersMenu.setVisible(false);
-      fitToWindow.setSelected(false);
+      fitToWindow.setState(false);
       sortAssocViews.setVisible(false);
     }
 
-    treeCanvas = new TreeCanvas(this, ap, scrollPane);
-    scrollPane.setViewportView(treeCanvas);
 
+    addKeyListener(new KeyAdapter()
+    {
+      @Override
+      public void keyPressed(KeyEvent e)
+      {
+        switch (e.getKeyCode())
+        { 
+        case 27: // escape
+          treeCanvas.clearSelectedLeaves();
+          e.consume();
+          break;
+          
+        }
+        
+      }
+    });
     PaintRefresher.Register(this, ap.av.getSequenceSetId());
 
     buildAssociatedViewMenu();
@@ -237,7 +261,7 @@ public class TreePanel extends GTreePanel
         {
           if (tree == null)
           {
-            System.out.println("tree is null");
+            jalview.bin.Console.outPrintln("tree is null");
             // TODO: deal with case when a change event is received whilst a
             // tree is still being calculated - should save reference for
             // processing message later.
@@ -245,7 +269,7 @@ public class TreePanel extends GTreePanel
           }
           if (evt.getNewValue() == null)
           {
-            System.out.println(
+            jalview.bin.Console.outPrintln(
                     "new alignment sequences vector value is null");
           }
 
@@ -368,9 +392,9 @@ public class TreePanel extends GTreePanel
                 ? new NJTree(av, sm, similarityParams)
                 : new AverageDistanceTree(av, sm, similarityParams);
         tree = new TreeModel(njtree);
-        showDistances(true);
+        // don't display distances for columnwise trees        
       }
-
+      showDistances(!columnWise);
       tree.reCount(tree.getTopNode());
       tree.findHeight(tree.getTopNode());
       treeCanvas.setTree(tree);
@@ -735,8 +759,12 @@ public class TreePanel extends GTreePanel
     String tree = MessageManager.getString("label.tree");
     ImageExporter exporter = new ImageExporter(writer, null, imageFormat,
             tree);
+    try {
     exporter.doExport(null, this, width, height,
             tree.toLowerCase(Locale.ROOT));
+    } catch (ImageOutputException ioex) {
+      Console.error("Unexpected error whilst writing "+imageFormat.toString(),ioex);
+    }
   }
 
   /**
@@ -868,7 +896,7 @@ public class TreePanel extends GTreePanel
       pg.close();
     } catch (Exception ex)
     {
-      System.err.println("Error writing tree as EPS");
+      jalview.bin.Console.errPrintln("Error writing tree as EPS");
       ex.printStackTrace();
     }
   }
index 298b8b4..14f9adf 100755 (executable)
@@ -686,7 +686,6 @@ public class UserDefinedColours extends GUserDefinedColours
       }
 
       addNewColourScheme(choice.getPath());
-      return null;
     });
 
     chooser.showOpenDialog(this);
index 8a8ba8d..28f6c59 100644 (file)
@@ -614,7 +614,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
       cdoc = null;
     } catch (Exception ee)
     {
-      System.err.println("Exception whilst updating :");
+      jalview.bin.Console.errPrintln("Exception whilst updating :");
       ee.printStackTrace(System.err);
       // recover object map backup, since its probably corrupted with references
       // to Vobjects that don't exist anymore.
@@ -803,7 +803,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
               // we only care about AlignmentSequence selections
               SelectionMessage sm = (SelectionMessage) message;
               sm.validate();
-              System.err.println("Received\n" + sm.getRawMessage());
+              jalview.bin.Console.errPrintln("Received\n" + sm.getRawMessage());
               Object[] jvobjs = sm.getVorbaIDs() == null ? null
                       : new Object[sm.getVorbaIDs().length];
               if (jvobjs == null)
index 4aac062..961caa7 100644 (file)
@@ -359,7 +359,7 @@ public class WebserviceInfo extends GWebserviceInfo
       @Override
       public void internalFrameClosed(InternalFrameEvent evt)
       {
-        // System.out.println("Shutting down webservice client");
+        // jalview.bin.Console.outPrintln("Shutting down webservice client");
         WSClientI service = thisinfo.getthisService();
         if (service != null && service.isCancellable())
         {
@@ -626,8 +626,8 @@ public class WebserviceInfo extends GWebserviceInfo
               true, false);
       ((JEditorPane) ((JScrollPane) jobPanes.get(which)).getViewport()
               .getComponent(0))
-              .setText(ensureHtmlTagged(
-                      txt + getHtmlFragment(text, false, true)));
+                      .setText(ensureHtmlTagged(
+                              txt + getHtmlFragment(text, false, true)));
     }
     else
     {
index e1613da..196eb32 100644 (file)
@@ -493,7 +493,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
     else
     {
       // TODO: show warning
-      System.err.println("Invalid name. Not saved.");
+      jalview.bin.Console.errPrintln("Invalid name. Not saved.");
     }
   }
 
@@ -642,7 +642,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
           }
           else
           {
-            System.err.println("Ignoring unknown service argument type "
+            jalview.bin.Console.errPrintln("Ignoring unknown service argument type "
                     + myarg.getClass().getName());
           }
         }
@@ -685,7 +685,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
         {
           if (arg instanceof OptionI)
           {
-            // System.out.println("Setting option "
+            // jalview.bin.Console.outPrintln("Setting option "
             // + System.identityHashCode(arg) + ":" + arg.getName()
             // + " with " + arg.getDefaultValue());
             opanp.selectOption((OptionI) arg, arg.getValue());
@@ -874,7 +874,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
         if (cw + 120 > panewidth)
         {
           jobOptions.add(pbox, "wrap");
-          // System.out.println("Wrap on "+pbox.option.getName());
+          // jalview.bin.Console.outPrintln("Wrap on "+pbox.option.getName());
           cw = hgap + pbox.getSize().width;
           fh = true;
         }
@@ -946,7 +946,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
     }
     // TODO: waste some time trying to eliminate any unnecessary .validate calls
     // here
-    // System.out.println("Size will be : "+w+","+os);
+    // jalview.bin.Console.outPrintln("Size will be : "+w+","+os);
     // optsAndparams.setPreferredSize(null);
     // paramPane.getViewport().setView(optsAndparams);
     paramPane.getViewport().setAutoscrolls(true);
@@ -976,7 +976,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
       disc.run();
     } catch (Exception e)
     {
-      System.err.println("Aborting. Problem discovering services.");
+      jalview.bin.Console.errPrintln("Aborting. Problem discovering services.");
       e.printStackTrace();
       return;
     }
@@ -1023,7 +1023,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
               pr = en.next();
             }
             {
-              System.out.println("Testing opts dupes for "
+              jalview.bin.Console.outPrintln("Testing opts dupes for "
                       + lastserv.getUri() + " : " + lastserv.getActionText()
                       + ":" + pr.getName());
               List<Option> rg = lastserv.getRunnerConfig().getOptions();
@@ -1034,17 +1034,17 @@ public class WsJobParameters extends JPanel implements ItemListener,
                   Option cpy = jalview.ws.jws2.ParameterUtils.copyOption(o);
                 } catch (Exception e)
                 {
-                  System.err.println("Failed to copy " + o.getName());
+                  jalview.bin.Console.errPrintln("Failed to copy " + o.getName());
                   e.printStackTrace();
                 } catch (Error e)
                 {
-                  System.err.println("Failed to copy " + o.getName());
+                  jalview.bin.Console.errPrintln("Failed to copy " + o.getName());
                   e.printStackTrace();
                 }
               }
             }
             {
-              System.out.println("Testing param dupes:");
+              jalview.bin.Console.outPrintln("Testing param dupes:");
               List<Parameter> rg = lastserv.getRunnerConfig()
                       .getParameters();
               for (Parameter o : rg)
@@ -1055,17 +1055,17 @@ public class WsJobParameters extends JPanel implements ItemListener,
                           .copyParameter(o);
                 } catch (Exception e)
                 {
-                  System.err.println("Failed to copy " + o.getName());
+                  jalview.bin.Console.errPrintln("Failed to copy " + o.getName());
                   e.printStackTrace();
                 } catch (Error e)
                 {
-                  System.err.println("Failed to copy " + o.getName());
+                  jalview.bin.Console.errPrintln("Failed to copy " + o.getName());
                   e.printStackTrace();
                 }
               }
             }
             {
-              System.out.println("Testing param write:");
+              jalview.bin.Console.outPrintln("Testing param write:");
               List<String> writeparam = null, readparam = null;
               try
               {
@@ -1073,7 +1073,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
                         .writeParameterSet(
                                 pr.getArguments(lastserv.getRunnerConfig()),
                                 " ");
-                System.out.println("Testing param read :");
+                jalview.bin.Console.outPrintln("Testing param read :");
                 List<Option> pset = jalview.ws.jws2.ParameterUtils
                         .processParameters(writeparam,
                                 lastserv.getRunnerConfig(), " ");
@@ -1087,7 +1087,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
                   String on = o.next(), sn = s.next(), st = t.next();
                   if (!sn.equals(st))
                   {
-                    System.out.println(
+                    jalview.bin.Console.outPrintln(
                             "Original was " + on + " Phase 1 wrote " + sn
                                     + "\tPhase 2 wrote " + st);
                     failed = true;
@@ -1095,11 +1095,11 @@ public class WsJobParameters extends JPanel implements ItemListener,
                 }
                 if (failed)
                 {
-                  System.out.println(
+                  jalview.bin.Console.outPrintln(
                           "Original parameters:\n" + pr.getOptions());
-                  System.out.println(
+                  jalview.bin.Console.outPrintln(
                           "Wrote parameters in first set:\n" + writeparam);
-                  System.out.println(
+                  jalview.bin.Console.outPrintln(
                           "Wrote parameters in second set:\n" + readparam);
 
                 }
@@ -1223,7 +1223,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
    * + storeSetName + ": ", jobParams); }
    * 
    * private void writeParam(String nm, List<ArgumentI> params) { for (ArgumentI
-   * p : params) { System.out.println(nm + ":" + System.identityHashCode(p) +
+   * p : params) { jalview.bin.Console.outPrintln(nm + ":" + System.identityHashCode(p) +
    * " Name: " + p.getName() + " Value: " + p.getDefaultValue()); } }
    * 
    * private Object[] _getUserPreset(String setName) { Object[] pset =
@@ -1376,7 +1376,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
         return;
       }
       settingDialog = true;
-      System.out.println("Prompting to save " + lsetname);
+      jalview.bin.Console.outPrintln("Prompting to save " + lsetname);
       if (JvOptionPane.showConfirmDialog(this, "Parameter set '" + lsetname
               + "' is modifed, and your changes will be lost.\nReally change preset ?",
               "Warning: Unsaved Changes",
@@ -1388,7 +1388,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
         settingDialog = false;
         // and leave.
         return;
-        // System.out.println("Saving for " + lsetname);
+        // jalview.bin.Console.outPrintln("Saving for " + lsetname);
         // _storeCurrentPreset(lsetname);
 
       }
@@ -1467,7 +1467,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
           return;
         }
         curSetName = newname;
-        System.err.println("New name for user setting " + curSetName
+        jalview.bin.Console.errPrintln("New name for user setting " + curSetName
                 + " (was " + setName.getSelectedItem() + ")");
         if (curSetName.equals(setName.getSelectedItem()))
         {
index 8555a78..76479e2 100644 (file)
@@ -150,7 +150,7 @@ public class PDBStructureChooserQuerySource
       String[] names = seqName.toLowerCase(Locale.ROOT).split("\\|");
       for (String name : names)
       {
-        // System.out.println("Found name : " + name);
+        // jalview.bin.Console.outPrintln("Found name : " + name);
         name.trim();
         if (isValidSeqName(name))
         {
@@ -196,7 +196,7 @@ public class PDBStructureChooserQuerySource
    */
   static boolean isValidSeqName(String seqName)
   {
-    // System.out.println("seqName : " + seqName);
+    // jalview.bin.Console.outPrintln("seqName : " + seqName);
     String ignoreList = "pdb,uniprot,swiss-prot";
     if (seqName.length() < 3)
     {
index cdf0d57..253c8dc 100644 (file)
@@ -120,7 +120,7 @@ public abstract class StructureChooserQuerySource
    */
   static boolean isValidSeqName(String seqName)
   {
-    // System.out.println("seqName : " + seqName);
+    // jalview.bin.Console.outPrintln("seqName : " + seqName);
     String ignoreList = "pdb,uniprot,swiss-prot";
     if (seqName.length() < 3)
     {
index e817b26..1cc7be4 100644 (file)
@@ -113,7 +113,7 @@ public class TDBResultAnalyser
     int idx = EXP_CATEGORIES.indexOf(upper_cat);
     if (idx == -1)
     {
-      System.out.println("Unknown category: '" + cat + "'");
+      jalview.bin.Console.outPrintln("Unknown category: '" + cat + "'");
       EXP_CATEGORIES.add(upper_cat);
       idx = EXP_CATEGORIES.size() - 1;
     }
index cbc6add..e32ba50 100644 (file)
@@ -587,7 +587,7 @@ public class ThreeDBStructureChooserQuerySource
       {
         if (!hasPdbResp)
         {
-          System.out.println(
+          jalview.bin.Console.outPrintln(
                   "Warning: seems like we couldn't get to the PDBe search interface.");
         }
         else
index ece2df0..a6e96cb 100644 (file)
@@ -67,14 +67,14 @@ public abstract class AbstractRequestHandler extends AbstractHandler
       /*
        * Set server error status on response
        */
-      System.err.println("Exception handling request "
+      jalview.bin.Console.errPrintln("Exception handling request "
               + request.getRequestURI() + " : " + t.getMessage());
       if (response.isCommitted())
       {
         /*
          * Can't write an HTTP header once any response content has been written
          */
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Unable to return HTTP 500 as response already committed");
       }
       else
@@ -105,20 +105,20 @@ public abstract class AbstractRequestHandler extends AbstractHandler
    */
   protected void dumpRequest(HttpServletRequest request)
   {
-    System.out.println(request.getMethod());
-    System.out.println(request.getRequestURL());
+    jalview.bin.Console.outPrintln(request.getMethod());
+    jalview.bin.Console.outPrintln(request.getRequestURL());
     for (String hdr : Collections.list(request.getHeaderNames()))
     {
       for (String val : Collections.list(request.getHeaders(hdr)))
       {
-        System.out.println(hdr + ": " + val);
+        jalview.bin.Console.outPrintln(hdr + ": " + val);
       }
     }
     for (String param : Collections.list(request.getParameterNames()))
     {
       for (String val : request.getParameterValues(param))
       {
-        System.out.println(param + "=" + val);
+        jalview.bin.Console.outPrintln(param + "=" + val);
       }
     }
   }
@@ -143,7 +143,7 @@ public abstract class AbstractRequestHandler extends AbstractHandler
       stop();
     } catch (Exception e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error stopping " + getName() + ": " + e.getMessage());
     }
   }
index a18d38d..b9adcc6 100644 (file)
@@ -150,13 +150,13 @@ public class HttpServer
       contextHandlers = new HandlerCollection(true);
       server.setHandler(contextHandlers);
       server.start();
-      // System.out.println(String.format(
+      // jalview.bin.Console.outPrintln(String.format(
       // "HttpServer started with %d threads", server.getThreadPool()
       // .getThreads()));
       contextRoot = server.getURI();
     } catch (Exception e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error trying to start HttpServer: " + e.getMessage());
       try
       {
@@ -195,14 +195,14 @@ public class HttpServer
     {
       for (String val : Collections.list(request.getHeaders(hdr)))
       {
-        System.out.println(hdr + ": " + val);
+        jalview.bin.Console.outPrintln(hdr + ": " + val);
       }
     }
     for (String param : Collections.list(request.getParameterNames()))
     {
       for (String val : request.getParameterValues(param))
       {
-        System.out.println(param + "=" + val);
+        jalview.bin.Console.outPrintln(param + "=" + val);
       }
     }
   }
@@ -221,7 +221,7 @@ public class HttpServer
           server.stop();
         } catch (Exception e)
         {
-          System.err.println("Error stopping Http Server on "
+          jalview.bin.Console.errPrintln("Error stopping Http Server on "
                   + server.getURI() + ": " + e.getMessage());
         }
       }
@@ -267,12 +267,12 @@ public class HttpServer
       ch.start();
     } catch (Exception e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Error starting handler for " + path + ": " + e.getMessage());
     }
 
     handler.setUri(this.contextRoot + ch.getContextPath().substring(1));
-    System.out.println("Jalview " + handler.getName()
+    jalview.bin.Console.outPrintln("Jalview " + handler.getName()
             + " handler started on " + handler.getUri());
   }
 
@@ -293,7 +293,7 @@ public class HttpServer
     {
       contextHandlers.removeHandler(ch);
       myHandlers.remove(handler);
-      System.out.println("Stopped Jalview " + handler.getName()
+      jalview.bin.Console.outPrintln("Stopped Jalview " + handler.getName()
               + " handler on " + handler.getUri());
     }
   }
index 1233940..b2cf262 100755 (executable)
@@ -82,6 +82,8 @@ public abstract class AlignFile extends FileParse
 
   private boolean dataClosed = false;
 
+  private boolean doXferSettings = true;
+
   /**
    * @return if doParse() was called at construction time
    */
@@ -152,6 +154,12 @@ public abstract class AlignFile extends FileParse
    * @param source
    * @throws IOException
    */
+  public AlignFile(FileParse source, boolean doXferSettings)
+          throws IOException
+  {
+    this(true, source, true, doXferSettings);
+  }
+
   public AlignFile(FileParse source) throws IOException
   {
     this(true, source);
@@ -174,12 +182,19 @@ public abstract class AlignFile extends FileParse
   public AlignFile(boolean parseImmediately, FileParse source,
           boolean closeData) throws IOException
   {
+    this(parseImmediately, source, closeData, true);
+  }
+
+  public AlignFile(boolean parseImmediately, FileParse source,
+          boolean closeData, boolean doXferSettings) throws IOException
+  {
     super(source);
     initData();
 
     // stash flag in case parse needs to know if it has to autoconfigure or was
     // configured after construction
     this.parseImmediately = parseImmediately;
+    this.doXferSettings = doXferSettings;
 
     if (parseImmediately)
     {
@@ -206,7 +221,7 @@ public abstract class AlignFile extends FileParse
                       + "Need to call initData() again before parsing can be reattempted.");
     }
     parseCalled = true;
-    parse();
+    parse(this.doXferSettings);
     if (closeData && !dataClosed)
     {
       dataIn.close();
@@ -371,6 +386,18 @@ public abstract class AlignFile extends FileParse
   public abstract void parse() throws IOException;
 
   /**
+   * This method is only overridden by JmolParser because of its use in
+   * StructureFile to parse annotations
+   * 
+   * @param doXferSettings
+   * @throws IOException
+   */
+  public void parse(boolean doXferSettings) throws IOException
+  {
+    parse();
+  }
+
+  /**
    * A general parser for ids.
    * 
    * @String id Id to be parsed
@@ -452,4 +479,14 @@ public abstract class AlignFile extends FileParse
   {
     seqs.add(seq);
   }
+
+  public void setDoXferSettings(boolean b)
+  {
+    doXferSettings = b;
+  }
+
+  public boolean getDoXferSettings()
+  {
+    return doXferSettings;
+  }
 }
index 09859c9..7e2539f 100755 (executable)
@@ -317,7 +317,7 @@ public class AnnotationFile
               }
               else
               {
-                // System.err.println("Skipping NaN - not valid value.");
+                // jalview.bin.Console.errPrintln("Skipping NaN - not valid value.");
                 text.append(comma + 0f);// row.annotations[j].value);
               }
               comma = ",";
@@ -679,10 +679,10 @@ public class AnnotationFile
     } catch (Exception ex)
     {
       ex.printStackTrace();
-      System.out.println("Problem reading annotation file: " + ex);
+      jalview.bin.Console.outPrintln("Problem reading annotation file: " + ex);
       if (nlinesread > 0)
       {
-        System.out.println("Last read line " + nlinesread + ": '" + lastread
+        jalview.bin.Console.outPrintln("Last read line " + nlinesread + ": '" + lastread
                 + "' (first 80 chars) ...");
       }
       return false;
@@ -821,7 +821,7 @@ public class AnnotationFile
               if (refSeqIndex < 1)
               {
                 refSeqIndex = 1;
-                System.out.println(
+                jalview.bin.Console.outPrintln(
                         "WARNING: SEQUENCE_REF index must be > 0 in AnnotationFile");
               }
             } catch (Exception ex)
@@ -923,7 +923,7 @@ public class AnnotationFile
           {
             if (hidden == null)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Cannot process HIDE_INSERTIONS without an alignment view: Ignoring line: "
                               + line);
             }
@@ -1075,7 +1075,7 @@ public class AnnotationFile
             {
               // TODO: specify and implement duplication of alignment annotation
               // for multiple group references.
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Ignoring 1:many group reference mappings for group name '"
                               + groupRef + "'");
             }
@@ -1368,7 +1368,7 @@ public class AnnotationFile
     }
     else
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Couldn't combine annotations. None are added to alignment yet!");
     }
   }
@@ -1385,7 +1385,7 @@ public class AnnotationFile
       value = Float.valueOf(nextToken);
     } catch (NumberFormatException e)
     {
-      System.err.println("line " + nlinesread + ": Threshold '" + nextToken
+      jalview.bin.Console.errPrintln("line " + nlinesread + ": Threshold '" + nextToken
               + "' invalid, setting to zero");
     }
     String label = st.hasMoreTokens() ? st.nextToken() : null;
@@ -1435,7 +1435,7 @@ public class AnnotationFile
       }
     } catch (Exception e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Couldn't parse Group Start or End Field as '*' or a valid column or sequence index: '"
                       + rng + "' - assuming alignment width for group.");
       // assume group is full width
index 9a4e982..56e9fa1 100755 (executable)
@@ -215,7 +215,7 @@ public class AppletFormatAdapter
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println("Failed to read alignment using the '" + fileFormat
+      jalview.bin.Console.errPrintln("Failed to read alignment using the '" + fileFormat
               + "' reader.\n" + e);
 
       if (e.getMessage() != null
@@ -297,7 +297,7 @@ public class AppletFormatAdapter
     } catch (Exception e)
     {
       e.printStackTrace();
-      System.err.println("Failed to read alignment using the '" + format
+      jalview.bin.Console.errPrintln("Failed to read alignment using the '" + format
               + "' reader.\n" + e);
 
       if (e.getMessage() != null
@@ -424,13 +424,13 @@ public class AppletFormatAdapter
       String afileresp = afile.print(seqs, jvsuffix);
       if (afile.hasWarningMessage())
       {
-        System.err.println("Warning raised when writing as " + format
+        jalview.bin.Console.errPrintln("Warning raised when writing as " + format
                 + " : " + afile.getWarningMessage());
       }
       return afileresp;
     } catch (Exception e)
     {
-      System.err.println("Failed to write alignment as a '"
+      jalview.bin.Console.errPrintln("Failed to write alignment as a '"
               + format.getName() + "' file\n");
       e.printStackTrace();
     }
@@ -488,7 +488,7 @@ public class AppletFormatAdapter
       {
         try
         {
-          System.out.println("Reading file: " + f);
+          jalview.bin.Console.outPrintln("Reading file: " + f);
           AppletFormatAdapter afa = new AppletFormatAdapter();
           Runtime r = Runtime.getRuntime();
           System.gc();
@@ -502,36 +502,36 @@ public class AppletFormatAdapter
           memf += r.totalMemory() - r.freeMemory();
           if (al != null)
           {
-            System.out.println("Alignment contains " + al.getHeight()
+            jalview.bin.Console.outPrintln("Alignment contains " + al.getHeight()
                     + " sequences and " + al.getWidth() + " columns.");
             try
             {
-              System.out.println(new AppletFormatAdapter()
+              jalview.bin.Console.outPrintln(new AppletFormatAdapter()
                       .formatSequences(FileFormat.Fasta, al, true));
             } catch (Exception e)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Couln't format the alignment for output as a FASTA file.");
               e.printStackTrace(System.err);
             }
           }
           else
           {
-            System.out.println("Couldn't read alignment");
+            jalview.bin.Console.outPrintln("Couldn't read alignment");
           }
-          System.out.println("Read took " + (t1 / 1000.0) + " seconds.");
-          System.out.println(
+          jalview.bin.Console.outPrintln("Read took " + (t1 / 1000.0) + " seconds.");
+          jalview.bin.Console.outPrintln(
                   "Difference between free memory now and before is "
                           + (memf / (1024.0 * 1024.0) * 1.0) + " MB");
         } catch (Exception e)
         {
-          System.err.println("Exception when dealing with " + i
+          jalview.bin.Console.errPrintln("Exception when dealing with " + i
                   + "'th argument: " + args[i] + "\n" + e);
         }
       }
       else
       {
-        System.err.println("Ignoring argument '" + args[i] + "' (" + i
+        jalview.bin.Console.errPrintln("Ignoring argument '" + args[i] + "' (" + i
                 + "'th)- not a readable file.");
       }
       i++;
@@ -559,7 +559,7 @@ public class AppletFormatAdapter
     DataSourceType protocol = null;
     if (debug)
     {
-      System.out.println("resolving datasource started with:\n>>file\n"
+      jalview.bin.Console.outPrintln("resolving datasource started with:\n>>file\n"
               + file + ">>endfile");
     }
 
@@ -577,7 +577,7 @@ public class AppletFormatAdapter
       }
       if (debug)
       {
-        System.err.println("Resource '" + file + "' was "
+        jalview.bin.Console.errPrintln("Resource '" + file + "' was "
                 + (rtn ? "" : "not") + " located by classloader.");
       }
       if (rtn)
@@ -605,7 +605,7 @@ public class AppletFormatAdapter
     {
       if (debug)
       {
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "Trying to get contents of resource as " + protocol + ":");
       }
       fp = new FileParse(file, protocol);
@@ -617,14 +617,14 @@ public class AppletFormatAdapter
       {
         if (debug)
         {
-          System.out.println("Successful.");
+          jalview.bin.Console.outPrintln("Successful.");
         }
       }
     } catch (Exception e)
     {
       if (debug)
       {
-        System.err.println("Exception when accessing content: " + e);
+        jalview.bin.Console.errPrintln("Exception when accessing content: " + e);
       }
       fp = null;
     }
@@ -632,7 +632,7 @@ public class AppletFormatAdapter
     {
       if (debug)
       {
-        System.out.println("Accessing as paste.");
+        jalview.bin.Console.outPrintln("Accessing as paste.");
       }
       protocol = DataSourceType.PASTE;
       fp = null;
@@ -645,7 +645,7 @@ public class AppletFormatAdapter
         }
       } catch (Exception e)
       {
-        System.err.println("Failed to access content as paste!");
+        jalview.bin.Console.errPrintln("Failed to access content as paste!");
         e.printStackTrace();
         fp = null;
       }
@@ -667,20 +667,20 @@ public class AppletFormatAdapter
         {
           if (debug)
           {
-            System.out.println("Format not identified. Inaccessible file.");
+            jalview.bin.Console.outPrintln("Format not identified. Inaccessible file.");
           }
           return null;
         }
         if (debug)
         {
-          System.out.println("Format identified as " + idformat
+          jalview.bin.Console.outPrintln("Format identified as " + idformat
                   + "and expected as " + format);
         }
         if (idformat.equals(format))
         {
           if (debug)
           {
-            System.out.println("Protocol identified as " + protocol);
+            jalview.bin.Console.outPrintln("Protocol identified as " + protocol);
           }
           return protocol;
         }
@@ -698,7 +698,7 @@ public class AppletFormatAdapter
       {
         if (debug)
         {
-          System.err.println("File deemed not accessible via " + protocol);
+          jalview.bin.Console.errPrintln("File deemed not accessible via " + protocol);
           e.printStackTrace();
         }
       }
index b8a721e..1a08363 100644 (file)
@@ -54,7 +54,7 @@ public class BackupFilenameFilter implements FilenameFilter
       }
     } catch (IOException e)
     {
-      System.out.println("IOException when checking file '" + filename
+      jalview.bin.Console.outPrintln("IOException when checking file '" + filename
               + "' is a backupfile");
     }
 
index 14c1260..c67c307 100644 (file)
@@ -232,6 +232,12 @@ public class BackupFiles
   public BackupFiles(File file)
   {
     classInit();
+    if (file.getParentFile() == null)
+    {
+      // filename probably in pwd represented with no parent -- fix it before
+      // it's a problem
+      file = file.getAbsoluteFile();
+    }
     this.file = file;
 
     // add this file from the save in progress stack
@@ -252,7 +258,7 @@ public class BackupFiles
       if (file != null)
       {
         String tempfilename = file.getName();
-        File tempdir = file.getParentFile();
+        File tempdir = file.getAbsoluteFile().getParentFile();
         tempdir.mkdirs();
         Console.trace(
                 "BACKUPFILES [file!=null] attempting to create temp file for "
@@ -283,7 +289,7 @@ public class BackupFiles
     this.setTempFile(temp);
   }
 
-  public static void classInit()
+  private static void classInit()
   {
     Console.initLogger();
     Console.trace("BACKUPFILES classInit");
index c88d8eb..eef203f 100644 (file)
  */
 package jalview.io;
 
-import jalview.bin.Cache;
-import jalview.gui.AlignmentPanel;
-import jalview.gui.OOMWarning;
-import jalview.json.binding.biojs.BioJSReleasePojo;
-import jalview.json.binding.biojs.BioJSRepositoryPojo;
-import jalview.util.MessageManager;
-
 import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.File;
@@ -39,6 +32,13 @@ import java.net.URL;
 import java.util.Objects;
 import java.util.TreeMap;
 
+import jalview.bin.Cache;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.OOMWarning;
+import jalview.json.binding.biojs.BioJSReleasePojo;
+import jalview.json.binding.biojs.BioJSRepositoryPojo;
+import jalview.util.MessageManager;
+
 public class BioJsHTMLOutput extends HTMLOutput
 {
   private static File currentBJSTemplateFile;
@@ -138,7 +138,7 @@ public class BioJsHTMLOutput extends HTMLOutput
       {
         if (!biojsDirectory.mkdirs())
         {
-          System.out.println("Couldn't create local directory : "
+          jalview.bin.Console.outPrintln("Couldn't create local directory : "
                   + BJS_TEMPLATES_LOCAL_DIRECTORY);
           return;
         }
@@ -264,7 +264,7 @@ public class BioJsHTMLOutput extends HTMLOutput
 
     } catch (OutOfMemoryError err)
     {
-      System.out.println("########################\n" + "OUT OF MEMORY "
+      jalview.bin.Console.outPrintln("########################\n" + "OUT OF MEMORY "
               + generatedFile + "\n" + "########################");
       new OOMWarning("Creating Image for " + generatedFile, err);
     } catch (Exception e)
@@ -276,4 +276,10 @@ public class BioJsHTMLOutput extends HTMLOutput
 
   }
 
+  @Override
+  public void run(String s)
+  {
+    run();
+  }
+
 }
index afb2009..a71e6e8 100755 (executable)
@@ -140,7 +140,7 @@ public class ClustalFile extends AlignFile
       }
     } catch (IOException e)
     {
-      System.err.println("Exception parsing clustal file " + e);
+      jalview.bin.Console.errPrintln("Exception parsing clustal file " + e);
       e.printStackTrace();
     }
 
@@ -168,7 +168,7 @@ public class ClustalFile extends AlignFile
         }
         else
         {
-          System.err.println("Clustal File Reader: Can't find sequence for "
+          jalview.bin.Console.errPrintln("Clustal File Reader: Can't find sequence for "
                   + headers.elementAt(i));
         }
       }
index 6332561..a704f24 100755 (executable)
@@ -312,7 +312,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
       // should report somewhere useful for UI if necessary
       warningMessage = ((warningMessage == null) ? "" : warningMessage)
               + "Parsing error at\n" + line;
-      System.out.println("Error parsing feature file: " + ex + "\n" + line);
+      jalview.bin.Console.outPrintln("Error parsing feature file: " + ex + "\n" + line);
       ex.printStackTrace(System.err);
       resetMatcher();
       return false;
@@ -354,7 +354,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
       String[] tokens = line.split(TAB_REGEX);
       if (tokens.length != 2)
       {
-        System.err.println(String.format("Invalid token count %d for %d",
+        jalview.bin.Console.errPrintln(String.format("Invalid token count %d for %d",
                 tokens.length, line));
       }
       else
@@ -392,7 +392,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
      */
     if (gffColumns.length < 6)
     {
-      System.err.println("Ignoring feature line '" + line
+      jalview.bin.Console.errPrintln("Ignoring feature line '" + line
               + "' with too few columns (" + gffColumns.length + ")");
       return false;
     }
@@ -415,13 +415,13 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
         seq = alignment.getSequenceAt(idx);
       } catch (NumberFormatException ex)
       {
-        System.err.println("Invalid sequence index: " + seqIndex);
+        jalview.bin.Console.errPrintln("Invalid sequence index: " + seqIndex);
       }
     }
 
     if (seq == null)
     {
-      System.out.println("Sequence not found: " + line);
+      jalview.bin.Console.outPrintln("Sequence not found: " + line);
       return false;
     }
 
@@ -1009,7 +1009,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
   @Override
   public String print(SequenceI[] sqs, boolean jvsuffix)
   {
-    System.out.println("Use printGffFormat() or printJalviewFormat()");
+    jalview.bin.Console.outPrintln("Use printGffFormat() or printJalviewFormat()");
     return null;
   }
 
@@ -1333,7 +1333,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
      */
     if (gffColumns.length < 5)
     {
-      System.err.println("Ignoring GFF feature line with too few columns ("
+      jalview.bin.Console.errPrintln("Ignoring GFF feature line with too few columns ("
               + gffColumns.length + ")");
       return null;
     }
@@ -1364,7 +1364,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
         }
       } catch (IOException e)
       {
-        System.err.println("GFF parsing failed with: " + e.getMessage());
+        jalview.bin.Console.errPrintln("GFF parsing failed with: " + e.getMessage());
         return null;
       }
     }
@@ -1532,7 +1532,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
     }
     else
     {
-      System.err.println("Ignoring unknown pragma: " + line);
+      jalview.bin.Console.errPrintln("Ignoring unknown pragma: " + line);
     }
   }
 }
index b701963..43c6dcf 100644 (file)
@@ -30,7 +30,7 @@ import jalview.structure.StructureImportSettings;
 
 public enum FileFormat implements FileFormatI
 {
-  Fasta("Fasta", "fa, fasta, mfa, fastq", true, true)
+  Fasta("Fasta", "fa,fasta,mfa,fastq", true, true)
   {
     @Override
     public AlignmentFileReaderI getReader(FileParse source)
@@ -92,7 +92,7 @@ public enum FileFormat implements FileFormatI
       return new PIRFile();
     }
   },
-  BLC("BLC", "BLC", true, true)
+  BLC("BLC", "blc", true, true)
   {
     @Override
     public AlignmentFileReaderI getReader(FileParse source)
@@ -244,7 +244,7 @@ public enum FileFormat implements FileFormatI
       return new PhylipFile();
     }
   },
-  GenBank("GenBank Flatfile", "gb, gbk", true, false)
+  GenBank("GenBank Flatfile", "gb,gbk", true, false)
   {
     @Override
     public AlignmentFileReaderI getReader(FileParse source)
@@ -379,7 +379,7 @@ public enum FileFormat implements FileFormatI
       return true;
     }
   },
-  Jalview("Jalview", "jvp, jar", true, true)
+  Jalview("Jalview", "jvp,jar", true, true)
   {
     @Override
     public AlignmentFileReaderI getReader(FileParse source)
index b7dd834..96489d0 100644 (file)
@@ -107,7 +107,7 @@ public class FileFormats
     String name = format.getName().toUpperCase(Locale.ROOT);
     if (formats.containsKey(name))
     {
-      System.err.println("Overwriting file format: " + format.getName());
+      jalview.bin.Console.errPrintln("Overwriting file format: " + format.getName());
     }
     formats.put(name, format);
     if (isIdentifiable)
index 449c685..dc7adac 100755 (executable)
@@ -74,6 +74,8 @@ public class FileLoader implements Runnable
 
   private File selectedFile;
 
+  private static boolean useDefaultFileFormat = false;
+
   /**
    * default constructor always raised errors in GUI dialog boxes
    */
@@ -96,32 +98,51 @@ public class FileLoader implements Runnable
   public void LoadFile(AlignViewport viewport, Object file,
           DataSourceType protocol, FileFormatI format)
   {
+    LoadFile(viewport, file, protocol, format, true);
+  }
+
+  public void LoadFile(AlignViewport viewport, Object file,
+          DataSourceType protocol, FileFormatI format, boolean async)
+  {
     this.viewport = viewport;
     if (file instanceof File)
     {
       this.selectedFile = (File) file;
       file = selectedFile.getPath();
     }
-    LoadFile(file.toString(), protocol, format);
+    LoadFile(file.toString(), protocol, format, async);
   }
 
   public void LoadFile(String file, DataSourceType protocol,
           FileFormatI format)
   {
+    LoadFile(file, protocol, format, true);
+  }
+
+  public void LoadFile(String file, DataSourceType protocol,
+          FileFormatI format, boolean async)
+  {
     this.file = file;
     this.protocol = protocol;
     this.format = format;
 
-    final Thread loader = new Thread(this);
-
-    SwingUtilities.invokeLater(new Runnable()
+    if (async)
     {
-      @Override
-      public void run()
+      final Thread loader = new Thread(this);
+
+      SwingUtilities.invokeLater(new Runnable()
       {
-        loader.start();
-      }
-    });
+        @Override
+        public void run()
+        {
+          loader.start();
+        }
+      });
+    }
+    else
+    {
+      this.run();
+    }
   }
 
   /**
@@ -302,9 +323,9 @@ public class FileLoader implements Runnable
       if (format == null)
       {
         Desktop.instance.stopLoading();
-        System.err.println("The input file \"" + file
+        jalview.bin.Console.errPrintln("The input file \"" + file
                 + "\" has null or unidentifiable data content!");
-        if (!Jalview.isHeadlessMode())
+        if (!Jalview.isHeadlessMode() && !Jalview.isBatchMode())
         {
           JvOptionPane.showInternalMessageDialog(Desktop.desktop,
                   MessageManager.getString("label.couldnt_read_data")
@@ -313,7 +334,8 @@ public class FileLoader implements Runnable
                   MessageManager.getString("label.couldnt_read_data"),
                   JvOptionPane.WARNING_MESSAGE);
         }
-        this.setShouldBeSaved();
+        // don't set shouldBeSaved if didn't load anything
+        // this.setShouldBeSaved();
         return;
       }
       // TODO: cache any stream datasources as a temporary file (eg. PDBs
@@ -334,12 +356,12 @@ public class FileLoader implements Runnable
         if (source != null)
         {
           // Tell the user (developer?) that this is going to cause a problem
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "IMPLEMENTATION ERROR: Cannot read consecutive Jalview XML projects from a stream.");
           // We read the data anyway - it might make sense.
         }
         // BH 2018 switch to File object here instead of filename
-        alignFrame = new Jalview2XML(raiseGUI).loadJalviewAlign(
+        alignFrame = new Jalview2XML(raiseGUI && !Jalview.isBatchMode()).loadJalviewAlign(
                 selectedFile == null ? file : selectedFile);
       }
       else
@@ -515,7 +537,7 @@ public class FileLoader implements Runnable
                   "label.couldnt_load_file") + " " + title + "\n" + error;
           // TODO: refactor FileLoader to be independent of Desktop / Applet GUI
           // bits ?
-          if (raiseGUI && Desktop.desktop != null)
+          if (raiseGUI && !Jalview.isBatchMode() && Desktop.desktop != null)
           {
             javax.swing.SwingUtilities.invokeLater(new Runnable()
             {
@@ -532,7 +554,7 @@ public class FileLoader implements Runnable
           }
           else
           {
-            System.err.println(errorMessage);
+            jalview.bin.Console.errPrintln(errorMessage);
           }
         }
       }
@@ -541,9 +563,9 @@ public class FileLoader implements Runnable
 
     } catch (Exception er)
     {
-      System.err.println("Exception whilst opening file '" + file);
+      jalview.bin.Console.errPrintln("Exception whilst opening file '" + file);
       er.printStackTrace();
-      if (raiseGUI)
+      if (raiseGUI && !Jalview.isBatchMode())
       {
         javax.swing.SwingUtilities.invokeLater(new Runnable()
         {
@@ -565,7 +587,7 @@ public class FileLoader implements Runnable
 
       er.printStackTrace();
       alignFrame = null;
-      if (raiseGUI)
+      if (raiseGUI && !Jalview.isBatchMode())
       {
         javax.swing.SwingUtilities.invokeLater(new Runnable()
         {
@@ -581,7 +603,7 @@ public class FileLoader implements Runnable
           }
         });
       }
-      System.err.println("Out of memory loading file " + file + "!!");
+      jalview.bin.Console.errPrintln("Out of memory loading file " + file + "!!");
 
     }
     loadtime += System.currentTimeMillis();
@@ -600,7 +622,7 @@ public class FileLoader implements Runnable
       {
         AlignmentI al = alignFrame.getViewport().getAlignment();
 
-        System.out.println("Loaded '" + title + "' in "
+        jalview.bin.Console.outPrintln("Loaded '" + title + "' in "
                 + (loadtime / 1000.0) + "s, took an additional "
                 + (1.0 * memused / (1024.0 * 1024.0)) + " MB ("
                 + al.getHeight() + " seqs by " + al.getWidth() + " cols)");
@@ -609,7 +631,7 @@ public class FileLoader implements Runnable
       {
         // report that we didn't load anything probably due to an out of memory
         // error
-        System.out.println("Failed to load '" + title + "' in "
+        jalview.bin.Console.outPrintln("Failed to load '" + title + "' in "
                 + (loadtime / 1000.0) + "s, took an additional "
                 + (1.0 * memused / (1024.0 * 1024.0))
                 + " MB (alignment is null)");
@@ -622,6 +644,8 @@ public class FileLoader implements Runnable
     }
 
     this.setShouldBeSaved();
+    // after first file loaded we revert to assuming a default file format
+    useDefaultFileFormat = true;
   }
 
   /**
@@ -664,4 +688,9 @@ public class FileLoader implements Runnable
             QuitHandler.Message.UNSAVED_ALIGNMENTS);
   }
 
+  public static boolean getUseDefaultFileFormat()
+  {
+    return useDefaultFileFormat;
+  }
+
 }
index d3a6ba9..1f51d8c 100755 (executable)
@@ -343,8 +343,8 @@ public class FileParse
     }
     String encoding = _conn.getContentEncoding();
     String contentType = _conn.getContentType();
-    boolean isgzipped = "application/x-gzip".equalsIgnoreCase(contentType) || contentType.endsWith("gzip")
-            || "gzip".equals(encoding);
+    boolean isgzipped = "application/x-gzip".equalsIgnoreCase(contentType)
+            || contentType.endsWith("gzip") || "gzip".equals(encoding);
     Exception e = null;
     InputStream inputStream = _conn.getInputStream();
     if (isgzipped)
@@ -380,7 +380,7 @@ public class FileParse
     if (sfpos > -1 && sfpos < fileStr.length() - 1)
     {
       suffix = fileStr.substring(sfpos + 1);
-      // System.err.println("DEBUG: Found Suffix:"+suffix);
+      // jalview.bin.Console.errPrintln("DEBUG: Found Suffix:"+suffix);
       return fileStr.substring(0, sfpos);
     }
     return null;
@@ -634,7 +634,7 @@ public class FileParse
   {
     if (bytesRead >= READAHEAD_LIMIT)
     {
-      System.err.println(String.format(
+      jalview.bin.Console.errPrintln(String.format(
               "File reset error: read %d bytes but reset limit is %d",
               bytesRead, READAHEAD_LIMIT));
     }
index 2745420..02d46e7 100644 (file)
@@ -34,6 +34,7 @@ import jalview.datamodel.AlignExportSettingsAdapter;
 import jalview.datamodel.AlignmentExportData;
 import jalview.gui.AlignmentPanel;
 import jalview.gui.IProgressIndicator;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.util.MessageManager;
 
 public abstract class HTMLOutput implements Runnable
@@ -238,7 +239,7 @@ public abstract class HTMLOutput implements Runnable
     }
     else
     {
-      System.out.println(message);
+      jalview.bin.Console.outPrintln(message);
     }
   }
 
@@ -302,7 +303,12 @@ public abstract class HTMLOutput implements Runnable
     return generatedFile;
   }
 
-  public void exportHTML(String outputFile)
+  public void exportHTML(String outputFile) throws ImageOutputException
+  {
+    exportHTML(outputFile, null);
+  }
+
+  public void exportHTML(String outputFile, String renderer) throws ImageOutputException
   {
     setProgressMessage(MessageManager.formatMessage(
             "status.exporting_alignment_as_x_file", getDescription()));
@@ -332,7 +338,7 @@ public abstract class HTMLOutput implements Runnable
     }
     if (Jalview.isHeadlessMode())
     {
-      this.run();
+      this.run(renderer);
     }
     else
     {
@@ -351,4 +357,7 @@ public abstract class HTMLOutput implements Runnable
   {
     return description;
   }
+
+  // used to pass an option such as render to run
+  public abstract void run(String string) throws ImageOutputException;
 }
\ No newline at end of file
index 9fb3720..b5fdc2c 100644 (file)
@@ -25,7 +25,7 @@ import java.awt.print.PrinterException;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.util.concurrent.Callable;
+import java.util.Locale;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.jfree.graphics2d.svg.SVGGraphics2D;
@@ -202,32 +202,39 @@ public class HtmlSvgOutput extends HTMLOutput
   @Override
   public void run()
   {
+    run(null);
+  }
+
+  @Override
+  public void run(String renderer)
+  {
     try
     {
-      String renderStyle = Cache.getDefault("HTML_RENDERING",
-              "Prompt each time");
+      String renderStyle = renderer == null
+              ? Cache.getDefault("HTML_RENDERING",
+                      LineartOptions.PROMPT_EACH_TIME)
+              : renderer;
       AtomicBoolean textOption = new AtomicBoolean(
-              !"Lineart".equals(renderStyle));
+              !"lineart".equals(renderStyle.toLowerCase(Locale.ROOT)));
 
       /*
        * configure the action to run on OK in the dialog
        */
-      Callable<Void> okAction = () -> {
+      Runnable okAction = () -> {
         doOutput(textOption.get());
-        return null;
       };
 
       /*
        * Prompt for character rendering style if preference is not set
        */
-      if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless())
+      if (renderStyle.equalsIgnoreCase(LineartOptions.PROMPT_EACH_TIME)
+              && !isHeadless())
       {
         LineartOptions svgOption = new LineartOptions("HTML", textOption);
         svgOption.setResponseAction(1, () -> {
           setProgressMessage(MessageManager.formatMessage(
                   "status.cancelled_image_export_operation",
                   getDescription()));
-          return null;
         });
         svgOption.setResponseAction(0, okAction);
         svgOption.showDialog();
@@ -242,7 +249,7 @@ public class HtmlSvgOutput extends HTMLOutput
       }
     } catch (OutOfMemoryError err)
     {
-      System.out.println("########################\n" + "OUT OF MEMORY "
+      jalview.bin.Console.outPrintln("########################\n" + "OUT OF MEMORY "
               + generatedFile + "\n" + "########################");
       new OOMWarning("Creating Image for " + generatedFile, err);
     } catch (Exception e)
index c21127e..ea87058 100755 (executable)
  */
 package jalview.io;
 
-import java.util.Locale;
-
 import java.io.File;
 import java.io.IOException;
+import java.util.Locale;
+
+import jalview.bin.Console;
 
 /**
  * DOCUMENT ME!
@@ -58,8 +59,7 @@ public class IdentifyFile
       }
     } catch (Exception e)
     {
-      System.err.println("Error whilst identifying " + file);
-      e.printStackTrace(System.err);
+      Console.error("Error whilst identifying " + file, e);
       emessage = e.getMessage();
     }
     if (parser != null)
@@ -94,8 +94,7 @@ public class IdentifyFile
       }
     } catch (Exception e)
     {
-      System.err.println("Error whilst identifying " + file);
-      e.printStackTrace(System.err);
+      Console.error("Error whilst identifying " + file, e);
       emessage = e.getMessage();
     }
     if (parser != null)
@@ -408,16 +407,15 @@ public class IdentifyFile
       }
     } catch (Exception ex)
     {
-      System.err.println("File Identification failed!\n" + ex);
+      Console.error("File Identification failed!\n" + ex);
       throw new FileFormatException(source.errormessage);
     }
     if (trimmedLength == 0)
     {
-      System.err.println(
-              "File Identification failed! - Empty file was read.");
+      Console.error("File Identification failed! - Empty file was read.");
       throw new FileFormatException("EMPTY DATA FILE");
     }
-    System.out.println("File format identified as " + reply.toString());
+    Console.debug("File format identified as " + reply.toString());
     return reply;
   }
 
@@ -485,15 +483,15 @@ public class IdentifyFile
         type = ider.identify(args[i], DataSourceType.FILE);
       } catch (FileFormatException e)
       {
-        System.err.println(
+        Console.error(
                 String.format("Error '%s' identifying file type for %s",
                         args[i], e.getMessage()));
       }
-      System.out.println("Type of " + args[i] + " is " + type);
+      Console.debug("Type of " + args[i] + " is " + type);
     }
     if (args == null || args.length == 0)
     {
-      System.err.println("Usage: <Filename> [<Filename> ...]");
+      Console.error("Usage: <Filename> [<Filename> ...]");
     }
   }
 
index ab2c00a..9f8ac4e 100755 (executable)
@@ -150,7 +150,7 @@ public class JPredFile extends AlignFile
   @Override
   public void parse() throws IOException
   {
-    // JBPNote log.System.out.println("all read in ");
+    // JBPNote log.jalview.bin.Console.outPrintln("all read in ");
     String line;
     QuerySeqPosition = -1;
     noSeqs = 0;
@@ -240,7 +240,7 @@ public class JPredFile extends AlignFile
       }
       else if (id.equals("jnetconf"))
       {
-        // log.debug System.out.println("here");
+        // log.debug jalview.bin.Console.outPrintln("here");
         id = "Prediction Confidence";
         this.conf = new Vector(numSymbols);
 
@@ -377,14 +377,14 @@ public class JPredFile extends AlignFile
 
       for (int i = 0; i < jpred.seqs.size(); i++)
       {
-        System.out.println(((Sequence) jpred.seqs.elementAt(i)).getName()
+        jalview.bin.Console.outPrintln(((Sequence) jpred.seqs.elementAt(i)).getName()
                 + "\n"
                 + ((Sequence) jpred.seqs.elementAt(i)).getSequenceAsString()
                 + "\n");
       }
     } catch (java.io.IOException e)
     {
-      System.err.println("Exception " + e);
+      jalview.bin.Console.errPrintln("Exception " + e);
       // e.printStackTrace(); not java 1.1 compatible!
     }
   }
@@ -447,6 +447,6 @@ public class JPredFile extends AlignFile
  * out = BLCFile.print(s);
  * 
  * AlignFrame af = new AlignFrame(null, s); af.resize(700, 500); af.show();
- * System.out.println(out); } catch (java.io.IOException e) {
- * System.out.println("Exception " + e); } } }
+ * jalview.bin.Console.outPrintln(out); } catch (java.io.IOException e) {
+ * jalview.bin.Console.outPrintln("Exception " + e); } } }
  */
index 2ee305f..0b45ba6 100644 (file)
@@ -363,7 +363,7 @@ public class JSONFile extends AlignFile implements ComplexAlignFile
                   .setSecondaryStructure(annotation.secondaryStructure);
           String displayChar = annotation.displayCharacter == null ? null
                   : annotation.displayCharacter;
-          // System.out.println("--------------------->[" + displayChar + "]");
+          // jalview.bin.Console.outPrintln("--------------------->[" + displayChar + "]");
           annotationPojo.setDisplayCharacter(displayChar);
           if (annotation.colour != null)
           {
index 3b6e325..3f44596 100755 (executable)
 //////////////////////////////////////////////////////////////////
 package jalview.io;
 
-import jalview.bin.Cache;
-import jalview.gui.JvOptionPane;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-import jalview.util.dialogrunner.DialogRunnerI;
-
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.EventQueue;
@@ -44,18 +38,21 @@ import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.Vector;
-import java.util.concurrent.Callable;
 
 import javax.swing.BoxLayout;
-import javax.swing.DefaultListCellRenderer;
 import javax.swing.JCheckBox;
 import javax.swing.JDialog;
 import javax.swing.JFileChooser;
+import javax.swing.JLabel;
 import javax.swing.JList;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
+import javax.swing.ListCellRenderer;
 import javax.swing.SpringLayout;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.border.TitledBorder;
 import javax.swing.filechooser.FileFilter;
 import javax.swing.plaf.basic.BasicFileChooserUI;
 
@@ -80,7 +77,7 @@ public class JalviewFileChooser extends JFileChooser
 {
   private static final long serialVersionUID = 1L;
 
-  private Map<Object, Callable> callbacks = new HashMap<>();
+  private Map<Object, Runnable> callbacks = new HashMap<>();
 
   File selectedFile = null;
 
@@ -200,7 +197,7 @@ public class JalviewFileChooser extends JFileChooser
     }
     else
     {
-      System.err.println("JalviewFileChooser arguments mismatch: "
+      jalview.bin.Console.errPrintln("JalviewFileChooser arguments mismatch: "
               + extensions + ", " + descs);
     }
   }
@@ -269,6 +266,31 @@ public class JalviewFileChooser extends JFileChooser
     // file filters to fix bug on Mac OSX
     setAcceptAllFileFilterUsed(acceptAny);
 
+    // add a "All known alignment files" option
+    List<String> allExtensions = new ArrayList<>();
+    for (String[] format : formats)
+    {
+      String[] extensions = format[0].split(",");
+      for (String ext : extensions)
+      {
+        if (!allExtensions.contains(ext))
+        {
+          allExtensions.add(ext);
+        }
+      }
+    }
+    allExtensions.sort(null);
+    JalviewFileFilter alljvf = new JalviewFileFilter(
+            allExtensions.toArray(new String[] {}),
+            MessageManager.getString("label.all_known_alignment_files"));
+    alljvf.setExtensionListInDescription(false);
+    addChoosableFileFilter(alljvf);
+
+    if (selected == null)
+    {
+      chosen = alljvf;
+    }
+
     for (String[] format : formats)
     {
       JalviewFileFilter jvf = new JalviewFileFilter(format[0], format[1]);
@@ -415,7 +437,7 @@ public class JalviewFileChooser extends JFileChooser
         return FileFormats.getInstance().forName(format);
       } catch (IllegalArgumentException e)
       {
-        System.err.println("Unexpected format: " + format);
+        jalview.bin.Console.errPrintln("Unexpected format: " + format);
       }
     }
     return null;
@@ -469,7 +491,7 @@ public class JalviewFileChooser extends JFileChooser
         }
       } catch (Throwable x)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Unexpected exception when trying to get filename.");
         x.printStackTrace();
       }
@@ -531,6 +553,11 @@ public class JalviewFileChooser extends JFileChooser
         }
       }
 
+      if (!file.isAbsolute() && file.exists())
+      {
+        file = file.getAbsoluteFile();
+      }
+
       setSelectedFile(file);
     }
   }
@@ -559,10 +586,7 @@ public class JalviewFileChooser extends JFileChooser
       }
 
       list = new JList<>(recent);
-
-      DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
-      dlcr.setHorizontalAlignment(DefaultListCellRenderer.RIGHT);
-      list.setCellRenderer(dlcr);
+      list.setCellRenderer(new recentlyOpenedCellRenderer());
 
       list.addMouseListener(new MouseAdapter()
       {
@@ -573,8 +597,11 @@ public class JalviewFileChooser extends JFileChooser
         }
       });
 
-      this.setBorder(new javax.swing.border.TitledBorder(
-              MessageManager.getString("label.recently_opened")));
+      TitledBorder recentlyOpenedBorder = new TitledBorder(
+              MessageManager.getString("label.recently_opened"));
+      recentlyOpenedBorder.setTitleFont(
+              recentlyOpenedBorder.getTitleFont().deriveFont(10f));
+      this.setBorder(recentlyOpenedBorder);
 
       final JScrollPane scroller = new JScrollPane(list);
 
@@ -584,18 +611,11 @@ public class JalviewFileChooser extends JFileChooser
       layout.putConstraint(SpringLayout.NORTH, scroller, 5,
               SpringLayout.NORTH, this);
 
-      if (Platform.isAMacAndNotJS())
-      {
-        scroller.setPreferredSize(new Dimension(500, 100));
-      }
-      else
-      {
-        scroller.setPreferredSize(new Dimension(530, 200));
-      }
-
+      // one size okay for all
+      scroller.setPreferredSize(new Dimension(280, 105));
       this.add(scroller);
 
-      javax.swing.SwingUtilities.invokeLater(new Runnable()
+      SwingUtilities.invokeLater(new Runnable()
       {
         @Override
         public void run()
@@ -609,6 +629,77 @@ public class JalviewFileChooser extends JFileChooser
 
   }
 
+  class recentlyOpenedCellRenderer extends JLabel
+          implements ListCellRenderer<String>
+  {
+    private final static int maxChars = 46;
+
+    private final static String ellipsis = "...";
+
+    @Override
+    public Component getListCellRendererComponent(
+            JList<? extends String> list, String value, int index,
+            boolean isSelected, boolean cellHasFocus)
+    {
+      String filename = value.toString();
+      String displayFilename;
+      if (filename.length() > maxChars)
+      {
+        StringBuilder displayFileSB = new StringBuilder();
+        File file = new File(filename);
+        displayFileSB.append(file.getName());
+        if (file.getParent() != null)
+        {
+          File parent = file;
+          boolean spaceleft = true;
+          while (spaceleft && parent.getParent() != null)
+          {
+            parent = parent.getParentFile();
+            String name = parent.getName();
+            displayFileSB.insert(0, File.separator);
+            if (displayFileSB.length() + name.length() < maxChars - 1)
+            {
+              displayFileSB.insert(0, name);
+            }
+            else
+            {
+              displayFileSB.insert(0, ellipsis);
+              spaceleft = false;
+            }
+          }
+          if (spaceleft && filename.startsWith(File.separator)
+                  && !(displayFileSB.charAt(0) == File.separatorChar))
+          {
+            displayFileSB.insert(0, File.separator);
+          }
+        }
+        displayFilename = displayFileSB.toString();
+      }
+      else
+      {
+        displayFilename = filename;
+      }
+      this.setText(displayFilename.toString());
+      this.setToolTipText(filename);
+      if (isSelected)
+      {
+        setBackground(list.getSelectionBackground());
+        setForeground(list.getSelectionForeground());
+      }
+      else
+      {
+        setBackground(list.getBackground());
+        setForeground(list.getForeground());
+      }
+      this.setHorizontalAlignment(SwingConstants.TRAILING);
+      this.setEnabled(list.isEnabled());
+      this.setFont(list.getFont().deriveFont(12f));
+      this.setOpaque(true);
+      return this;
+    }
+
+  }
+
   /*
   @Override
   public JalviewFileChooser setResponseHandler(Object response,
@@ -628,7 +719,7 @@ public class JalviewFileChooser extends JFileChooser
   */
 
   @Override
-  public DialogRunnerI setResponseHandler(Object response, Callable action)
+  public DialogRunnerI setResponseHandler(Object response, Runnable action)
   {
     callbacks.put(response, action);
     return this;
@@ -644,12 +735,12 @@ public class JalviewFileChooser extends JFileChooser
     {
       return;
     }
-    Callable action = callbacks.get(response);
+    Runnable action = callbacks.get(response);
     if (action != null)
     {
       try
       {
-        action.call();
+        action.run();
       } catch (Exception e)
       {
         e.printStackTrace();
index 10dc9ea..5e9a242 100755 (executable)
  */
 package jalview.io;
 
-import java.util.Locale;
-
 import java.io.File;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
+import java.util.Locale;
 import java.util.Map;
 import java.util.StringTokenizer;
 
@@ -175,7 +174,7 @@ public class JalviewFileFilter extends FileFilter
 
           while (extensions.hasNext())
           {
-            fullDescription += (", " + extensions.next());
+            fullDescription += (", ." + extensions.next());
           }
         }
 
index a9fc7ed..5996781 100755 (executable)
@@ -169,7 +169,7 @@ public class JalviewFileView extends FileView
         }
         else
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "JalviewFileView.createImageIcon: Couldn't find file: "
                           + filePath);
         }
index 158feb9..0a0520a 100755 (executable)
@@ -136,7 +136,7 @@ public class MSFfile extends AlignFile
       }
     } catch (IOException e)
     {
-      System.err.println("Exception parsing MSFFile " + e);
+      jalview.bin.Console.errPrintln("Exception parsing MSFFile " + e);
       e.printStackTrace();
     }
 
@@ -169,7 +169,7 @@ public class MSFfile extends AlignFile
       }
       else
       {
-        System.err.println("MSFFile Parser: Can't find sequence for "
+        jalview.bin.Console.errPrintln("MSFFile Parser: Can't find sequence for "
                 + headers.get(i));
       }
     }
@@ -200,7 +200,7 @@ public class MSFfile extends AlignFile
         }
       } catch (Exception e)
       {
-        System.err.println("Exception during MSF Checksum calculation");
+        jalview.bin.Console.errPrintln("Exception during MSF Checksum calculation");
         e.printStackTrace();
       }
     }
index 269ffb3..38ee9ca 100755 (executable)
 // TODO: Extended SequenceNodeI to hold parsed NHX strings
 package jalview.io;
 
-import java.util.Locale;
-
-import jalview.datamodel.BinaryNode;
-import jalview.datamodel.SequenceNode;
-import jalview.util.MessageManager;
-
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.util.Locale;
 import java.util.StringTokenizer;
 
 import com.stevesoft.pat.Regex;
 
+import jalview.bin.Jalview;
+import jalview.datamodel.BinaryNode;
+import jalview.datamodel.SequenceNode;
+import jalview.util.MessageManager;
+
 /**
  * Parse a new hanpshire style tree Caveats: NHX files are NOT supported and the
  * tree distances and topology are unreliable when they are parsed. TODO: on
@@ -394,7 +394,7 @@ public class NewickFile extends FileParse
           // node string contains Comment or structured/extended NH format info
           /*
            * if ((fcp-cp>1 && nf.substring(cp,fcp).trim().length()>1)) { // will
-           * process in remains System.err.println("skipped text:
+           * process in remains jalview.bin.Console.errPrintln("skipped text:
            * '"+nf.substring(cp,fcp)+"'"); }
            */
           // verify termination.
@@ -488,7 +488,8 @@ public class NewickFile extends FileParse
         {
           try
           {
-            distance = (Double.valueOf(ndist.stringMatched(1))).floatValue();
+            distance = (Double.valueOf(ndist.stringMatched(1)))
+                    .floatValue();
             HasDistances = true;
             nodehasdistance = true;
           } catch (Exception e)
@@ -664,7 +665,7 @@ public class NewickFile extends FileParse
             // more codes here.
           } catch (Exception e)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Couldn't parse code '" + code + "' = '" + value + "'");
             e.printStackTrace(System.err);
           }
@@ -877,20 +878,20 @@ public class NewickFile extends FileParse
       {
         if (root.isDummy())
         {
-          _print(tf,  root.right());
-          _print(tf,  root.left());
+          _print(tf, root.right());
+          _print(tf, root.left());
         }
         else
         {
           tf.append("(");
-          _print(tf,  root.right());
+          _print(tf, root.right());
 
           if (root.left() != null)
           {
             tf.append(",");
           }
 
-          _print(tf,  root.left());
+          _print(tf, root.left());
           tf.append(")" + printRootField(root));
         }
       }
@@ -910,24 +911,24 @@ public class NewickFile extends FileParse
       {
         if (c.isDummy())
         {
-          _print(tf,  c.left());
+          _print(tf, c.left());
           if (c.left() != null)
           {
             tf.append(",");
           }
-          _print(tf,  c.right());
+          _print(tf, c.right());
         }
         else
         {
           tf.append("(");
-          _print(tf,  c.right());
+          _print(tf, c.right());
 
           if (c.left() != null)
           {
             tf.append(",");
           }
 
-          _print(tf,  c.left());
+          _print(tf, c.left());
           tf.append(")" + printNodeField(c));
         }
       }
@@ -945,9 +946,8 @@ public class NewickFile extends FileParse
     {
       if (args == null || args.length != 1)
       {
-        System.err.println(
-                "Takes one argument - file name of a newick tree file.");
-        System.exit(0);
+        Jalview.exit(
+                "Takes one argument - file name of a newick tree file.", 0);
       }
 
       File fn = new File(args[0]);
@@ -962,31 +962,31 @@ public class NewickFile extends FileParse
       }
 
       treefile.close();
-      System.out.println("Read file :\n");
+      jalview.bin.Console.outPrintln("Read file :\n");
 
       NewickFile trf = new NewickFile(args[0], DataSourceType.FILE);
       trf.parse();
-      System.out.println("Original file :\n");
+      jalview.bin.Console.outPrintln("Original file :\n");
 
       Regex nonl = new Regex("\n+", "");
-      System.out.println(nonl.replaceAll(newickfile.toString()) + "\n");
-
-      System.out.println("Parsed file.\n");
-      System.out.println("Default output type for original input.\n");
-      System.out.println(trf.print());
-      System.out.println("Without bootstraps.\n");
-      System.out.println(trf.print(false));
-      System.out.println("Without distances.\n");
-      System.out.println(trf.print(true, false));
-      System.out.println("Without bootstraps but with distanecs.\n");
-      System.out.println(trf.print(false, true));
-      System.out.println("Without bootstraps or distanecs.\n");
-      System.out.println(trf.print(false, false));
-      System.out.println("With bootstraps and with distances.\n");
-      System.out.println(trf.print(true, true));
+      jalview.bin.Console.outPrintln(nonl.replaceAll(newickfile.toString()) + "\n");
+
+      jalview.bin.Console.outPrintln("Parsed file.\n");
+      jalview.bin.Console.outPrintln("Default output type for original input.\n");
+      jalview.bin.Console.outPrintln(trf.print());
+      jalview.bin.Console.outPrintln("Without bootstraps.\n");
+      jalview.bin.Console.outPrintln(trf.print(false));
+      jalview.bin.Console.outPrintln("Without distances.\n");
+      jalview.bin.Console.outPrintln(trf.print(true, false));
+      jalview.bin.Console.outPrintln("Without bootstraps but with distanecs.\n");
+      jalview.bin.Console.outPrintln(trf.print(false, true));
+      jalview.bin.Console.outPrintln("Without bootstraps or distanecs.\n");
+      jalview.bin.Console.outPrintln(trf.print(false, false));
+      jalview.bin.Console.outPrintln("With bootstraps and with distances.\n");
+      jalview.bin.Console.outPrintln(trf.print(true, true));
     } catch (java.io.IOException e)
     {
-      System.err.println("Exception\n" + e);
+      jalview.bin.Console.errPrintln("Exception\n" + e);
       e.printStackTrace();
     }
   }
index 3df9804..164d7cc 100644 (file)
@@ -47,8 +47,8 @@ public class PContactPredictionFile extends AlignFile
 {
   protected static final String CONTACT_PREDICTION = "CONTACT_PREDICTION";
 
-  public PContactPredictionFile(String inFile, DataSourceType fileSourceType)
-          throws IOException
+  public PContactPredictionFile(String inFile,
+          DataSourceType fileSourceType) throws IOException
   {
     super(inFile, fileSourceType);
 
@@ -109,19 +109,23 @@ public class PContactPredictionFile extends AlignFile
 
         if (cm == null)
         {
-          cm = new ContactMatrix(true) {
+          cm = new ContactMatrix(true)
+          {
             @Override
             public String getType()
             {
               return CONTACT_PREDICTION;
             }
+
             @Override
             public int getHeight()
             {
               // TODO Auto-generated method stub
-              // return maximum contact height 
+              // return maximum contact height
               return 0;
-            }@Override
+            }
+
+            @Override
             public int getWidth()
             {
               // TODO Auto-generated method stub
@@ -140,15 +144,15 @@ public class PContactPredictionFile extends AlignFile
         } catch (Exception x)
         {
           error = true;
-          errormessage = "Couldn't process line: "
-                  + x.getLocalizedMessage() + "\n" + line;
+          errormessage = "Couldn't process line: " + x.getLocalizedMessage()
+                  + "\n" + line;
           return;
         }
         cm.addContact(left, right, (float) strength);
       }
     }
     // TODO COMPLETE
-    throw(new Error("Not Implemented yet."));
+    throw (new Error("Not Implemented yet."));
   }
 
   @Override
index d9ed516..adfc1cb 100755 (executable)
@@ -59,7 +59,7 @@ public class PIRFile extends AlignFile
     {
       if (line.length() == 0)
       {
-        // System.out.println("blank line");
+        // jalview.bin.Console.outPrintln("blank line");
         continue;
       }
       if (line.indexOf("C;") == 0 || line.indexOf("#") == 0)
index 6b9dc3f..57fae00 100755 (executable)
@@ -137,7 +137,7 @@ public class PfamFile extends AlignFile
       }
       else
       {
-        System.err.println("PFAM File reader: Can't find sequence for "
+        jalview.bin.Console.errPrintln("PFAM File reader: Can't find sequence for "
                 + headers.get(i));
       }
     }
index 12e87a6..7542884 100644 (file)
@@ -188,7 +188,7 @@ public class PhylipFile extends AlignFile
 
     } catch (IOException e)
     {
-      System.err.println("Exception parsing PHYLIP file " + e);
+      jalview.bin.Console.errPrintln("Exception parsing PHYLIP file " + e);
       e.printStackTrace(System.err);
       throw e;
     }
index 4d3ddc1..f8c384d 100644 (file)
@@ -160,8 +160,10 @@ public class RnamlFile extends AlignFile
         }
       }
       sqs[i] = new Sequence(id, seq, begin, end);
-
-      sqs[i].setEnd(sqs[i].findPosition(sqs[i].getLength()));
+      if (seq.length()!=(end-begin+1))
+      {
+        sqs[i].setEnd(sqs[i].findPosition(sqs[i].getLength()));
+      }
       String[] annot = new String[rna.length()];
       Annotation[] ann = new Annotation[rna.length()];
 
@@ -210,8 +212,8 @@ public class RnamlFile extends AlignFile
   // public static void main(String[] args) {
   // Pattern p= Pattern.compile("(.+)[.][^.]+");
   // Matcher m = p.matcher("toto.xml.zip");
-  // System.out.println(m.matches());
-  // System.out.println(m.group(1));
+  // jalview.bin.Console.outPrintln(m.matches());
+  // jalview.bin.Console.outPrintln(m.group(1));
   // }
   /**
    * make a friendly ID string.
index 95bd1cc..721cd47 100644 (file)
@@ -423,7 +423,7 @@ public class SequenceAnnotationReport
             }
           } catch (Exception x)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "problem when creating links from " + urlstring);
             x.printStackTrace();
           }
@@ -446,7 +446,7 @@ public class SequenceAnnotationReport
     UrlLink urlLink = new UrlLink(link);
     if (!urlLink.isValid())
     {
-      System.err.println(urlLink.getInvalidMessage());
+      jalview.bin.Console.errPrintln(urlLink.getInvalidMessage());
       return null;
     }
 
index ba6b2f3..d8b3215 100644 (file)
@@ -165,7 +165,7 @@ public class SimpleBlastFile extends AlignFile
               rstart = Long.parseLong(stindx);
             } catch (Exception e)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Couldn't parse '" + stindx + "' as start of row");
               // inAlignments = false;
               // warn for this line
@@ -175,7 +175,7 @@ public class SimpleBlastFile extends AlignFile
               rend = Long.parseLong(endindx);
             } catch (Exception e)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Couldn't parse '" + endindx + "' as end of row");
               // inAlignments = false;
 
index a3f7531..d674485 100644 (file)
@@ -147,19 +147,19 @@ public class StockholmFile extends AlignFile
               + umcp.getMessage() + ")";
       throw new IOException(umcp);
     }
-    // DEBUG System.out.println("this is the secondary scructure:"
+    // DEBUG jalview.bin.Console.outPrintln("this is the secondary scructure:"
     // +result.size());
     SequenceI[] seqs = new SequenceI[result.size()];
     String id = null;
     for (int i = 0; i < result.size(); i++)
     {
-      // DEBUG System.err.println("Processing i'th sequence in Stockholm file")
+      // DEBUG jalview.bin.Console.errPrintln("Processing i'th sequence in Stockholm file")
       RNA current = result.get(i);
 
       String seq = current.getSeq();
       String rna = current.getStructDBN(true);
-      // DEBUG System.out.println(seq);
-      // DEBUG System.err.println(rna);
+      // DEBUG jalview.bin.Console.outPrintln(seq);
+      // DEBUG jalview.bin.Console.errPrintln(rna);
       int begin = 0;
       int end = seq.length() - 1;
       id = safeName(getDataName());
@@ -218,8 +218,9 @@ public class StockholmFile extends AlignFile
     r = new Regex("# STOCKHOLM ([\\d\\.]+)");
     if (!r.search(nextLine()))
     {
-      throw new IOException(MessageManager
-                           .getString("exception.stockholm_invalid_format") +" ("+r+")");
+      throw new IOException(
+              MessageManager.getString("exception.stockholm_invalid_format")
+                      + " (" + r + ")");
     }
     else
     {
@@ -440,7 +441,7 @@ public class StockholmFile extends AlignFile
       }
       else if (!r.search(line))
       {
-        // System.err.println("Found sequence line: " + line);
+        // jalview.bin.Console.errPrintln("Found sequence line: " + line);
 
         // Split sequence in sequence and accession parts
         if (!x.search(line))
@@ -464,7 +465,7 @@ public class StockholmFile extends AlignFile
         String annType = r.stringMatched(1);
         String annContent = r.stringMatched(2);
 
-        // System.err.println("type:" + annType + " content: " + annContent);
+        // jalview.bin.Console.errPrintln("type:" + annType + " content: " + annContent);
 
         if (annType.equals("GF"))
         {
@@ -566,7 +567,7 @@ public class StockholmFile extends AlignFile
           else
           {
             // throw new IOException("Error parsing " + line);
-            System.err.println(">> missing annotation: " + line);
+            jalview.bin.Console.errPrintln(">> missing annotation: " + line);
           }
         }
         else if (annType.equals("GC"))
@@ -684,7 +685,7 @@ public class StockholmFile extends AlignFile
           // }
           else
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Warning - couldn't parse sequence annotation row line:\n"
                             + line);
             // throw new IOException("Error parsing " + line);
@@ -936,7 +937,7 @@ public class StockholmFile extends AlignFile
               annot.annotations.length);
       System.arraycopy(els, 0, anns, annot.annotations.length, els.length);
       annot.annotations = anns;
-      // System.out.println("else: ");
+      // jalview.bin.Console.outPrintln("else: ");
     }
     return annot;
   }
@@ -1048,9 +1049,18 @@ public class StockholmFile extends AlignFile
       }
     }
 
-    // output annotations
+    // output description and annotations
+
     while (i < slen && (seq = s[i]) != null)
     {
+      if (seq.getDescription() != null)
+      {
+        // out.append("#=GR ");
+        out.append(new Format("%-" + maxid + "s").form("#=GS "
+                + printId(seq, jvSuffix) + " DE " + seq.getDescription()));
+        out.append(newline);
+      }
+
       AlignmentAnnotation[] alAnot = seq.getAnnotation();
       if (alAnot != null)
       {
@@ -1260,7 +1270,7 @@ public class StockholmFile extends AlignFile
     {
       return (String) typeIds.get(id);
     }
-    System.err.println(
+    jalview.bin.Console.errPrintln(
             "Warning : Unknown Stockholm annotation type code " + id);
     return id;
   }
@@ -1282,7 +1292,7 @@ public class StockholmFile extends AlignFile
     {
       return key;
     }
-    System.err.println(
+    jalview.bin.Console.errPrintln(
             "Warning : Unknown Stockholm annotation type: " + type);
     return key;
   }
index f498c1e..df384a6 100644 (file)
@@ -23,6 +23,7 @@ package jalview.io;
 import java.awt.Color;
 import java.io.IOException;
 import java.lang.reflect.Constructor;
+import java.net.MalformedURLException;
 import java.util.List;
 import java.util.Vector;
 
@@ -36,6 +37,7 @@ import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.SequenceI;
+import jalview.ext.jmol.JmolParser;
 import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureImportSettings.TFType;
 import mc_view.PDBChain;
@@ -68,7 +70,7 @@ public abstract class StructureFile extends AlignFile
 
   private boolean pdbIdAvailable;
 
-  private StructureImportSettings.TFType temperatureFactorType = TFType.DEFAULT;
+  private TFType temperatureFactorType = TFType.DEFAULT;
 
   private String paeMatrix = null;
 
@@ -89,12 +91,12 @@ public abstract class StructureFile extends AlignFile
     return paeMatrix != null;
   }
 
-  public void setTemperatureFactorType(StructureImportSettings.TFType t)
+  public void setTemperatureFactorType(TFType t)
   {
     this.temperatureFactorType = t;
   }
 
-  public StructureImportSettings.TFType getTemperatureFactorType()
+  public TFType getTemperatureFactorType()
   {
     return temperatureFactorType;
   }
@@ -116,7 +118,7 @@ public abstract class StructureFile extends AlignFile
   }
 
   public StructureFile(Object inFile, DataSourceType sourceType,
-          StructureImportSettings.TFType tempfacType) throws IOException
+          TFType tempfacType) throws IOException
   {
     super(false, inFile, sourceType);
     this.setTemperatureFactorType(tempfacType);
@@ -125,7 +127,13 @@ public abstract class StructureFile extends AlignFile
 
   public StructureFile(FileParse fp) throws IOException
   {
-    super(fp);
+    this(fp, true);
+  }
+
+  public StructureFile(FileParse fp, boolean doXferSettings)
+          throws IOException
+  {
+    super(fp, doXferSettings);
   }
 
   public void addSettings(boolean addAlignmentAnnotations,
@@ -138,14 +146,17 @@ public abstract class StructureFile extends AlignFile
 
   public void xferSettings()
   {
-    this.visibleChainAnnotation = StructureImportSettings
-            .isVisibleChainAnnotation();
-    this.predictSecondaryStructure = StructureImportSettings
-            .isProcessSecondaryStructure();
-    this.externalSecondaryStructure = StructureImportSettings
-            .isExternalSecondaryStructure();
-    this.temperatureFactorType = StructureImportSettings
-            .getTemperatureFactorType();
+    if (this.getDoXferSettings())
+    {
+      this.visibleChainAnnotation = StructureImportSettings
+              .isVisibleChainAnnotation();
+      this.predictSecondaryStructure = StructureImportSettings
+              .isProcessSecondaryStructure();
+      this.externalSecondaryStructure = StructureImportSettings
+              .isExternalSecondaryStructure();
+      this.temperatureFactorType = StructureImportSettings
+              .getTemperatureFactorType();
+    }
   }
 
   public StructureFile(boolean parseImmediately, Object dataObject,
@@ -231,7 +242,7 @@ public abstract class StructureFile extends AlignFile
   protected void processPdbFileWithAnnotate3d(List<SequenceI> rna)
           throws Exception
   {
-    // System.out.println("this is a PDB format and RNA sequence");
+    // jalview.bin.Console.outPrintln("this is a PDB format and RNA sequence");
     // note: we use reflection here so that the applet can compile and run
     // without the HTTPClient bits and pieces needed for accessing Annotate3D
     // web service
@@ -325,7 +336,7 @@ public abstract class StructureFile extends AlignFile
         processPdbFileWithAnnotate3d(rnaSequences);
       } catch (Exception x)
       {
-        System.err.println("Exceptions when dealing with RNA in pdb file");
+        jalview.bin.Console.errPrintln("Exceptions when dealing with RNA in pdb file");
         x.printStackTrace();
 
       }
@@ -338,60 +349,43 @@ public abstract class StructureFile extends AlignFile
     {
       try
       {
-        processWithJmolParser(proteinSequences);
+        processWithJmolParser(proteinSequences, true);
       } catch (Exception x)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Exceptions from Jmol when processing data in pdb file");
         x.printStackTrace();
       }
     }
   }
 
-  @SuppressWarnings({ "unchecked", "rawtypes" })
-  private void processWithJmolParser(List<SequenceI> prot) throws Exception
+  private void processWithJmolParser(List<SequenceI> prot,
+          boolean doXferSettings) throws MalformedURLException, IOException
   {
-    try
-    {
+    FileParse fp = new FileParse(getDataName(), dataSourceType);
 
-      Class cl = Class.forName("jalview.ext.jmol.JmolParser");
-      if (cl != null)
+    StructureImportSettings.setShowSeqFeatures(false);
+    StructureImportSettings.setVisibleChainAnnotation(false);
+    StructureImportSettings
+            .setProcessSecondaryStructure(predictSecondaryStructure);
+    StructureImportSettings
+            .setExternalSecondaryStructure(externalSecondaryStructure);
+    StructureImportSettings.setTemperatureFactorType(temperatureFactorType);
+    JmolParser jmf = new JmolParser(fp, doXferSettings);
+    AlignmentI al = new Alignment((SequenceI[]) jmf.getSeqsAsArray());
+    jmf.addAnnotations(al);
+    for (SequenceI sq : al.getSequences())
+    {
+      if (sq.getDatasetSequence() != null)
       {
-        final Constructor constructor = cl
-                .getConstructor(new Class[]
-                { FileParse.class });
-        final Object[] args = new Object[] {
-            new FileParse(getDataName(), dataSourceType) };
-
-        StructureImportSettings.setShowSeqFeatures(false);
-        StructureImportSettings.setVisibleChainAnnotation(false);
-        StructureImportSettings
-                .setProcessSecondaryStructure(predictSecondaryStructure);
-        StructureImportSettings
-                .setExternalSecondaryStructure(externalSecondaryStructure);
-        StructureImportSettings
-                .setTemperatureFactorType(temperatureFactorType);
-        Object jmf = constructor.newInstance(args);
-        AlignmentI al = new Alignment((SequenceI[]) cl
-                .getMethod("getSeqsAsArray", new Class[] {}).invoke(jmf));
-        cl.getMethod("addAnnotations", new Class[] { AlignmentI.class })
-                .invoke(jmf, al);
-        for (SequenceI sq : al.getSequences())
-        {
-          if (sq.getDatasetSequence() != null)
-          {
-            sq.getDatasetSequence().getAllPDBEntries().clear();
-          }
-          else
-          {
-            sq.getAllPDBEntries().clear();
-          }
-        }
-        replaceAndUpdateChains(prot, al, AlignSeq.PEP, false);
+        sq.getDatasetSequence().getAllPDBEntries().clear();
+      }
+      else
+      {
+        sq.getAllPDBEntries().clear();
       }
-    } catch (ClassNotFoundException q)
-    {
     }
+    replaceAndUpdateChains(prot, al, AlignSeq.PEP, false);
     StructureImportSettings.setShowSeqFeatures(true);
   }
 
index 7e963d5..52751e9 100644 (file)
@@ -601,7 +601,7 @@ public class TCoffeeScoreFile extends AlignFile
           annotations[j] = null;
           if (val > 0)
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Warning: non-zero value for positional T-COFFEE score for gap at "
                             + j + " in sequence " + s.getName());
           }
index dd4b72c..c3776d3 100644 (file)
@@ -460,7 +460,7 @@ public class VamsasAppDatastore
           {
             // removeValignmentSequences(alignment, docseqs);
             docseqs.removeAllElements();
-            System.out.println(
+            jalview.bin.Console.outPrintln(
                     "Sequence deletion from alignment is not implemented.");
 
           }
@@ -488,11 +488,11 @@ public class VamsasAppDatastore
           }
           if (alismod)
           {
-            System.out.println("update alignment in document.");
+            jalview.bin.Console.outPrintln("update alignment in document.");
           }
           else
           {
-            System.out.println("alignment in document left unchanged.");
+            jalview.bin.Console.outPrintln("alignment in document left unchanged.");
           }
         }
         else
@@ -500,7 +500,7 @@ public class VamsasAppDatastore
           // unbind alignment from view.
           // create new binding and new alignment.
           // mark trail on new alignment as being derived from old ?
-          System.out.println(
+          jalview.bin.Console.outPrintln(
                   "update edited alignment to new alignment in document.");
         }
       }
@@ -1115,12 +1115,12 @@ public class VamsasAppDatastore
       // METHODS)
       {
         // verify existing alignment sequence annotation is up to date
-        System.out.println("update dataset sequence annotation.");
+        jalview.bin.Console.outPrintln("update dataset sequence annotation.");
       }
       else
       {
         // verify existing alignment sequence annotation is up to date
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "make new alignment dataset sequence annotation if modification has happened.");
       }
     }
@@ -1184,12 +1184,12 @@ public class VamsasAppDatastore
       // METHODS)
       {
         // verify existing alignment sequence annotation is up to date
-        System.out.println("update alignment sequence annotation.");
+        jalview.bin.Console.outPrintln("update alignment sequence annotation.");
       }
       else
       {
         // verify existing alignment sequence annotation is up to date
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "make new alignment sequence annotation if modification has happened.");
       }
     }
index 63b78b2..c7c90f4 100755 (executable)
@@ -84,7 +84,7 @@ public class WSWUBlastClient
     for (int i = 0; i < ids.size(); i++)
     {
       Sequence sequence = (Sequence) ids.get(i);
-      System.out.println(sequence.getName());
+      jalview.bin.Console.outPrintln(sequence.getName());
 
       BlastThread thread = new BlastThread(sequence);
       thread.start();
@@ -249,7 +249,7 @@ public class WSWUBlastClient
 
     BlastThread(Sequence sequence)
     {
-      System.out.println("blasting for: " + sequence.getName());
+      jalview.bin.Console.outPrintln("blasting for: " + sequence.getName());
       this.sequence = sequence;
     }
 
@@ -276,7 +276,7 @@ public class WSWUBlastClient
           else
           {
             Thread.sleep(10000);
-            System.out.println("WSWuBlastClient: I'm alive "
+            jalview.bin.Console.outPrintln("WSWuBlastClient: I'm alive "
                     + sequence.getName() + " " + jobid); // log.debug
           }
         } catch (Exception ex)
@@ -315,7 +315,7 @@ public class WSWUBlastClient
       {
         jobComplete = true;
         jobsRunning--;
-        System.err.println("WSWUBlastClient error:\n" + exp.toString());
+        jalview.bin.Console.errPrintln("WSWUBlastClient error:\n" + exp.toString());
         exp.printStackTrace();
       }
     }
index eedf09a..e4e2d99 100644 (file)
@@ -204,7 +204,7 @@ public class JvCacheableInputBox<E>
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        // System.out.println(">>>>> Clear cache items");
+        // jalview.bin.Console.outPrintln(">>>>> Clear cache items");
         setSelectedItem("");
         appCache.deleteCacheItems(cacheKey);
         updateCache();
diff --git a/src/jalview/io/exceptions/ImageOutputException.java b/src/jalview/io/exceptions/ImageOutputException.java
new file mode 100644 (file)
index 0000000..bf06494
--- /dev/null
@@ -0,0 +1,36 @@
+package jalview.io.exceptions;
+
+/**
+ * wrapper for passing error messages and exceptions back to UI when image io goes wrong
+ * @author jprocter
+ *
+ */
+public class ImageOutputException extends Exception
+{
+
+  public ImageOutputException()
+  {
+  }
+
+  public ImageOutputException(String message)
+  {
+    super(message);
+  }
+
+  public ImageOutputException(Throwable cause)
+  {
+    super(cause);
+  }
+
+  public ImageOutputException(String message, Throwable cause)
+  {
+    super(message, cause);
+  }
+
+  public ImageOutputException(String message, Throwable cause,
+          boolean enableSuppression, boolean writableStackTrace)
+  {
+    super(message, cause, enableSuppression, writableStackTrace);
+  }
+
+}
index 9ce4cc6..77b641a 100644 (file)
@@ -90,7 +90,7 @@ public class ExonerateHelper extends Gff2Helper
               relaxedIdMatching);
     } catch (IOException ivfe)
     {
-      System.err.println(ivfe);
+      jalview.bin.Console.errPrintln(ivfe);
     }
 
     /*
@@ -200,7 +200,7 @@ public class ExonerateHelper extends Gff2Helper
     }
     else if (!"+".equals(strand))
     {
-      System.err.println("Strand must be specified for alignment");
+      jalview.bin.Console.errPrintln("Strand must be specified for alignment");
       return;
     }
 
@@ -239,7 +239,7 @@ public class ExonerateHelper extends Gff2Helper
     String[] tokens = region.split(" ");
     if (tokens.length != 3)
     {
-      System.err.println("Malformed Align descriptor: " + region);
+      jalview.bin.Console.errPrintln("Malformed Align descriptor: " + region);
       return null;
     }
 
@@ -257,7 +257,7 @@ public class ExonerateHelper extends Gff2Helper
       alignCount = Integer.parseInt(tokens[2]);
     } catch (NumberFormatException nfe)
     {
-      System.err.println(nfe.toString());
+      jalview.bin.Console.errPrintln(nfe.toString());
       return null;
     }
 
@@ -351,7 +351,7 @@ public class ExonerateHelper extends Gff2Helper
         return true;
       }
     }
-    System.err.println("Sorry, I don't handle exonerate model " + model);
+    jalview.bin.Console.errPrintln("Sorry, I don't handle exonerate model " + model);
     return false;
   }
 
index 1ef8848..646900d 100644 (file)
@@ -154,7 +154,7 @@ public class Gff3Helper extends GffHelperBase
      */
     if ("-".equals(strand))
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Skipping mapping from reverse complement as not yet supported");
       return null;
     }
@@ -162,7 +162,7 @@ public class Gff3Helper extends GffHelperBase
     List<String> targets = attributes.get(TARGET);
     if (targets == null)
     {
-      System.err.println("'Target' missing in GFF");
+      jalview.bin.Console.errPrintln("'Target' missing in GFF");
       return null;
     }
 
@@ -178,7 +178,7 @@ public class Gff3Helper extends GffHelperBase
       String[] tokens = target.split(" ");
       if (tokens.length < 3)
       {
-        System.err.println("Incomplete Target: " + target);
+        jalview.bin.Console.errPrintln("Incomplete Target: " + target);
         continue;
       }
 
@@ -225,7 +225,7 @@ public class Gff3Helper extends GffHelperBase
         }
       } catch (NumberFormatException nfe)
       {
-        System.err.println("Invalid start or end in Target " + target);
+        jalview.bin.Console.errPrintln("Invalid start or end in Target " + target);
       }
     }
 
index 22386d4..dccfd27 100644 (file)
@@ -114,7 +114,7 @@ public abstract class GffHelperBase implements GffHelperI
      */
     if (!trimMapping(from, to, fromRatio, toRatio))
     {
-      System.err.println("Ignoring mapping from " + Arrays.toString(from)
+      jalview.bin.Console.errPrintln("Ignoring mapping from " + Arrays.toString(from)
               + " to " + Arrays.toString(to) + " as counts don't match!");
       return null;
     }
@@ -166,7 +166,7 @@ public abstract class GffHelperBase implements GffHelperI
       {
         from[1] += fromOverlap / toRatio;
       }
-      System.err.println(Arrays.toString(from));
+      jalview.bin.Console.errPrintln(Arrays.toString(from));
       return true;
     }
     else if (fromOverlap < 0 && fromOverlap % fromRatio == 0)
@@ -185,7 +185,7 @@ public abstract class GffHelperBase implements GffHelperI
       {
         to[1] += fromOverlap / fromRatio;
       }
-      System.err.println(Arrays.toString(to));
+      jalview.bin.Console.errPrintln(Arrays.toString(to));
       return true;
     }
 
@@ -444,7 +444,7 @@ public abstract class GffHelperBase implements GffHelperI
       return sf;
     } catch (NumberFormatException nfe)
     {
-      System.err.println("Invalid number in gff: " + nfe.getMessage());
+      jalview.bin.Console.errPrintln("Invalid number in gff: " + nfe.getMessage());
       return null;
     }
   }
@@ -504,7 +504,7 @@ public abstract class GffHelperBase implements GffHelperI
 
     if (!valid)
     {
-      System.err.println(INVALID_GFF_ATTRIBUTE_FORMAT + s);
+      jalview.bin.Console.errPrintln(INVALID_GFF_ATTRIBUTE_FORMAT + s);
       return map;
     }
 
@@ -526,7 +526,7 @@ public abstract class GffHelperBase implements GffHelperI
       theKey = theKey.trim();
       if (theKey.isEmpty())
       {
-        System.err.println(INVALID_GFF_ATTRIBUTE_FORMAT + s);
+        jalview.bin.Console.errPrintln(INVALID_GFF_ATTRIBUTE_FORMAT + s);
         map.clear();
         return map;
       }
index 7d354e0..1e77f78 100644 (file)
@@ -215,7 +215,7 @@ public class SequenceOntologyLite implements SequenceOntologyI
       {
         // suppress logging here as it reports Uniprot sequence features
         // (which do not use SO terms) when auto-configuring feature colours
-        // System.out.println("SO term " + term
+        // jalview.bin.Console.outPrintln("SO term " + term
         // + " not known - add to model if needed in "
         // + getClass().getName());
         termsNotFound.add(term);
index 9f84c16..5248a16 100644 (file)
@@ -291,7 +291,7 @@ public class JalviewDataset
     AlignmentSet last = getLastAlignmentSet();
     if (last != null)
     {
-      System.err.println("Deuniquifying last alignment set.");
+      jalview.bin.Console.errPrintln("Deuniquifying last alignment set.");
       last.deuniquifyAlignment();
     }
     al.add(new AlignmentSet(newal));
index 37dd66b..3ce774e 100644 (file)
@@ -246,7 +246,7 @@ public class ParsePackedSet
           fp = new FileParse(file, AppletFormatAdapter.checkProtocol(file));
         } catch (Exception e)
         {
-          System.err.println("Couldn't handle datasource of type " + jtype
+          jalview.bin.Console.errPrintln("Couldn't handle datasource of type " + jtype
                   + " using URI " + file);
           e.printStackTrace();
           return;
@@ -255,7 +255,7 @@ public class ParsePackedSet
       }
       else
       {
-        System.out.println("Couldn't parse source type token '"
+        jalview.bin.Console.outPrintln("Couldn't parse source type token '"
                 + type.toUpperCase(Locale.ROOT) + "'");
       }
     }
@@ -269,7 +269,7 @@ public class ParsePackedSet
       System.out.print("\n");
 
     }
-    System.out.println("Now trying to parse set:");
+    jalview.bin.Console.outPrintln("Now trying to parse set:");
     JalviewDataset context;
     Object[] newdm;
     ParsePackedSet pps;
@@ -279,7 +279,7 @@ public class ParsePackedSet
               .getAlignment(context = new JalviewDataset(), dp);
     } catch (Exception e)
     {
-      System.out.println("Test failed for these arguments.\n");
+      jalview.bin.Console.outPrintln("Test failed for these arguments.\n");
       e.printStackTrace(System.out);
       return;
     }
@@ -287,7 +287,7 @@ public class ParsePackedSet
     {
       for (Object o : newdm)
       {
-        System.out.println("Will need to create an " + o.getClass());
+        jalview.bin.Console.outPrintln("Will need to create an " + o.getClass());
       }
 
       // now test uniquify/deuniquify stuff
@@ -300,7 +300,7 @@ public class ParsePackedSet
     {
       if (context.getLastAlignmentSet().isModified())
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Initial alignment set was modified and any associated views should be updated.");
       }
     }
index a33390f..3183bf6 100644 (file)
@@ -139,7 +139,7 @@ public class Sequencemapping extends Rangetype
 
   private void conflict(Mapping mjvmapping, SequenceMapping sequenceMapping)
   {
-    System.err.println("Conflict in update of sequenceMapping "
+    jalview.bin.Console.errPrintln("Conflict in update of sequenceMapping "
             + sequenceMapping.getVorbaId());
   }
 
index c0d1774..a6dd8b6 100644 (file)
@@ -358,7 +358,7 @@ public class Tree extends DatastoreItem
         }
         if (jvseq instanceof SequenceI)
         {
-          leaf.setElement(jvseq);
+          leaf.setElement((SequenceI) jvseq);
           leaf.setPlaceholder(false);
         }
         else
@@ -394,8 +394,7 @@ public class Tree extends DatastoreItem
       {
         if (!((jalview.datamodel.SequenceNode) tnode).isPlaceholder())
         {
-          Object assocseq = ((BinaryNode) tnode)
-                  .element();
+          Object assocseq = ((BinaryNode) tnode).element();
           if (assocseq instanceof SequenceI)
           {
             Vobject vobj = this.getjv2vObj(assocseq);
@@ -416,7 +415,7 @@ public class Tree extends DatastoreItem
             }
             else
             {
-              System.err.println("WARNING: Unassociated treeNode "
+              jalview.bin.Console.errPrintln("WARNING: Unassociated treeNode "
                       + tnode.element().toString() + " "
                       + ((tnode.getName() != null)
                               ? " label " + tnode.getName()
@@ -467,7 +466,7 @@ public class Tree extends DatastoreItem
       occurence = Integer.valueOf(oval).intValue();
     } catch (Exception e)
     {
-      System.err.println("Invalid nodespec '" + nodespec + "'");
+      jalview.bin.Console.errPrintln("Invalid nodespec '" + nodespec + "'");
       return null;
     }
     jalview.datamodel.BinaryNode bn = null;
index ea5b8e0..c3fbea8 100644 (file)
@@ -278,7 +278,7 @@ public class VCFLoader
       initialise(vcfFile);
     } catch (IOException e)
     {
-      System.err.println("Error opening VCF file: " + e.getMessage());
+      jalview.bin.Console.errPrintln("Error opening VCF file: " + e.getMessage());
     }
 
     // map of species!chromosome!fromAssembly!toAssembly to {fromRange, toRange}
@@ -398,7 +398,7 @@ public class VCFLoader
       }
     } catch (Throwable e)
     {
-      System.err.println("Error processing VCF: " + e.getMessage());
+      jalview.bin.Console.errPrintln("Error processing VCF: " + e.getMessage());
       e.printStackTrace();
       if (gui != null)
       {
@@ -678,7 +678,7 @@ public class VCFLoader
         patterns.add(Pattern.compile(token.toUpperCase(Locale.ROOT)));
       } catch (PatternSyntaxException e)
       {
-        System.err.println("Invalid pattern ignored: " + token);
+        jalview.bin.Console.errPrintln("Invalid pattern ignored: " + token);
       }
     }
     return patterns;
index 29f3fa9..c174696 100644 (file)
@@ -171,7 +171,7 @@ public class JSFunctionExec implements Runnable
           {
             if (jvlite.debug && dbgMsg != null)
             {
-              System.err.println(dbgMsg);
+              jalview.bin.Console.errPrintln(dbgMsg);
             }
             scriptObject.call(_listener, objects);
           }
@@ -182,7 +182,7 @@ public class JSFunctionExec implements Runnable
           {
             if (jvlite.debug)
             {
-              System.err.println(jex);
+              jalview.bin.Console.errPrintln(jex);
             }
             if (jex instanceof netscape.javascript.JSException
                     && jvlite.jsfallbackEnabled)
@@ -190,7 +190,7 @@ public class JSFunctionExec implements Runnable
               jsex[0] = jex;
               if (jvlite.debug)
               {
-                System.err.println("Falling back to javascript: url call");
+                jalview.bin.Console.errPrintln("Falling back to javascript: url call");
               }
               StringBuffer sb = new StringBuffer(
                       "javascript:" + _listener + "(");
@@ -213,7 +213,7 @@ public class JSFunctionExec implements Runnable
               sb.append(")");
               if (jvlite.debug)
               {
-                System.err.println(sb.toString());
+                jalview.bin.Console.errPrintln(sb.toString());
               }
               // alternate
               URL url = null;
index c2a963e..eda8741 100644 (file)
@@ -47,7 +47,7 @@ public class JsSelectionSender extends JSFunctionExec
   public void selection(SequenceGroup seqsel, ColumnSelection colsel,
           HiddenColumns hidden, SelectionSource source)
   {
-    // System.err.println("Testing selection event relay to
+    // jalview.bin.Console.errPrintln("Testing selection event relay to
     // jsfunction:"+_listener);
     try
     {
@@ -106,20 +106,20 @@ public class JsSelectionSender extends JSFunctionExec
         ;
 
       }
-      System.err.println("Relaying selection to jsfunction:" + _listener);
+      jalview.bin.Console.errPrintln("Relaying selection to jsfunction:" + _listener);
       executeJavascriptFunction(_listener,
               new Object[]
               { src, setid, jvlite.arrayToSeparatorList(seqs),
                   jvlite.arrayToSeparatorList(cols) });
     } catch (Exception ex)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Jalview Javascript exec error: Couldn't send selection message using function '"
                       + _listener + "'");
       ex.printStackTrace();
       if (ex instanceof netscape.javascript.JSException)
       {
-        System.err.println("Javascript Exception: "
+        jalview.bin.Console.errPrintln("Javascript Exception: "
                 + ((netscape.javascript.JSException) ex).getCause()
                         .toString());
       }
index 16b57a4..70a300c 100644 (file)
@@ -71,12 +71,12 @@ public class MouseOverListener extends JSFunctionExec
       } catch (Exception ex)
       {
 
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "JalviewLite javascript error: Couldn't send mouseOver with handler '"
                         + _listener + "'");
         if (ex instanceof netscape.javascript.JSException)
         {
-          System.err.println("Javascript Exception: "
+          jalview.bin.Console.errPrintln("Javascript Exception: "
                   + ((netscape.javascript.JSException) ex).getMessage());
         }
         ex.printStackTrace();
index e90b968..f0b3132 100644 (file)
@@ -156,7 +156,7 @@ public class MouseOverStructureListener extends JSFunctionExec
                     "" + (atom.getPdbResNum()), "" + atom.getAtomIndex() });
       } catch (Exception ex)
       {
-        System.err.println("Couldn't execute callback with " + _listenerfn
+        jalview.bin.Console.errPrintln("Couldn't execute callback with " + _listenerfn
                 + " for atomSpec: " + atom);
         ex.printStackTrace();
       }
@@ -172,7 +172,7 @@ public class MouseOverStructureListener extends JSFunctionExec
 
     if (JalviewLite.debug)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               this.getClass().getName() + " modelSet[0]: " + modelSet[0]);
       ssm.reportMapping();
     }
@@ -197,7 +197,7 @@ public class MouseOverStructureListener extends JSFunctionExec
         }
         // if (jvlite.debug)
         // {
-        // System.err.println("Mapped '" + modelSet[m] + "' to "
+        // jalview.bin.Console.errPrintln("Mapped '" + modelSet[m] + "' to "
         // + sequence[m].length + " sequences.");
         // }
       }
@@ -260,7 +260,7 @@ public class MouseOverStructureListener extends JSFunctionExec
           executeJavascriptFunction(true, _listenerfn, st);
         } catch (Exception ex)
         {
-          System.err.println("Couldn't execute callback with " + _listenerfn
+          jalview.bin.Console.errPrintln("Couldn't execute callback with " + _listenerfn
                   + " using args { " + st[0] + ", " + st[1] + ", " + st[2]
                   + "," + st[3] + "}"); // + ","+st[4]+"\n");
           ex.printStackTrace();
@@ -274,7 +274,7 @@ public class MouseOverStructureListener extends JSFunctionExec
        * executeJavascriptFunction( false, _listenerfn, st = new String[] {
        * "colourstruct", "" + ((jalview.appletgui.AlignmentPanel) source).av
        * .getViewId(), handle, "" }); } catch (Exception ex) {
-       * System.err.println("Couldn't execute callback with " + _listenerfn +
+       * jalview.bin.Console.errPrintln("Couldn't execute callback with " + _listenerfn +
        * " using args { " + st[0] + ", " + st[1] + ", " + st[2] + "," + st[3] +
        * "\n"); ex.printStackTrace();
        * 
index 8ae97b0..7daeb37 100755 (executable)
@@ -220,6 +220,7 @@ public class GAlignFrame extends JInternalFrame
   {
     try
     {
+      setFrameIcon(null);
 
       // for Web-page embedding using id=align-frame-div
       setName("jalview-alignment");
@@ -245,7 +246,7 @@ public class GAlignFrame extends JInternalFrame
       }
     } catch (Exception e)
     {
-      System.err.println(e.toString());
+      jalview.bin.Console.errPrintln(e.toString());
     }
 
     if (Platform.allowMnemonics()) // was "not mac and not JS"
@@ -263,6 +264,7 @@ public class GAlignFrame extends JInternalFrame
 
   private void jbInit() throws Exception
   {
+    setFrameIcon(null);
     initColourMenu();
 
     JMenuItem saveAs = new JMenuItem(
@@ -1080,7 +1082,7 @@ public class GAlignFrame extends JInternalFrame
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        createPNG(null);
+        createPNG_actionPerformed(e);
       }
     });
     createPNG.setActionCommand(
@@ -1112,7 +1114,7 @@ public class GAlignFrame extends JInternalFrame
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        createEPS(null);
+        createEPS_actionPerformed(e);
       }
     });
 
@@ -1122,7 +1124,7 @@ public class GAlignFrame extends JInternalFrame
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        createSVG(null);
+        createSVG_actionPerformed(e);
       }
     });
 
@@ -1974,6 +1976,24 @@ public class GAlignFrame extends JInternalFrame
     // selectMenu.add(listenToViewSelections);
   }
 
+  protected void createPNG_actionPerformed(ActionEvent object)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  protected void createEPS_actionPerformed(ActionEvent object)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
+  protected void createSVG_actionPerformed(ActionEvent object)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
   protected void copyHighlightedColumns_actionPerformed(
           ActionEvent actionEvent)
   {
@@ -2157,7 +2177,7 @@ public class GAlignFrame extends JInternalFrame
    * @param forAlignment
    *          update non-sequence-related annotations
    */
-  protected void setAnnotationsVisibility(boolean visible,
+  public void setAnnotationsVisibility(boolean visible,
           boolean forSequences, boolean forAlignment)
   {
 
@@ -2467,10 +2487,6 @@ public class GAlignFrame extends JInternalFrame
   {
   }
 
-  public void createPNG(java.io.File f)
-  {
-  }
-
   protected void font_actionPerformed(ActionEvent e)
   {
   }
@@ -2484,15 +2500,6 @@ public class GAlignFrame extends JInternalFrame
 
   }
 
-  public void createEPS(java.io.File f)
-  {
-  }
-
-  public void createSVG(java.io.File f)
-  {
-
-  }
-
   protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
   {
 
index 6594e2d..2f0c75e 100755 (executable)
@@ -76,7 +76,7 @@ public class GAlignmentPanel extends JPanel
 
   protected JPanel scalePanelHolder = newJPanel();
 
-  protected JPanel idPanelHolder = newJPanel();
+  public JPanel idPanelHolder = newJPanel();
 
   protected JPanel idSpaceFillerPanel1 = newJPanel();
 
index ad1c1cf..ef09b6a 100644 (file)
@@ -20,9 +20,6 @@
  */
 package jalview.jbgui;
 
-import jalview.gui.JvSwingUtils;
-import jalview.util.MessageManager;
-
 import java.awt.BorderLayout;
 import java.awt.Font;
 import java.awt.event.ActionEvent;
@@ -41,6 +38,9 @@ import javax.swing.JScrollPane;
 import javax.swing.text.EditorKit;
 import javax.swing.text.html.HTMLEditorKit;
 
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+
 /**
  * DOCUMENT ME!
  * 
@@ -103,6 +103,7 @@ public class GCutAndPasteHtmlTransfer extends JInternalFrame
    */
   private void jbInit() throws Exception
   {
+    setFrameIcon(null);
     scrollPane.setBorder(null);
     ok.setFont(JvSwingUtils.getLabelFont());
     ok.setText(MessageManager.getString("label.new_window"));
index b75dd8c..3cd52ae 100755 (executable)
  */
 package jalview.jbgui;
 
-import jalview.gui.JvSwingUtils;
-import jalview.util.MessageManager;
-
 import java.awt.BorderLayout;
 import java.awt.Font;
-import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.MouseEvent;
@@ -39,6 +35,9 @@ import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
 
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+
 /**
  * DOCUMENT ME!
  * 
@@ -98,6 +97,7 @@ public class GCutAndPasteTransfer extends JInternalFrame
    */
   private void jbInit() throws Exception
   {
+    setFrameIcon(null);
     scrollPane.setBorder(null);
     ok.setFont(JvSwingUtils.getLabelFont());
     ok.setText(MessageManager.getString("label.new_window"));
index b0079b4..124c7c7 100755 (executable)
@@ -152,7 +152,7 @@ public class GDesktop extends JFrame
       APQHandlers.setAPQHandlers((Desktop) this);
     } catch (Exception e)
     {
-      System.out.println("Cannot set APQHandlers");
+      jalview.bin.Console.outPrintln("Cannot set APQHandlers");
       // e.printStackTrace();
     } catch (Throwable t)
     {
@@ -193,7 +193,7 @@ public class GDesktop extends JFrame
           inputURLMenuItem_actionPerformed(null);
         } catch (FileFormatException e1)
         {
-          System.err.println("Error loading from URL: " + e1.getMessage());
+          jalview.bin.Console.errPrintln("Error loading from URL: " + e1.getMessage());
         }
       }
     });
@@ -521,7 +521,7 @@ public class GDesktop extends JFrame
    */
   protected void quit()
   {
-    // System.out.println("********** GDesktop.quit()");
+    // jalview.bin.Console.outPrintln("********** GDesktop.quit()");
   }
 
   /**
index a6498d2..cf7bc4e 100755 (executable)
@@ -20,9 +20,6 @@
  */
 package jalview.jbgui;
 
-import jalview.util.ImageMaker.TYPE;
-import jalview.util.MessageManager;
-
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.FlowLayout;
@@ -43,6 +40,9 @@ import javax.swing.JPanel;
 import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
 
+import jalview.util.ImageMaker.TYPE;
+import jalview.util.MessageManager;
+
 public class GPCAPanel extends JInternalFrame
 {
   private static final Font VERDANA_12 = new Font("Verdana", 0, 12);
@@ -88,6 +88,7 @@ public class GPCAPanel extends JInternalFrame
 
   private void jbInit() throws Exception
   {
+    setFrameIcon(null);
     setName("jalview-pca");
     this.getContentPane().setLayout(new BorderLayout());
     JPanel jPanel2 = new JPanel();
index 69c0f4d..03538ef 100755 (executable)
@@ -39,6 +39,7 @@ import java.awt.event.KeyListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.util.Arrays;
+import java.util.EnumSet;
 import java.util.List;
 
 import javax.swing.AbstractCellEditor;
@@ -1679,10 +1680,16 @@ public class GPreferences extends JPanel
      */
     structViewer.setFont(LABEL_FONT);
     structViewer.setBounds(new Rectangle(190, ypos, 120, height));
+    for (ViewerType v : EnumSet.allOf(ViewerType.class))
+    {
+      structViewer.addItem(v.name());
+    }
+    /*
     structViewer.addItem(ViewerType.JMOL.name());
     structViewer.addItem(ViewerType.CHIMERA.name());
     structViewer.addItem(ViewerType.CHIMERAX.name());
     structViewer.addItem(ViewerType.PYMOL.name());
+    */
     structViewer.addActionListener(new ActionListener()
     {
       @Override
index 5dc726f..663245f 100644 (file)
@@ -38,6 +38,7 @@ public class GRnaStructureViewer extends JInternalFrame
 
   private void jbInit() throws Exception
   {
+    setFrameIcon(null);
 
     setName("jalview-rnastructureviewer");
 
index 5e65047..4d531be 100644 (file)
@@ -20,8 +20,6 @@
  */
 package jalview.jbgui;
 
-import jalview.util.Platform;
-
 import java.awt.Component;
 import java.awt.MouseInfo;
 import java.awt.Point;
@@ -31,6 +29,8 @@ import javax.swing.JInternalFrame;
 import javax.swing.JSplitPane;
 import javax.swing.plaf.basic.BasicInternalFrameUI;
 
+import jalview.util.Platform;
+
 public class GSplitFrame extends JInternalFrame
 {
   protected static final int DIVIDER_SIZE = 5;
@@ -57,6 +57,7 @@ public class GSplitFrame extends JInternalFrame
    */
   public GSplitFrame(GAlignFrame top, GAlignFrame bottom)
   {
+    setFrameIcon(null);
     setName("jalview-splitframe");
     this.topFrame = top;
     this.bottomFrame = bottom;
index d317e97..5b04359 100644 (file)
@@ -106,6 +106,8 @@ public abstract class GStructureChooser extends JPanel
    */
   protected static final String VIEWS_LOCAL_PDB = "VIEWS_LOCAL_PDB";
 
+  protected JPanel actionsPanel;
+
   protected JPanel statusPanel = new JPanel();
 
   public JLabel statusBar = new JLabel();
@@ -121,6 +123,8 @@ public abstract class GStructureChooser extends JPanel
 
   protected StringBuilder errorWarning = new StringBuilder();
 
+  protected JButton btn_cancel;
+
   protected JButton btn_add;
 
   protected JButton btn_newView;
@@ -291,7 +295,7 @@ public abstract class GStructureChooser extends JPanel
       mainFrame.pack();
     } catch (Exception e)
     {
-      System.out.println(e); // for JavaScript TypeError
+      jalview.bin.Console.outPrintln(e); // for JavaScript TypeError
       e.printStackTrace();
     }
   }
@@ -414,8 +418,7 @@ public abstract class GStructureChooser extends JPanel
       }
     });
 
-    JButton btn_cancel = new JButton(
-            MessageManager.getString("action.cancel"));
+    btn_cancel = new JButton(MessageManager.getString("action.cancel"));
     btn_cancel.setFont(VERDANA_12);
     btn_cancel.addActionListener(new ActionListener()
     {
@@ -569,10 +572,8 @@ public abstract class GStructureChooser extends JPanel
     lbl_pdbFile.setFont(VERDANA_10);
 
     lbl_chooseTempFacType.setFont(VERDANA_12);
-    lbl_chooseTempFacType.setText(new StringBuilder()
-            .append(MessageManager.getString("label.choose_tempfac_type"))
-            .append(" ").append(MessageManager.getString("label.optional"))
-            .toString());
+    lbl_chooseTempFacType.setText(
+            MessageManager.getString("label.interpret_tempfac_as"));
 
     combo_tempFacAs.setFont(VERDANA_12);
     for (TFType t : TFType.values())
@@ -590,10 +591,8 @@ public abstract class GStructureChooser extends JPanel
     });
 
     btn_paeMatrixFile.setFont(VERDANA_12);
-    btn_paeMatrixFile.setText(new StringBuilder()
-            .append(MessageManager.getString("label.add_pae_matrix_file"))
-            .append(" ").append(MessageManager.getString("label.optional"))
-            .toString());
+    btn_paeMatrixFile
+            .setText(MessageManager.getString("label.add_pae_matrix_file"));
     btn_paeMatrixFile.addActionListener(new ActionListener()
     {
       @Override
@@ -685,7 +684,7 @@ public abstract class GStructureChooser extends JPanel
 
     targetView.setVisible(false);
 
-    JPanel actionsPanel = new JPanel(new MigLayout());
+    actionsPanel = new JPanel(new MigLayout());
     actionsPanel.add(targetView, "left");
     actionsPanel.add(btn_add, "wrap");
     actionsPanel.add(chk_superpose, "left");
@@ -727,15 +726,23 @@ public abstract class GStructureChooser extends JPanel
     gbc.insets = new Insets(0, 0, 18, 0);
     pnl_fileOptions.add(lbl_pdbFile, gbc);
     gbc.gridy++;
+
     gbc.insets = new Insets(0, 0, 2, 0);
+    pnl_fileOptions.add(new JLabel(
+            MessageManager.getString("label.structure_import_options")),
+            gbc);
+    gbc.gridy++;
+
+    gbc.insets = new Insets(0, 0, 6, 0);
     pnl_fileOptions.add(lbl_chooseTempFacType, gbc);
     gbc.gridy++;
     gbc.insets = new Insets(0, 0, 18, 0);
     pnl_fileOptions.add(combo_tempFacAs, gbc);
     gbc.gridy++;
-    gbc.insets = new Insets(0, 0, 2, 0);
+    gbc.insets = new Insets(0, 0, 6, 0);
     pnl_fileOptions.add(btn_paeMatrixFile, gbc);
     gbc.gridy++;
+    gbc.insets = new Insets(0, 0, 2, 0);
     gbc.weighty = 1.0;
     pnl_fileOptions.add(lbl_paeFile, gbc);
 
@@ -842,11 +849,11 @@ public abstract class GStructureChooser extends JPanel
 
   protected void closeAction(int preferredHeight)
   {
-    // System.out.println(">>>>>>>>>> closing internal frame!!!");
-    // System.out.println("width : " + mainFrame.getWidth());
-    // System.out.println("heigh : " + mainFrame.getHeight());
-    // System.out.println("x : " + mainFrame.getX());
-    // System.out.println("y : " + mainFrame.getY());
+    // jalview.bin.Console.outPrintln(">>>>>>>>>> closing internal frame!!!");
+    // jalview.bin.Console.outPrintln("width : " + mainFrame.getWidth());
+    // jalview.bin.Console.outPrintln("heigh : " + mainFrame.getHeight());
+    // jalview.bin.Console.outPrintln("x : " + mainFrame.getX());
+    // jalview.bin.Console.outPrintln("y : " + mainFrame.getY());
     tempUserPrefs.put("structureChooser.width", pnl_filter.getWidth());
     tempUserPrefs.put("structureChooser.height", preferredHeight);
     tempUserPrefs.put("structureChooser.x", mainFrame.getX());
@@ -1070,5 +1077,6 @@ public abstract class GStructureChooser extends JPanel
     lbl_chooseTempFacType.setEnabled(b);
     combo_tempFacAs.setEnabled(b);
     btn_paeMatrixFile.setEnabled(b);
+    lbl_paeFile.setEnabled(b);
   }
 }
index 4e13032..18e4c9f 100644 (file)
@@ -88,7 +88,7 @@ public abstract class GStructureViewer extends JInternalFrame
 
   private void jbInit() throws Exception
   {
-
+    setFrameIcon(null);
     setName("jalview-structureviewer");
 
     JMenuBar menuBar = new JMenuBar();
index d184e76..2a1b11f 100755 (executable)
@@ -20,9 +20,6 @@
  */
 package jalview.jbgui;
 
-import jalview.util.ImageMaker.TYPE;
-import jalview.util.MessageManager;
-
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.event.ActionEvent;
@@ -37,6 +34,9 @@ import javax.swing.JScrollPane;
 import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
 
+import jalview.util.ImageMaker.TYPE;
+import jalview.util.MessageManager;
+
 @SuppressWarnings("serial")
 public class GTreePanel extends JInternalFrame
 {
@@ -92,6 +92,7 @@ public class GTreePanel extends JInternalFrame
 
   private void jbInit() throws Exception
   {
+    setFrameIcon(null);
     setName("jalview-tree");
     this.getContentPane().setLayout(borderLayout1);
     this.setBackground(Color.white);
index 714b0de..554b997 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.log;
 
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -48,7 +49,7 @@ public abstract class JLogger implements JLoggerI
 
   public static boolean isLevel(String levelString)
   {
-    for (LogLevel l : LogLevel.values())
+    for (LogLevel l : EnumSet.allOf(LogLevel.class))
     {
       if (l.name().equals(levelString))
         return true;
@@ -137,13 +138,13 @@ public abstract class JLogger implements JLoggerI
     {
       String logLine = String.format("%s: %s", loglevel.toString(),
               message);
-      System.out.println(logLine);
+      jalview.bin.Console.outPrintln(logLine);
       if (t != null)
       {
         if (loglevel.compareTo(LogLevel.DEBUG) <= 0)
           t.printStackTrace(System.err);
         else
-          System.err.println(t.getMessage());
+          jalview.bin.Console.errPrintln(t.getMessage());
       }
       return false;
     }
index b22bf4e..ad91464 100755 (executable)
@@ -464,7 +464,7 @@ public class Matrix implements MatrixI
           }
           else
           {
-            // System.out.println("Iteration " + iter);
+            // jalview.bin.Console.outPrintln("Iteration " + iter);
           }
 
           g = (d[l] - d[l - 1]) / (2.0 * e[l - 1]);
@@ -728,7 +728,7 @@ public class Matrix implements MatrixI
           }
           else
           {
-            // System.out.println("Iteration " + iter);
+            // jalview.bin.Console.outPrintln("Iteration " + iter);
           }
 
           g = (d[l] - d[l - 1]) / (2.0 * e[l - 1]);
index f3bf436..ea67f48 100755 (executable)
@@ -137,7 +137,7 @@ public class RotatableMatrix
     Float floatValue = Float.valueOf(degrees);
     if (cachedRotations.get(axis).containsKey(floatValue))
     {
-      // System.out.println("getRotation from cache: " + (int) degrees);
+      // jalview.bin.Console.outPrintln("getRotation from cache: " + (int) degrees);
       return cachedRotations.get(axis).get(floatValue);
     }
 
index ddf2afd..af3b2c8 100644 (file)
@@ -26,7 +26,6 @@ import static jalview.math.RotatableMatrix.Axis.Z;
 
 import java.awt.Color;
 import java.awt.Font;
-import java.awt.FontMetrics;
 import java.awt.Rectangle;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
@@ -87,6 +86,7 @@ import jalview.api.analysis.SimilarityParamsI;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Console;
+import jalview.bin.Jalview;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
@@ -96,6 +96,7 @@ import jalview.datamodel.ContactMatrixI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.GeneLocus;
 import jalview.datamodel.GraphLine;
+import jalview.datamodel.GroupSet;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Point;
 import jalview.datamodel.RnaViewerModel;
@@ -152,6 +153,7 @@ import jalview.viewmodel.ViewportRanges;
 import jalview.viewmodel.seqfeatures.FeatureRendererModel;
 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
+import jalview.ws.datamodel.MappableContactMatrixI;
 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 import jalview.ws.jws2.Jws2Discoverer;
 import jalview.ws.jws2.dm.AAConSettings;
@@ -194,6 +196,7 @@ import jalview.xml.binding.jalview.JalviewModel.Viewport.HiddenColumns;
 import jalview.xml.binding.jalview.JalviewModel.Viewport.Overview;
 import jalview.xml.binding.jalview.JalviewUserColours;
 import jalview.xml.binding.jalview.JalviewUserColours.Colour;
+import jalview.xml.binding.jalview.MapListType;
 import jalview.xml.binding.jalview.MapListType.MapListFrom;
 import jalview.xml.binding.jalview.MapListType.MapListTo;
 import jalview.xml.binding.jalview.Mapping;
@@ -517,7 +520,7 @@ public class Jalview2XML
           }
         } catch (Exception x)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
                           + ref.getSref());
           x.printStackTrace();
@@ -531,29 +534,30 @@ public class Jalview2XML
     }
     if (unresolved > 0)
     {
-      System.err.println("Jalview Project Import: There were " + unresolved
+      jalview.bin.Console.errPrintln("Jalview Project Import: There were "
+              + unresolved
               + " forward references left unresolved on the stack.");
     }
     if (failedtoresolve > 0)
     {
-      System.err.println("SERIOUS! " + failedtoresolve
+      jalview.bin.Console.errPrintln("SERIOUS! " + failedtoresolve
               + " resolvable forward references failed to resolve.");
     }
     if (incompleteSeqs != null && incompleteSeqs.size() > 0)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Jalview Project Import: There are " + incompleteSeqs.size()
                       + " sequences which may have incomplete metadata.");
       if (incompleteSeqs.size() < 10)
       {
         for (SequenceI s : incompleteSeqs.values())
         {
-          System.err.println(s.toString());
+          jalview.bin.Console.errPrintln(s.toString());
         }
       }
       else
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Too many to report. Skipping output of incomplete sequences.");
       }
     }
@@ -933,7 +937,7 @@ public class Jalview2XML
       object.setCreationDate(now);
     } catch (DatatypeConfigurationException e)
     {
-      System.err.println("error writing date: " + e.toString());
+      jalview.bin.Console.errPrintln("error writing date: " + e.toString());
     }
     object.setVersion(Cache.getDefault("VERSION", "Development Build"));
 
@@ -1000,14 +1004,14 @@ public class Jalview2XML
           // HAPPEN! (PF00072.15.stk does this)
           // JBPNote: Uncomment to debug writing out of files that do not read
           // back in due to ArrayOutOfBoundExceptions.
-          // System.err.println("vamsasSeq backref: "+id+"");
-          // System.err.println(jds.getName()+"
+          // jalview.bin.Console.errPrintln("vamsasSeq backref: "+id+"");
+          // jalview.bin.Console.errPrintln(jds.getName()+"
           // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
-          // System.err.println("Hashcode: "+seqHash(jds));
+          // jalview.bin.Console.errPrintln("Hashcode: "+seqHash(jds));
           // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
-          // System.err.println(rsq.getName()+"
+          // jalview.bin.Console.errPrintln(rsq.getName()+"
           // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
-          // System.err.println("Hashcode: "+seqHash(rsq));
+          // jalview.bin.Console.errPrintln("Hashcode: "+seqHash(rsq));
         }
         else
         {
@@ -1136,38 +1140,55 @@ public class Jalview2XML
            * only view *should* be coped with sensibly.
            */
           // This must have been loaded, is it still visible?
-          JInternalFrame[] frames = Desktop.desktop.getAllFrames();
-          String matchedFile = null;
-          for (int f = frames.length - 1; f > -1; f--)
+          List<JalviewStructureDisplayI> viewFrames = new ArrayList<>();
+          if (Desktop.desktop != null)
           {
-            if (frames[f] instanceof StructureViewerBase)
+            JInternalFrame[] jifs = Desktop.desktop.getAllFrames();
+            if (jifs != null)
             {
-              StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
-              matchedFile = saveStructureViewer(ap, jds, pdb, entry,
-                      viewIds, matchedFile, viewFrame);
-              /*
-               * Only store each structure viewer's state once in the project
-               * jar. First time through only (storeDS==false)
-               */
-              String viewId = viewFrame.getViewId();
-              String viewerType = viewFrame.getViewerType().toString();
-              if (!storeDS && !viewIds.contains(viewId))
+              for (JInternalFrame jif : jifs)
               {
-                viewIds.add(viewId);
-                File viewerState = viewFrame.saveSession();
-                if (viewerState != null)
-                {
-                  copyFileToJar(jout, viewerState.getPath(),
-                          getViewerJarEntryName(viewId), viewerType);
-                }
-                else
+                if (jif instanceof JalviewStructureDisplayI)
                 {
-                  Console.error(
-                          "Failed to save viewer state for " + viewerType);
+                  viewFrames.add((JalviewStructureDisplayI) jif);
                 }
               }
             }
           }
+          else if (Jalview.isHeadlessMode()
+                  && Jalview.getInstance().getCommands() != null)
+          {
+            viewFrames.addAll(
+                    StructureViewerBase.getAllStructureViewerBases());
+          }
+
+          String matchedFile = null;
+          for (JalviewStructureDisplayI viewFrame : viewFrames)
+          {
+            matchedFile = saveStructureViewer(ap, jds, pdb, entry, viewIds,
+                    matchedFile, viewFrame);
+            /*
+             * Only store each structure viewer's state once in the project
+             * jar. First time through only (storeDS==false)
+             */
+            String viewId = viewFrame.getViewId();
+            String viewerType = viewFrame.getViewerType().toString();
+            if (!storeDS && !viewIds.contains(viewId))
+            {
+              viewIds.add(viewId);
+              File viewerState = viewFrame.saveSession();
+              if (viewerState != null)
+              {
+                copyFileToJar(jout, viewerState.getPath(),
+                        getViewerJarEntryName(viewId), viewerType);
+              }
+              else
+              {
+                Console.error(
+                        "Failed to save viewer state for " + viewerType);
+              }
+            }
+          }
 
           if (matchedFile != null || entry.getFile() != null)
           {
@@ -1523,7 +1544,7 @@ public class Jalview2XML
                 ov.getCanvas().getResidueColour().getRGB());
         overview.setHiddenColour(ov.getCanvas().getHiddenColour().getRGB());
         view.setOverview(overview);
-      } 
+      }
       if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
       {
         view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
@@ -1760,7 +1781,7 @@ public class Jalview2XML
       try
       {
         fileName = fileName.replace('\\', '/');
-        System.out.println("Writing jar entry " + fileName);
+        jalview.bin.Console.outPrintln("Writing jar entry " + fileName);
         JarEntry entry = new JarEntry(fileName);
         jout.putNextEntry(entry);
         PrintWriter pout = new PrintWriter(
@@ -1781,7 +1802,7 @@ public class Jalview2XML
       } catch (Exception ex)
       {
         // TODO: raise error in GUI if marshalling failed.
-        System.err.println("Error writing Jalview project");
+        jalview.bin.Console.errPrintln("Error writing Jalview project");
         ex.printStackTrace();
       }
     }
@@ -2095,7 +2116,7 @@ public class Jalview2XML
       File file = new File(infilePath);
       if (file.exists() && jout != null)
       {
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "Writing jar entry " + jarEntryName + " (" + msg + ")");
         jout.putNextEntry(new JarEntry(jarEntryName));
         copyAll(is, jout);
@@ -2144,7 +2165,7 @@ public class Jalview2XML
    */
   protected String saveStructureViewer(AlignmentPanel ap, SequenceI jds,
           Pdbids pdb, PDBEntry entry, List<String> viewIds,
-          String matchedFile, StructureViewerBase viewFrame)
+          String matchedFile, JalviewStructureDisplayI viewFrame)
   {
     final AAStructureBindingModel bindingModel = viewFrame.getBinding();
 
@@ -2189,7 +2210,7 @@ public class Jalview2XML
         {
           StructureState state = new StructureState();
           state.setVisible(true);
-          state.setXpos(viewFrame.getX());
+          state.setXpos(viewFrame.getY());
           state.setYpos(viewFrame.getY());
           state.setWidth(viewFrame.getWidth());
           state.setHeight(viewFrame.getHeight());
@@ -2304,25 +2325,26 @@ public class Jalview2XML
           line.setColour(annotation.getThreshold().colour.getRGB());
           an.setThresholdLine(line);
         }
-        if (annotation.graph==AlignmentAnnotation.CONTACT_MAP)
+        if (annotation.graph == AlignmentAnnotation.CONTACT_MAP)
         {
-          if (annotation.sequenceRef.getContactMaps()!=null)
+          if (annotation.sequenceRef.getContactMaps() != null)
           {
-            ContactMatrixI cm = annotation.sequenceRef.getContactMatrixFor(annotation);
-            if (cm!=null)
+            ContactMatrixI cm = annotation.sequenceRef
+                    .getContactMatrixFor(annotation);
+            if (cm != null)
             {
               MatrixType xmlmat = new MatrixType();
               xmlmat.setType(cm.getType());
               xmlmat.setRows(BigInteger.valueOf(cm.getWidth()));
               xmlmat.setCols(BigInteger.valueOf(cm.getHeight()));
-              // consider using an opaque to/from -> allow instance to control its representation ?
+              // consider using an opaque to/from -> allow instance to control
+              // its representation ?
               xmlmat.setElements(ContactMatrix.contactToFloatString(cm));
               if (cm.hasGroups())
               {
-                for (BitSet gp: cm.getGroups())
+                for (BitSet gp : cm.getGroups())
                 {
-                  BigInteger val = new BigInteger(gp.toByteArray());
-                  xmlmat.getGroups().add(val.toString());
+                  xmlmat.getGroups().add(stringifyBitset(gp));
                 }
               }
               if (cm.hasTree())
@@ -2335,8 +2357,39 @@ public class Jalview2XML
               {
                 xmlmat.setCutHeight(cm.getCutHeight());
               }
-              
               // set/get properties
+              if (cm instanceof MappableContactMatrixI)
+              {
+                jalview.util.MapList mlst = ((MappableContactMatrixI) cm)
+                        .getMapFor(annotation.sequenceRef);
+                if (mlst != null)
+                {
+                  MapListType mp = new MapListType();
+                  List<int[]> r = mlst.getFromRanges();
+                  for (int[] range : r)
+                  {
+                    MapListFrom mfrom = new MapListFrom();
+                    mfrom.setStart(range[0]);
+                    mfrom.setEnd(range[1]);
+                    // mp.addMapListFrom(mfrom);
+                    mp.getMapListFrom().add(mfrom);
+                  }
+                  r = mlst.getToRanges();
+                  for (int[] range : r)
+                  {
+                    MapListTo mto = new MapListTo();
+                    mto.setStart(range[0]);
+                    mto.setEnd(range[1]);
+                    // mp.addMapListTo(mto);
+                    mp.getMapListTo().add(mto);
+                  }
+                  mp.setMapFromUnit(
+                          BigInteger.valueOf(mlst.getFromRatio()));
+                  mp.setMapToUnit(BigInteger.valueOf(mlst.getToRatio()));
+                  xmlmat.setMapping(mp);
+                }
+              }
+              // and add to model
               an.getContactmatrix().add(xmlmat);
             }
           }
@@ -2444,6 +2497,44 @@ public class Jalview2XML
 
   }
 
+  private String stringifyBitset(BitSet gp)
+  {
+    StringBuilder sb = new StringBuilder();
+    for (long val : gp.toLongArray())
+    {
+      if (sb.length() > 0)
+      {
+        sb.append(",");
+      }
+      sb.append(val);
+    }
+    return sb.toString();
+  }
+
+  private BitSet deStringifyBitset(String stringified)
+  {
+    if ("".equals(stringified) || stringified == null)
+    {
+      return new BitSet();
+    }
+    String[] longvals = stringified.split(",");
+    long[] newlongvals = new long[longvals.length];
+    for (int lv = 0; lv < longvals.length; lv++)
+    {
+      try
+      {
+        newlongvals[lv] = Long.valueOf(longvals[lv]);
+      } catch (Exception x)
+      {
+        errorMessage += "Couldn't destringify bitset from: '" + stringified
+                + "'";
+        newlongvals[lv] = 0;
+      }
+    }
+    return BitSet.valueOf(newlongvals);
+
+  }
+
   private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
   {
     AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
@@ -2887,7 +2978,8 @@ public class Jalview2XML
         });
       } catch (Exception x)
       {
-        System.err.println("Error loading alignment: " + x.getMessage());
+        jalview.bin.Console
+                .errPrintln("Error loading alignment: " + x.getMessage());
       }
     }
     return af;
@@ -2926,19 +3018,22 @@ public class Jalview2XML
         {
           if (bytes != null)
           {
-            // System.out.println("Jalview2XML: opening byte jarInputStream for
+            // jalview.bin.Console.outPrintln("Jalview2XML: opening byte
+            // jarInputStream for
             // bytes.length=" + bytes.length);
             return new JarInputStream(new ByteArrayInputStream(bytes));
           }
           if (_url != null)
           {
-            // System.out.println("Jalview2XML: opening url jarInputStream for "
+            // jalview.bin.Console.outPrintln("Jalview2XML: opening url
+            // jarInputStream for "
             // + _url);
             return new JarInputStream(_url.openStream());
           }
           else
           {
-            // System.out.println("Jalview2XML: opening file jarInputStream for
+            // jalview.bin.Console.outPrintln("Jalview2XML: opening file
+            // jarInputStream for
             // " + file);
             return new JarInputStream(new FileInputStream(file));
           }
@@ -3045,11 +3140,12 @@ public class Jalview2XML
     {
       ex.printStackTrace();
       errorMessage = "Couldn't locate Jalview XML file : " + file;
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Exception whilst loading jalview XML file : " + ex + "\n");
     } catch (Exception ex)
     {
-      System.err.println("Parsing as Jalview Version 2 file failed.");
+      jalview.bin.Console
+              .errPrintln("Parsing as Jalview Version 2 file failed.");
       ex.printStackTrace(System.err);
       if (attemptversion1parse)
       {
@@ -3061,18 +3157,19 @@ public class Jalview2XML
       }
       if (af != null)
       {
-        System.out.println("Successfully loaded archive file");
+        jalview.bin.Console.outPrintln("Successfully loaded archive file");
         return af;
       }
       ex.printStackTrace();
 
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Exception whilst loading jalview XML file : " + ex + "\n");
     } catch (OutOfMemoryError e)
     {
       // Don't use the OOM Window here
       errorMessage = "Out of memory loading jalview XML file";
-      System.err.println("Out of memory whilst loading jalview XML file");
+      jalview.bin.Console
+              .errPrintln("Out of memory whilst loading jalview XML file");
       e.printStackTrace();
     }
 
@@ -3176,8 +3273,8 @@ public class Jalview2XML
         Desktop.addInternalFrame(af, view.getTitle(),
                 safeInt(view.getWidth()), safeInt(view.getHeight()));
         af.setMenusForViewport();
-        System.err.println("Failed to restore view " + view.getTitle()
-                + " to split frame");
+        jalview.bin.Console.errPrintln("Failed to restore view "
+                + view.getTitle() + " to split frame");
       }
     }
 
@@ -3255,7 +3352,8 @@ public class Jalview2XML
       }
       else
       {
-        System.err.println("Problem loading Jalview file: " + errorMessage);
+        jalview.bin.Console.errPrintln(
+                "Problem loading Jalview file: " + errorMessage);
       }
     }
     errorMessage = null;
@@ -3453,7 +3551,7 @@ public class Jalview2XML
           if (tmpSeq.getStart() != jseq.getStart()
                   || tmpSeq.getEnd() != jseq.getEnd())
           {
-            System.err.println(String.format(
+            jalview.bin.Console.errPrintln(String.format(
                     "Warning JAL-2154 regression: updating start/end for sequence %s from %d/%d to %d/%d",
                     tmpSeq.getName(), tmpSeq.getStart(), tmpSeq.getEnd(),
                     jseq.getStart(), jseq.getEnd()));
@@ -3948,7 +4046,8 @@ public class Jalview2XML
         jaa.setCalcId(annotation.getCalcId());
         if (annotation.getProperty().size() > 0)
         {
-          for (jalview.xml.binding.jalview.Property prop : annotation.getProperty())
+          for (jalview.xml.binding.jalview.Property prop : annotation
+                  .getProperty())
           {
             jaa.setProperty(prop.getName(), prop.getValue());
           }
@@ -3972,33 +4071,57 @@ public class Jalview2XML
                           .fromFloatStringToContacts(xmlmat.getElements(),
                                   xmlmat.getCols().intValue(),
                                   xmlmat.getRows().intValue());
+                  jalview.util.MapList mapping = null;
+                  if (xmlmat.getMapping() != null)
+                  {
+                    MapListType m = xmlmat.getMapping();
+                    // Mapping m = dr.getMapping();
+                    int fr[] = new int[m.getMapListFrom().size() * 2];
+                    Iterator<MapListFrom> from = m.getMapListFrom()
+                            .iterator();// enumerateMapListFrom();
+                    for (int _i = 0; from.hasNext(); _i += 2)
+                    {
+                      MapListFrom mf = from.next();
+                      fr[_i] = mf.getStart();
+                      fr[_i + 1] = mf.getEnd();
+                    }
+                    int fto[] = new int[m.getMapListTo().size() * 2];
+                    Iterator<MapListTo> to = m.getMapListTo().iterator();// enumerateMapListTo();
+                    for (int _i = 0; to.hasNext(); _i += 2)
+                    {
+                      MapListTo mf = to.next();
+                      fto[_i] = mf.getStart();
+                      fto[_i + 1] = mf.getEnd();
+                    }
 
-                  PAEContactMatrix newpae = new PAEContactMatrix(
-                          jaa.sequenceRef, elements);
-                  List<BitSet> newgroups=new ArrayList<BitSet>();
-                  if (xmlmat.getGroups().size()>0)
+                    mapping = new jalview.util.MapList(fr, fto,
+                            m.getMapFromUnit().intValue(),
+                            m.getMapToUnit().intValue());
+                  }
+                  List<BitSet> newgroups = new ArrayList<BitSet>();
+                  if (xmlmat.getGroups().size() > 0)
                   {
-                    for (String sgroup:xmlmat.getGroups())
+                    for (String sgroup : xmlmat.getGroups())
                     {
-                      try {
-                        BigInteger group = new BigInteger(sgroup);
-                        newgroups.add(BitSet.valueOf(group.toByteArray()));
-                      } catch (NumberFormatException nfe)
-                      {
-                        Console.error("Problem parsing groups for a contact matrix (\""+sgroup+"\"",nfe);
-                      }
+                      newgroups.add(deStringifyBitset(sgroup));
                     }
                   }
-                  String nwk=xmlmat.getNewick().size()>0 ? xmlmat.getNewick().get(0):null;
-                  if  (xmlmat.getNewick().size()>1)
+                  String nwk = xmlmat.getNewick().size() > 0
+                          ? xmlmat.getNewick().get(0)
+                          : null;
+                  if (xmlmat.getNewick().size() > 1)
                   {
                     Console.log.info(
                             "Ignoring additional clusterings for contact matrix");
                   }
-                  
                   String treeMethod = xmlmat.getTreeMethod();
-                  double thresh = xmlmat.getCutHeight()!=null ? xmlmat.getCutHeight() : 0;
-                  newpae.restoreGroups(newgroups, treeMethod, nwk, thresh);
+                  double thresh = xmlmat.getCutHeight() != null
+                          ? xmlmat.getCutHeight()
+                          : 0;
+                  GroupSet grpset = new GroupSet();
+                  grpset.restoreGroups(newgroups, treeMethod, nwk, thresh);
+                  PAEContactMatrix newpae = new PAEContactMatrix(
+                          jaa.sequenceRef, mapping, elements, grpset);
                   jaa.sequenceRef.addContactListFor(jaa, newpae);
                 }
               }
@@ -4159,7 +4282,7 @@ public class Jalview2XML
       // XML.
       // and then recover its containing af to allow the settings to be applied.
       // TODO: fix for vamsas demo
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "About to recover a viewport for existing alignment: Sequence set ID is "
                       + uniqueSeqSetId);
       Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
@@ -4168,13 +4291,13 @@ public class Jalview2XML
         if (seqsetobj instanceof String)
         {
           uniqueSeqSetId = (String) seqsetobj;
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
                           + uniqueSeqSetId);
         }
         else
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Warning : Collision between sequence set ID string and existing jalview object mapping.");
         }
 
@@ -4246,8 +4369,8 @@ public class Jalview2XML
    */
   protected void loadOverview(Viewport view, String version, AlignFrame af)
   {
-    if (!isVersionStringLaterThan("2.11.3",
-            version) && view.getOverview()==null)
+    if (!isVersionStringLaterThan("2.11.3", version)
+            && view.getOverview() == null)
     {
       return;
     }
@@ -4394,8 +4517,8 @@ public class Jalview2XML
         {
           if (tree.isColumnWise())
           {
-            AlignmentAnnotation aa = (AlignmentAnnotation) annotationIds.get(tree
-                    .getColumnReference());
+            AlignmentAnnotation aa = annotationIds
+                    .get(tree.getColumnReference());
             if (aa == null)
             {
               Console.warn(
@@ -4614,7 +4737,7 @@ public class Jalview2XML
         createOrLinkStructureViewer(entry, af, ap, jprovider);
       } catch (Exception e)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Error loading structure viewer: " + e.getMessage());
         // failed - try the next one
       }
@@ -4818,7 +4941,7 @@ public class Jalview2XML
             || version.equalsIgnoreCase("Test")
             || version.equalsIgnoreCase("AUTOMATED BUILD"))
     {
-      System.err.println("Assuming project file with "
+      jalview.bin.Console.errPrintln("Assuming project file with "
               + (version == null ? "null" : version)
               + " is compatible with Jalview version " + supported);
       return true;
@@ -4865,7 +4988,7 @@ public class Jalview2XML
     //
     // @Override
     // protected void processKeyEvent(java.awt.event.KeyEvent e) {
-    // System.out.println("Jalview2XML AF " + e);
+    // jalview.bin.Console.outPrintln("Jalview2XML AF " + e);
     // super.processKeyEvent(e);
     //
     // }
@@ -4953,10 +5076,11 @@ public class Jalview2XML
     viewport.setIncrement(safeInt(view.getConsThreshold()));
     viewport.setShowJVSuffix(safeBoolean(view.isShowFullId()));
     viewport.setRightAlignIds(safeBoolean(view.isRightAlignIds()));
-    viewport.setFont(new Font(view.getFontName(),
-            safeInt(view.getFontStyle()), safeInt(view.getFontSize())),
-            (view.getCharWidth()!=null) ? false : true);
-    if (view.getCharWidth()!=null)
+    viewport.setFont(
+            new Font(view.getFontName(), safeInt(view.getFontStyle()),
+                    safeInt(view.getFontSize())),
+            (view.getCharWidth() != null) ? false : true);
+    if (view.getCharWidth() != null)
     {
       viewport.setCharWidth(view.getCharWidth());
       viewport.setCharHeight(view.getCharHeight());
@@ -5279,11 +5403,12 @@ public class Jalview2XML
     }
     if (matchedAnnotation == null)
     {
-      System.err.println("Failed to match annotation colour scheme for "
-              + annotationId);
+      jalview.bin.Console
+              .errPrintln("Failed to match annotation colour scheme for "
+                      + annotationId);
       return null;
     }
-    // belt-and-braces create a threshold line if the 
+    // belt-and-braces create a threshold line if the
     // colourscheme needs one but the matchedAnnotation doesn't have one
     if (safeInt(viewAnnColour.getAboveThreshold()) != 0
             && matchedAnnotation.getThreshold() == null)
@@ -5738,7 +5863,7 @@ public class Jalview2XML
         }
         // TODO: merges will never happen if we 'know' we have the real dataset
         // sequence - this should be detected when id==dssid
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "DEBUG Notice:  Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
         // + (pre ? "prepended" : "") + " "
         // + (post ? "appended" : ""));
@@ -5931,7 +6056,7 @@ public class Jalview2XML
       }
       else
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Warning - making up dataset sequence id for DbRef sequence map reference");
         sqid = ((Object) ms).toString(); // make up a new hascode for
         // undefined dataset sequence hash
@@ -6612,7 +6737,7 @@ public class Jalview2XML
     } catch (IllegalStateException e)
     {
       // mixing AND and OR conditions perhaps
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               String.format("Error reading filter conditions for '%s': %s",
                       featureType, e.getMessage()));
       // return as much as was parsed up to the error
@@ -6693,7 +6818,8 @@ public class Jalview2XML
       }
       else
       {
-        System.err.println("Malformed compound filter condition");
+        jalview.bin.Console
+                .errPrintln("Malformed compound filter condition");
       }
     }
   }
index eb83f31..d943d39 100644 (file)
  */
 package jalview.renderer;
 
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.RenderingHints;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.image.ImageObserver;
+import java.util.BitSet;
+import java.util.Hashtable;
+
+import org.jfree.graphics2d.svg.SVGGraphics2D;
+import org.jibble.epsgraphics.EpsGraphics2D;
+
 import jalview.analysis.AAFrequency;
 import jalview.analysis.CodingUtils;
 import jalview.analysis.Rna;
 import jalview.analysis.StructureFrequency;
 import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
+import jalview.bin.Console;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
@@ -38,18 +57,6 @@ import jalview.schemes.ResidueProperties;
 import jalview.schemes.ZappoColourScheme;
 import jalview.util.Platform;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.geom.AffineTransform;
-import java.awt.image.ImageObserver;
-import java.util.BitSet;
-import java.util.Hashtable;
-
 public class AnnotationRenderer
 {
   private static final int UPPER_TO_LOWER = 'a' - 'A'; // 32
@@ -88,6 +95,10 @@ public class AnnotationRenderer
 
   private boolean av_ignoreGapsConsensus;
 
+  private boolean vectorRendition = false;
+
+  private boolean glyphLineDrawn = false;
+
   /**
    * attributes set from AwtRenderPanelI
    */
@@ -189,7 +200,7 @@ public class AnnotationRenderer
          * if new annotation with a closing base pair half of the stem, 
          * display a backward arrow
          */
-        g.fillPolygon(new int[] { lastSSX + 5, lastSSX + 5, lastSSX },
+        fillPolygon(g, new int[] { lastSSX + 5, lastSSX + 5, lastSSX },
                 new int[]
                 { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset },
                 3);
@@ -209,7 +220,7 @@ public class AnnotationRenderer
          * if annotation ending with an opeing base pair half of the stem, 
          * display a forward arrow
          */
-        g.fillPolygon(new int[] { x2 - 5, x2 - 5, x2 },
+        fillPolygon(g, new int[] { x2 - 5, x2 - 5, x2 },
                 new int[]
                 { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset },
                 3);
@@ -221,7 +232,7 @@ public class AnnotationRenderer
       }
     }
     // draw arrow body
-    g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 7);
+    fillRect(g, x1, y + 4 + iconOffset, x2 - x1, 7);
   }
 
   void drawNotCanonicalAnnot(Graphics g, Color nonCanColor,
@@ -229,9 +240,8 @@ public class AnnotationRenderer
           int iconOffset, int startRes, int column, boolean validRes,
           boolean validEnd)
   {
-    // System.out.println(nonCanColor);
+    // Console.info(nonCanColor);
 
-    g.setColor(nonCanColor);
     int sCol = (lastSSX / charWidth)
             + hiddenColumns.visibleToAbsoluteColumn(startRes);
     int x1 = lastSSX;
@@ -245,9 +255,16 @@ public class AnnotationRenderer
     boolean diffdownstream = !validRes || !validEnd
             || row_annotations[column] == null
             || !dc.equals(row_annotations[column].displayCharacter);
-    // System.out.println("Column "+column+" diff up: "+diffupstream+"
+    // Console.info("Column "+column+" diff up:
+    // "+diffupstream+"
     // down:"+diffdownstream);
     // If a closing base pair half of the stem, display a backward arrow
+    if (diffupstream || diffdownstream)
+    {
+      // draw glyphline under arrow
+      drawGlyphLine(g, lastSSX, x, y, iconOffset);
+    }
+    g.setColor(nonCanColor);
     if (column > 0 && Rna.isClosingParenthesis(dc))
     {
 
@@ -255,9 +272,10 @@ public class AnnotationRenderer
       // if (validRes && column>1 && row_annotations[column-2]!=null &&
       // dc.equals(row_annotations[column-2].displayCharacter))
       {
-        g.fillPolygon(new int[] { lastSSX + 5, lastSSX + 5, lastSSX },
+        fillPolygon(g, new int[] { lastSSX + 5, lastSSX + 5, lastSSX },
                 new int[]
-                { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset },
+                { y + iconOffset + 1, y + 13 + iconOffset,
+                    y + 7 + iconOffset },
                 3);
         x1 += 5;
       }
@@ -272,9 +290,10 @@ public class AnnotationRenderer
       // display a forward arrow
       if (diffdownstream)
       {
-        g.fillPolygon(new int[] { x2 - 5, x2 - 5, x2 },
+        fillPolygon(g, new int[] { x2 - 6, x2 - 6, x2 - 1 },
                 new int[]
-                { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset },
+                { y + iconOffset + 1, y + 13 + iconOffset,
+                    y + 7 + iconOffset },
                 3);
         x2 -= 5;
       }
@@ -284,7 +303,8 @@ public class AnnotationRenderer
       }
     }
     // draw arrow body
-    g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 7);
+    unsetAntialias(g);
+    fillRect(g, x1, y + 4 + iconOffset, x2 - x1, 6);
   }
 
   // public void updateFromAnnotationPanel(FontMetrics annotFM, AlignViewportI
@@ -447,6 +467,12 @@ public class AnnotationRenderer
           AlignViewportI av, Graphics g, int activeRow, int startRes,
           int endRes)
   {
+    if (g instanceof EpsGraphics2D || g instanceof SVGGraphics2D)
+    {
+      this.setVectorRendition(true);
+    }
+    Graphics2D g2d = (Graphics2D) g;
+
     long stime = System.currentTimeMillis();
     boolean usedFaded = false;
     // NOTES:
@@ -592,9 +618,13 @@ public class AnnotationRenderer
          * 
          * continue; }
          */
+
         // first pass sets up state for drawing continuation from left-hand
         // column
         // of startRes
+
+        // flag used for vector rendition
+        this.glyphLineDrawn = false;
         x = (startRes == 0) ? 0 : -1;
         while (x < endRes - startRes)
         {
@@ -626,6 +656,7 @@ public class AnnotationRenderer
                   : null;
           if (x > -1)
           {
+            unsetAntialias(g);
             if (activeRow == i)
             {
               g.setColor(Color.red);
@@ -634,24 +665,24 @@ public class AnnotationRenderer
               {
                 if (columnSelection.contains(column))
                 {
-                  g.fillRect(x * charWidth, y, charWidth, charHeight);
+                  fillRect(g, x * charWidth, y, charWidth, charHeight);
                 }
               }
             }
             if (row.getInvalidStrucPos() > x)
             {
               g.setColor(Color.orange);
-              g.fillRect(x * charWidth, y, charWidth, charHeight);
+              fillRect(g, x * charWidth, y, charWidth, charHeight);
             }
             else if (row.getInvalidStrucPos() == x)
             {
               g.setColor(Color.orange.darker());
-              g.fillRect(x * charWidth, y, charWidth, charHeight);
+              fillRect(g, x * charWidth, y, charWidth, charHeight);
             }
             if (validCharWidth && validRes && displayChar != null
                     && (displayChar.length() > 0))
             {
-              Graphics2D gg = ((Graphics2D) g);
+              // Graphics2D gg = (g);
               float fmWidth = fm.charsWidth(displayChar.toCharArray(), 0,
                       displayChar.length());
 
@@ -674,11 +705,11 @@ public class AnnotationRenderer
 
               if (row_annotations[column].colour == null)
               {
-                gg.setColor(Color.black);
+                g2d.setColor(Color.black);
               }
               else
               {
-                gg.setColor(row_annotations[column].colour);
+                g2d.setColor(row_annotations[column].colour);
               }
 
               /*
@@ -691,19 +722,20 @@ public class AnnotationRenderer
               /*
                * translate to drawing position _before_ applying any scaling
                */
-              gg.translate(xPos, yPos);
+              g2d.translate(xPos, yPos);
               if (scaledToFit)
               {
                 /*
                  * use a scaling transform to make the label narrower
                  * (JalviewJS doesn't have Font.deriveFont(AffineTransform))
                  */
-                gg.transform(
+                g2d.transform(
                         AffineTransform.getScaleInstance(fmScaling, 1.0));
               }
+              setAntialias(g);
               if (column == 0 || row.graph > 0)
               {
-                gg.drawString(displayChar, 0, 0);
+                g2d.drawString(displayChar, 0, 0);
               }
               else if (row_annotations[column - 1] == null || (labelAllCols
                       || !displayChar.equals(
@@ -711,7 +743,7 @@ public class AnnotationRenderer
                       || (displayChar.length() < 2
                               && row_annotations[column].secondaryStructure == ' ')))
               {
-                gg.drawString(displayChar, 0, 0);
+                g2d.drawString(displayChar, 0, 0);
               }
               if (scaledToFit)
               {
@@ -719,10 +751,10 @@ public class AnnotationRenderer
                  * undo scaling before translating back 
                  * (restoring saved transform does NOT work in JS PDFGraphics!)
                  */
-                gg.transform(AffineTransform
+                g2d.transform(AffineTransform
                         .getScaleInstance(1D / fmScaling, 1.0));
               }
-              gg.translate(-xPos, -yPos);
+              g2d.translate(-xPos, -yPos);
             }
           }
           if (row.hasIcons)
@@ -784,7 +816,8 @@ public class AnnotationRenderer
               {
 
                 // int nb_annot = x - temp;
-                // System.out.println("\t type :"+lastSS+"\t x :"+x+"\t nbre
+                // Console.info("\t type :"+lastSS+"\t x
+                // :"+x+"\t nbre
                 // annot :"+nb_annot);
                 switch (lastSS)
                 {
@@ -878,10 +911,17 @@ public class AnnotationRenderer
                   // temp = x;
                   break;
                 default:
-                  g.setColor(Color.gray);
-                  g.fillRect(lastSSX, y + 6 + iconOffset,
-                          (x * charWidth) - lastSSX, 2);
-                  // temp = x;
+                  if (isVectorRendition())
+                  {
+                    // draw single full width glyphline
+                    drawGlyphLine(g, lastSSX, endRes - x, y, iconOffset);
+                    // disable more glyph lines
+                    this.glyphLineDrawn = true;
+                  }
+                  else
+                  {
+                    drawGlyphLine(g, lastSSX, x, y, iconOffset);
+                  }
                   break;
                 }
               }
@@ -1006,14 +1046,23 @@ public class AnnotationRenderer
           case 'y':
           case 'Z':
           case 'z':
-            // System.out.println(lastSS);
+            // Console.info(lastSS);
             Color nonCanColor = getNotCanonicalColor(lastSS);
             drawNotCanonicalAnnot(g, nonCanColor, row_annotations, lastSSX,
                     x, y, iconOffset, startRes, column, validRes, validEnd);
             break;
           default:
-            drawGlyphLine(g, row_annotations, lastSSX, x, y, iconOffset,
-                    startRes, column, validRes, validEnd);
+            if (isVectorRendition())
+            {
+              // draw single full width glyphline
+              drawGlyphLine(g, lastSSX, endRes - x, y, iconOffset);
+              // disable more glyph lines
+              this.glyphLineDrawn = true;
+            }
+            else
+            {
+              drawGlyphLine(g, lastSSX, x, y, iconOffset);
+            }
             break;
           }
         }
@@ -1077,22 +1126,22 @@ public class AnnotationRenderer
                     .getRendererFor(row);
             if (renderer != null)
             {
-              renderer.renderRow(g, charWidth, charHeight,
-                      hasHiddenColumns, av, hiddenColumns, columnSelection,
-                      row, row_annotations, startRes, endRes, row.graphMin,
+              renderer.renderRow(g, charWidth, charHeight, hasHiddenColumns,
+                      av, hiddenColumns, columnSelection, row,
+                      row_annotations, startRes, endRes, row.graphMin,
                       row.graphMax, y);
             }
             if (debugRedraw)
             {
               if (renderer == null)
               {
-                System.err.println("No renderer found for "
-                        + row.toString());
+                System.err
+                        .println("No renderer found for " + row.toString());
               }
               else
               {
-                System.err.println("rendered with "
-                        + renderer.getClass().toString());
+                Console.warn(
+                        "rendered with " + renderer.getClass().toString());
               }
             }
 
@@ -1122,17 +1171,15 @@ public class AnnotationRenderer
       {
         if (clipst)
         {
-          System.err.println(
-                  "Start clip at : " + yfrom + " (index " + f_i + ")");
+          Console.warn("Start clip at : " + yfrom + " (index " + f_i + ")");
         }
         if (clipend)
         {
-          System.err.println(
-                  "End clip at : " + yto + " (index " + f_to + ")");
+          Console.warn("End clip at : " + yto + " (index " + f_to + ")");
         }
       }
       ;
-      System.err.println("Annotation Rendering time:"
+      Console.warn("Annotation Rendering time:"
               + (System.currentTimeMillis() - stime));
     }
     ;
@@ -1150,10 +1197,15 @@ public class AnnotationRenderer
 
   // private Color sdNOTCANONICAL_COLOUR;
 
-  void drawGlyphLine(Graphics g, Annotation[] row, int lastSSX, int x,
-          int y, int iconOffset, int startRes, int column, boolean validRes,
-          boolean validEnd)
+  void drawGlyphLine(Graphics g, int lastSSX, int x, int y, int iconOffset)
   {
+    if (glyphLineDrawn)
+    {
+      // if we've drawn a single long glyphline for an export, don't draw the
+      // bits
+      return;
+    }
+    unsetAntialias(g);
     g.setColor(GLYPHLINE_COLOR);
     g.fillRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX, 2);
   }
@@ -1163,45 +1215,52 @@ public class AnnotationRenderer
           int lastSSX, int x, int y, int iconOffset, int startRes,
           int column, boolean validRes, boolean validEnd)
   {
-    g.setColor(SHEET_COLOUR);
-
     if (!validEnd || !validRes || row == null || row[column] == null
             || row[column].secondaryStructure != 'E')
     {
-      g.fillRect(lastSSX, y + 4 + iconOffset, (x * charWidth) - lastSSX - 4,
-              7);
-      g.fillPolygon(
+      // draw the glyphline underneath
+      drawGlyphLine(g, lastSSX, x, y, iconOffset);
+
+      g.setColor(SHEET_COLOUR);
+      fillRect(g, lastSSX, y + 4 + iconOffset,
+              (x * charWidth) - lastSSX - 4, 6);
+      fillPolygon(g,
               new int[]
-              { (x * charWidth) - 4, (x * charWidth) - 4, (x * charWidth) },
+              { (x * charWidth) - 6, (x * charWidth) - 6,
+                  (x * charWidth - 1) },
               new int[]
-              { y + iconOffset, y + 14 + iconOffset, y + 7 + iconOffset },
+              { y + iconOffset + 1, y + 13 + iconOffset,
+                  y + 7 + iconOffset },
               3);
     }
     else
     {
-      g.fillRect(lastSSX, y + 4 + iconOffset, (x + 1) * charWidth - lastSSX,
-              7);
+      g.setColor(SHEET_COLOUR);
+      fillRect(g, lastSSX, y + 4 + iconOffset, (x * charWidth) - lastSSX,
+              6);
     }
-
   }
 
   void drawHelixAnnot(Graphics g, Annotation[] row, int lastSSX, int x,
           int y, int iconOffset, int startRes, int column, boolean validRes,
           boolean validEnd)
   {
-    g.setColor(HELIX_COLOUR);
-
     int sCol = (lastSSX / charWidth)
             + hiddenColumns.visibleToAbsoluteColumn(startRes);
     int x1 = lastSSX;
     int x2 = (x * charWidth);
 
-    if (USE_FILL_ROUND_RECT)
+    if (USE_FILL_ROUND_RECT || isVectorRendition())
     {
+      // draw glyph line behind helix (visible in EPS or SVG output)
+      drawGlyphLine(g, lastSSX, x, y, iconOffset);
+
+      g.setColor(HELIX_COLOUR);
+      setAntialias(g);
       int ofs = charWidth / 2;
       // Off by 1 offset when drawing rects and ovals
       // to offscreen image on the MAC
-      g.fillRoundRect(lastSSX, y + 4 + iconOffset, x2 - x1, 8, 8, 8);
+      fillRoundRect(g, lastSSX, y + 3 + iconOffset, x2 - x1 - 1, 8, 8, 8);
       if (sCol == 0 || row[sCol - 1] == null
               || row[sCol - 1].secondaryStructure != 'H')
       {
@@ -1209,8 +1268,8 @@ public class AnnotationRenderer
       else
       {
         // g.setColor(Color.orange);
-        g.fillRoundRect(lastSSX, y + 4 + iconOffset, x2 - x1 - ofs + 1, 8,
-                0, 0);
+        fillRoundRect(g, lastSSX, y + 3 + iconOffset, x2 - x1 - ofs, 8, 0,
+                0);
       }
       if (!validRes || row[column] == null
               || row[column].secondaryStructure != 'H')
@@ -1220,30 +1279,38 @@ public class AnnotationRenderer
       else
       {
         // g.setColor(Color.magenta);
-        g.fillRoundRect(lastSSX + ofs, y + 4 + iconOffset,
-                x2 - x1 - ofs + 1, 8, 0, 0);
-
+        fillRoundRect(g, lastSSX + ofs, y + 3 + iconOffset, x2 - x1 - ofs,
+                8, 0, 0);
       }
 
       return;
     }
 
-    if (sCol == 0 || row[sCol - 1] == null
-            || row[sCol - 1].secondaryStructure != 'H')
+    boolean leftEnd = sCol == 0 || row[sCol - 1] == null
+            || row[sCol - 1].secondaryStructure != 'H';
+    boolean rightEnd = !validRes || row[column] == null
+            || row[column].secondaryStructure != 'H';
+
+    if (leftEnd || rightEnd)
+    {
+      drawGlyphLine(g, lastSSX, x, y, iconOffset);
+    }
+    g.setColor(HELIX_COLOUR);
+
+    if (leftEnd)
     {
-      g.fillArc(lastSSX, y + 4 + iconOffset, charWidth, 8, 90, 180);
+      fillArc(g, lastSSX, y + 3 + iconOffset, charWidth, 8, 90, 180);
       x1 += charWidth / 2;
     }
 
-    if (!validRes || row[column] == null
-            || row[column].secondaryStructure != 'H')
+    if (rightEnd)
     {
-      g.fillArc((x * charWidth) - charWidth, y + 4 + iconOffset, charWidth,
-              8, 270, 180);
+      fillArc(g, ((x - 1) * charWidth), y + 3 + iconOffset, charWidth, 8,
+              270, 180);
       x2 -= charWidth / 2;
     }
 
-    g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
+    fillRect(g, x1, y + 3 + iconOffset, x2 - x1, 8);
   }
 
   void drawLineGraph(Graphics g, AlignmentAnnotation _aa,
@@ -1254,6 +1321,13 @@ public class AnnotationRenderer
     {
       return;
     }
+    Stroke roundStroke = new BasicStroke(1, BasicStroke.CAP_ROUND,
+            BasicStroke.JOIN_ROUND);
+    Stroke squareStroke = new BasicStroke(1, BasicStroke.CAP_SQUARE,
+            BasicStroke.JOIN_MITER);
+    Graphics2D g2d = (Graphics2D) g;
+    Stroke prevStroke = g2d.getStroke();
+    g2d.setStroke(roundStroke);
 
     int x = 0;
 
@@ -1280,7 +1354,8 @@ public class AnnotationRenderer
     }
 
     g.setColor(Color.gray);
-    g.drawLine(x - charWidth, y2, (eRes - sRes + 1) * charWidth, y2);
+    drawLine(g, squareStroke, x * charWidth - charWidth, y2,
+            (eRes - sRes) * charWidth, y2);
 
     eRes = Math.min(eRes, aa_annotations.length);
 
@@ -1300,8 +1375,7 @@ public class AnnotationRenderer
         break;
       }
 
-      if (aa_annotations[column] == null
-              || aa_annotations[column - 1] == null)
+      if (aa_annotations[column] == null)
       {
         x++;
         continue;
@@ -1316,12 +1390,31 @@ public class AnnotationRenderer
         g.setColor(aa_annotations[column].colour);
       }
 
+      if (aa_annotations[column - 1] == null
+              && aa_annotations.length > column + 1
+              && aa_annotations[column + 1] == null)
+      {
+        // standalone value
+        y1 = y - (int) (((aa_annotations[column].value - min) / range)
+                * graphHeight);
+        drawLine(g, x * charWidth + charWidth / 4, y1,
+                x * charWidth + 3 * charWidth / 4, y1);
+        x++;
+        continue;
+      }
+
+      if (aa_annotations[column - 1] == null)
+      {
+        x++;
+        continue;
+      }
+
       y1 = y - (int) (((aa_annotations[column - 1].value - min) / range)
               * graphHeight);
       y2 = y - (int) (((aa_annotations[column].value - min) / range)
               * graphHeight);
 
-      g.drawLine(x * charWidth - charWidth / 2, y1,
+      drawLine(g, (x - 1) * charWidth + charWidth / 2, y1,
               x * charWidth + charWidth / 2, y2);
       x++;
     }
@@ -1330,14 +1423,14 @@ public class AnnotationRenderer
     {
       g.setColor(_aa.threshold.colour);
       Graphics2D g2 = (Graphics2D) g;
-      g2.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE,
+      Stroke s = new BasicStroke(1, BasicStroke.CAP_SQUARE,
               BasicStroke.JOIN_ROUND, 3f, new float[]
-              { 5f, 3f }, 0f));
+              { 5f, 3f }, 0f);
 
       y2 = (int) (y - ((_aa.threshold.value - min) / range) * graphHeight);
-      g.drawLine(0, y2, (eRes - sRes) * charWidth, y2);
-      g2.setStroke(new BasicStroke());
+      drawLine(g, s, 0, y2, (eRes - sRes) * charWidth, y2);
     }
+    g2d.setStroke(prevStroke);
   }
 
   @SuppressWarnings("unused")
@@ -1364,7 +1457,7 @@ public class AnnotationRenderer
 
     g.setColor(Color.gray);
 
-    g.drawLine(x, y2, (eRes - sRes) * charWidth, y2);
+    drawLine(g, x, y2, (eRes - sRes) * charWidth, y2);
 
     int column;
     int aaMax = aa_annotations.length - 1;
@@ -1402,11 +1495,11 @@ public class AnnotationRenderer
       {
         if (y1 - y2 > 0)
         {
-          g.fillRect(x * charWidth, y2, charWidth, y1 - y2);
+          fillRect(g, x * charWidth, y2, charWidth, y1 - y2);
         }
         else
         {
-          g.fillRect(x * charWidth, y1, charWidth, y2 - y1);
+          fillRect(g, x * charWidth, y1, charWidth, y2 - y1);
         }
       }
       // draw profile if available
@@ -1437,7 +1530,8 @@ public class AnnotationRenderer
           // lm is not necessary - we can just use fm - could be off by no more
           // than 0.5 px
           // LineMetrics lm = g.getFontMetrics(ofont).getLineMetrics("Q", g);
-          // System.out.println(asc + " " + dec + " " + (asc - lm.getAscent())
+          // Console.info(asc + " " + dec + " " + (asc -
+          // lm.getAscent())
           // + " " + (dec - lm.getDescent()));
 
           double asc = fm.getAscent();
@@ -1562,15 +1656,13 @@ public class AnnotationRenderer
     if (_aa.threshold != null)
     {
       g.setColor(_aa.threshold.colour);
-      Graphics2D g2 = (Graphics2D) g;
-      g2.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE,
+      Stroke s = new BasicStroke(1, BasicStroke.CAP_SQUARE,
               BasicStroke.JOIN_ROUND, 3f, new float[]
-              { 5f, 3f }, 0f));
+              { 5f, 3f }, 0f);
 
       y2 = (int) (y
               - ((_aa.threshold.value - min) / range) * _aa.graphHeight);
-      g.drawLine(0, y2, (eRes - sRes) * charWidth, y2);
-      g2.setStroke(new BasicStroke());
+      drawLine(g, s, 0, y2, (eRes - sRes) * charWidth, y2);
     }
   }
 
@@ -1580,7 +1672,7 @@ public class AnnotationRenderer
   {
     eRes = Math.min(eRes, aa_annotations.length);
     g.setColor(Color.white);
-    g.fillRect(0, 0, width, y);
+    fillRect(g, 0, 0, width, y);
     g.setColor(new Color(0, 0, 180));
 
     int x = 0, height;
@@ -1604,7 +1696,7 @@ public class AnnotationRenderer
           height = y;
         }
 
-        g.fillRect(x, y - height, charWidth, height);
+        fillRect(g, x, y - height, charWidth, height);
       }
       x += charWidth;
     }
@@ -1731,9 +1823,92 @@ public class AnnotationRenderer
       return new Color(0, 80, 255);
 
     default:
-      System.out.println("This is not a interaction : " + lastss);
+      Console.info("This is not a interaction : " + lastss);
       return null;
 
     }
   }
+
+  private void fillPolygon(Graphics g, int[] xpoints, int[] ypoints, int n)
+  {
+    setAntialias(g);
+    g.fillPolygon(xpoints, ypoints, n);
+  }
+
+  /*
+  private void fillRect(Graphics g, int a, int b, int c, int d)
+  {
+    fillRect(g, false, a, b, c, d);
+  }*/
+
+  private void fillRect(Graphics g, int a, int b, int c, int d)
+  {
+    unsetAntialias(g);
+    g.fillRect(a, b, c, d);
+  }
+
+  private void fillRoundRect(Graphics g, int a, int b, int c, int d, int e,
+          int f)
+  {
+    setAntialias(g);
+    g.fillRoundRect(a, b, c, d, e, f);
+  }
+
+  private void fillArc(Graphics g, int a, int b, int c, int d, int e, int f)
+  {
+    setAntialias(g);
+    g.fillArc(a, b, c, d, e, f);
+  }
+
+  private void drawLine(Graphics g, Stroke s, int a, int b, int c, int d)
+  {
+    Graphics2D g2d = (Graphics2D) g;
+    Stroke p = g2d.getStroke();
+    g2d.setStroke(s);
+    drawLine(g, a, b, c, d);
+    g2d.setStroke(p);
+  }
+
+  private void drawLine(Graphics g, int a, int b, int c, int d)
+  {
+    setAntialias(g);
+    g.drawLine(a, b, c, d);
+  }
+
+  private void setAntialias(Graphics g)
+  {
+    if (isVectorRendition())
+    {
+      // no need to antialias vector drawings
+      return;
+    }
+    if (Cache.getDefault("ANTI_ALIAS", true))
+    {
+      Graphics2D g2d = (Graphics2D) g;
+      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+              RenderingHints.VALUE_ANTIALIAS_ON);
+    }
+  }
+
+  private void unsetAntialias(Graphics g)
+  {
+    if (isVectorRendition())
+    {
+      // no need to antialias vector drawings
+      return;
+    }
+    Graphics2D g2d = (Graphics2D) g;
+    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+            RenderingHints.VALUE_ANTIALIAS_OFF);
+  }
+
+  public void setVectorRendition(boolean b)
+  {
+    vectorRendition = b;
+  }
+
+  public boolean isVectorRendition()
+  {
+    return vectorRendition;
+  }
 }
index db2eb7a..85d22c9 100644 (file)
@@ -7,8 +7,7 @@ import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 
 import java.util.IdentityHashMap;
 
-public class AnnotationRendererFactory implements
-        AnnotationRendererFactoryI
+public class AnnotationRendererFactory implements AnnotationRendererFactoryI
 {
 
   private static AnnotationRendererFactoryI factory = null;
@@ -40,8 +39,9 @@ public class AnnotationRendererFactory implements
       {
         return ContactMapRenderer.newPAERenderer();
       }
-      // TODO add potential for configuring renderer directly from the annotation row and/or viewmodel
-      
+      // TODO add potential for configuring renderer directly from the
+      // annotation row and/or viewmodel
+
     }
     return null;
   }
index 4aef1d8..9fd4de6 100644 (file)
@@ -2,10 +2,23 @@ package jalview.renderer;
 
 import java.util.Iterator;
 
+import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.ContactListI;
-
+import jalview.datamodel.HiddenColumns;
+import jalview.renderer.ContactGeometry.contactInterval;
+
+/**
+ * encapsulate logic for mapping between positions in a ContactList and their
+ * rendered representation in a given number of pixels.
+ * 
+ * @author jprocter
+ *
+ */
 public class ContactGeometry
 {
+
+  final ContactListI contacts;
+
   final int pixels_step;
 
   final double contacts_per_pixel;
@@ -14,8 +27,9 @@ public class ContactGeometry
 
   final int graphHeight;
 
-  public ContactGeometry(ContactListI contacts, int graphHeight)
+  public ContactGeometry(final ContactListI contacts, int graphHeight)
   {
+    this.contacts = contacts;
     this.graphHeight = graphHeight;
     contact_height = contacts.getContactHeight();
     // fractional number of contacts covering each pixel
@@ -54,6 +68,56 @@ public class ContactGeometry
     public final int pStart;
 
     public final int pEnd;
+
+  }
+
+  /**
+   * 
+   * @param columnSelection
+   * @param ci
+   * @param visibleOnly
+   *          - when true, only test intersection of visible columns given
+   *          matrix range
+   * @return true if the range on the matrix specified by ci intersects with
+   *         selected columns in the ContactListI's reference frame.
+   */
+
+  boolean intersects(contactInterval ci, ColumnSelection columnSelection,
+          HiddenColumns hiddenColumns, boolean visibleOnly)
+  {
+    boolean rowsel = false;
+    final int[] mappedRange = contacts.getMappedPositionsFor(ci.cStart,
+            ci.cEnd);
+    if (mappedRange == null)
+    {
+      return false;
+    }
+    for (int p = 0; p < mappedRange.length && !rowsel; p += 2)
+    {
+      boolean containsHidden = false;
+      if (visibleOnly && hiddenColumns != null
+              && hiddenColumns.hasHiddenColumns())
+      {
+        // TODO: turn into function on hiddenColumns and create test !!
+        Iterator<int[]> viscont = hiddenColumns.getVisContigsIterator(
+                mappedRange[p], mappedRange[p + 1], false);
+        containsHidden = !viscont.hasNext();
+        if (!containsHidden)
+        {
+          for (int[] interval = viscont.next(); viscont
+                  .hasNext(); rowsel |= columnSelection
+                          .intersects(interval[p], interval[p + 1]))
+            ;
+        }
+      }
+      else
+      {
+        rowsel = columnSelection.intersects(mappedRange[p],
+                mappedRange[p + 1]);
+      }
+    }
+    return rowsel;
+
   }
 
   /**
index e54f471..0471145 100644 (file)
@@ -25,6 +25,7 @@ public abstract class ContactMapRenderer implements AnnotationRowRendererI
 {
   /**
    * bean holding colours for shading
+   * 
    * @author jprocter
    *
    */
@@ -66,6 +67,7 @@ public abstract class ContactMapRenderer implements AnnotationRowRendererI
 
   /**
    * build an EBI-AlphaFold style renderer of PAE matrices
+   * 
    * @return
    */
   public static ContactMapRenderer newPAERenderer()
@@ -100,19 +102,20 @@ public abstract class ContactMapRenderer implements AnnotationRowRendererI
           HiddenColumns hiddenColumns, ColumnSelection columnSelection,
           AlignmentAnnotation _aa, Annotation[] aa_annotations, int sRes,
           int eRes, float min, float max, int y)
-  {
+  {    
     if (sRes > aa_annotations.length)
     {
       return;
     }
     eRes = Math.min(eRes, aa_annotations.length);
 
-    int x = 0, y2 = y;
-
-    g.setColor(shade.no_data);
-
-    g.drawLine(x, y2, (eRes - sRes) * charWidth, y2);
+    int x = 0, topY = y;
 
+    // uncomment below to render whole area of matrix as pink
+    // g.setColor(shade.no_data);
+    // g.fillRect(x, topY-_aa.height, (eRes - sRes) * charWidth, _aa.graphHeight);
+    
+    boolean showGroups = _aa.isShowGroupsForContactMatrix();
     int column;
     int aaMax = aa_annotations.length - 1;
     ContactMatrixI cm = viewport.getContactMatrix(_aa);
@@ -146,21 +149,28 @@ public abstract class ContactMapRenderer implements AnnotationRowRendererI
         x++;
         continue;
       }
-      Color gpcol = (cm==null) ? Color.white: cm.getColourForGroup(cm.getGroupsFor(column));
+      // ContactListI from viewport can map column -> group
+      Color gpcol = (cm == null) ? Color.white
+              : contacts.getColourForGroup(); // cm.getColourForGroup(cm.getGroupsFor(column));
       // feature still in development - highlight or omit regions hidden in
       // the alignment - currently marks them as red rows
       boolean maskHiddenCols = false;
-      // TODO: pass visible column mask to the ContactGeometry object so it maps
+      // TODO: optionally pass visible column mask to the ContactGeometry object
+      // so it maps
       // only visible contacts to geometry
       // Bean holding mapping from contact list to pixels
+      // TODO: allow bracketing/limiting of range on contacts to render (like
+      // visible column mask but more flexible?)
+
+      // COntactListI provides mapping for column -> cm-groupmapping
       final ContactGeometry cgeom = new ContactGeometry(contacts,
               _aa.graphHeight);
 
-      for (int ht = y2, eht = y2
-              - _aa.graphHeight; ht >= eht; ht -= cgeom.pixels_step)
+      for (int ht = 0, botY = topY
+              - _aa.height; ht < _aa.graphHeight; ht += cgeom.pixels_step)
       {
-        ContactGeometry.contactInterval ci = cgeom.mapFor(y2 - ht,
-                y2 - ht + cgeom.pixels_step);
+        ContactGeometry.contactInterval ci = cgeom.mapFor(ht,
+                ht + cgeom.pixels_step);
         // cstart = (int) Math.floor(((double) y2 - ht) * contacts_per_pixel);
         // cend = (int) Math.min(contact_height,
         // Math.ceil(cstart + contacts_per_pixel * pixels_step));
@@ -169,29 +179,8 @@ public abstract class ContactMapRenderer implements AnnotationRowRendererI
         boolean rowsel = false, containsHidden = false;
         if (columnSelection != null)
         {
-          if (_aa.sequenceRef == null)
-          {
-            rowsel = columnSelection.intersects(ci.cStart, ci.cEnd);
-          }
-          else
-          {
-            // TODO check we have correctly mapped cstart to local sequence
-            // numbering
-            int s = _aa.sequenceRef.findIndex(ci.cStart);
-            int e = _aa.sequenceRef.findIndex(ci.cEnd);
-            if (maskHiddenCols && hasHiddenColumns)
-            {
-              // TODO: turn into function and create test !!
-              Iterator<int[]> viscont = hiddenColumns
-                      .getVisContigsIterator(s, e, false);
-              containsHidden = !viscont.hasNext();
-            }
-            if (s > 0 && s < _aa.sequenceRef.getLength())
-            {
-              rowsel = columnSelection.intersects(s, e);
-            }
-
-          }
+          rowsel = cgeom.intersects(ci, columnSelection, hiddenColumns,
+                  maskHiddenCols);
         }
         // TODO: show selected region
         if (colsel || rowsel)
@@ -216,21 +205,23 @@ public abstract class ContactMapRenderer implements AnnotationRowRendererI
         {
           col = shade.hidden;
         }
-        if (gpcol!=null && gpcol!=Color.white) {
+        if (showGroups && gpcol != null && gpcol != Color.white)
+        {
           // todo - could overlay group as a transparent rectangle ?
-          col = new Color((int)(((float)(col.getRed()+gpcol.getRed()))/2f),
-                  (int)(((float)(col.getGreen()+gpcol.getGreen()))/2f),
-                  (int)(((float)(col.getBlue()+gpcol.getBlue()))/2f));
+          col = new Color(
+                  (int) (((float) (col.getRed() + gpcol.getRed())) / 2f),
+                  (int) (((float) (col.getGreen() + gpcol.getGreen()))
+                          / 2f),
+                  (int) (((float) (col.getBlue() + gpcol.getBlue())) / 2f));
         }
         g.setColor(col);
-        
         if (cgeom.pixels_step > 1)
         {
-          g.fillRect(x * charWidth, ht, charWidth, 1 + cgeom.pixels_step);
+          g.fillRect(x * charWidth, botY+ht, charWidth, 1 + cgeom.pixels_step);
         }
         else
         {
-          g.drawLine(x * charWidth, ht, (x + 1) * charWidth, ht);
+          g.drawLine(x * charWidth, botY+ht, (x + 1) * charWidth, botY+ht);
         }
       }
       x++;
@@ -240,8 +231,8 @@ public abstract class ContactMapRenderer implements AnnotationRowRendererI
 
   Color shadeFor(float min, float max, float value)
   {
-    return jalview.util.ColorUtils.getGraduatedColour(value, 0, shade.minColor,
-            max, shade.maxColor);
+    return jalview.util.ColorUtils.getGraduatedColour(value, 0,
+            shade.minColor, max, shade.maxColor);
   }
 
   public Color getColorForRange(float min, float max, ContactListI cl,
index ef4d04b..4cbb1ba 100644 (file)
@@ -48,6 +48,7 @@ public class OverviewResColourFinder extends ResidueColourFinder
 
   /**
    * Constructor without colour settings (used by applet)
+   * 
    * @deprecated
    */
   @Deprecated
index bedbad5..0907228 100644 (file)
@@ -13,9 +13,8 @@ public interface AnnotationRowRendererI
 
   void renderRow(Graphics g, int charWidth, int charHeight,
           boolean hasHiddenColumns, AlignViewportI av,
-          HiddenColumns hiddenColumns,
-          ColumnSelection columnSelection, AlignmentAnnotation row,
-          Annotation[] row_annotations, int startRes, int endRes,
-          float graphMin, float graphMax, int y);
+          HiddenColumns hiddenColumns, ColumnSelection columnSelection,
+          AlignmentAnnotation row, Annotation[] row_annotations,
+          int startRes, int endRes, float graphMin, float graphMax, int y);
 
 }
index e66b7d5..2d16fcd 100644 (file)
@@ -543,7 +543,7 @@ public class FeatureRenderer extends FeatureRendererModel
        */
       List<SequenceFeature> overlaps = seq.findFeatures(column, column,
               type);
-      for (int i = overlaps.size() - 1 ; i >= 0 ; i--)
+      for (int i = overlaps.size() - 1; i >= 0; i--)
       {
         SequenceFeature sequenceFeature = overlaps.get(i);
         if (!featureGroupNotShown(sequenceFeature))
index a37882f..32672dd 100644 (file)
@@ -94,7 +94,7 @@ public class RestHandler extends AbstractRequestHandler
     final String reply = "REST not yet implemented; received "
             + request.getMethod() + ": " + request.getRequestURL()
             + (queryString == null ? "" : "?" + queryString);
-    System.out.println(reply);
+    jalview.bin.Console.outPrintln(reply);
 
     response.setHeader("Cache-Control", "no-cache/no-store");
     response.setHeader("Content-type", "text/plain");
index 061ccd4..f80669d 100644 (file)
@@ -117,7 +117,7 @@ public class ColourSchemeLoader
     } catch (Exception ex)
     {
       // used to try to parse a V1 Castor generated colours file
-      System.err.println("Failed to read colour scheme from " + filePath
+      jalview.bin.Console.errPrintln("Failed to read colour scheme from " + filePath
               + " : " + ex.toString());
     }
 
index 14daed6..e2a8cb3 100644 (file)
  */
 package jalview.schemes;
 
+import java.util.LinkedHashMap;
 import java.util.Locale;
+import java.util.Map;
 
 import jalview.api.AlignViewportI;
 import jalview.datamodel.AnnotatedCollectionI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
 
-import java.util.LinkedHashMap;
-import java.util.Map;
-
 public class ColourSchemes
 {
   /*
@@ -78,7 +77,7 @@ public class ColourSchemes
                 cs.getSchemeClass().getDeclaredConstructor().newInstance());
       } catch (InstantiationException | IllegalAccessException e)
       {
-        System.err.println("Error instantiating colour scheme for "
+        jalview.bin.Console.errPrintln("Error instantiating colour scheme for "
                 + cs.toString() + " " + e.getMessage());
         e.printStackTrace();
       } catch (ReflectiveOperationException roe)
@@ -98,7 +97,7 @@ public class ColourSchemes
     String name = cs.getSchemeName();
     if (name == null)
     {
-      System.err.println("ColourScheme name may not be null");
+      jalview.bin.Console.errPrintln("ColourScheme name may not be null");
       return;
     }
 
@@ -106,7 +105,7 @@ public class ColourSchemes
      * name is lower-case for non-case-sensitive lookup
      * (name in the colour keeps its true case)
      */
-    String lower = name.toLowerCase(Locale.ROOT);
+    String lower = getColourSchemeShortName(cs);
     if (schemes.containsKey(lower))
     {
       System.err
@@ -115,6 +114,19 @@ public class ColourSchemes
     schemes.put(lower, cs);
   }
 
+  private String getColourSchemeShortName(ColourSchemeI cs)
+  {
+    return getColourSchemeShortName(cs.getSchemeName());
+  }
+
+  private String getColourSchemeShortName(String name)
+  {
+    if (name == null)
+      return null;
+    return name.toLowerCase(Locale.ROOT).replaceAll("%", "pc")
+            .replaceAll("[^a-z0-9]", "-").replaceAll("--+", "-");
+  }
+
   /**
    * Removes a colour scheme by name
    * 
@@ -124,7 +136,7 @@ public class ColourSchemes
   {
     if (name != null)
     {
-      schemes.remove(name.toLowerCase(Locale.ROOT));
+      schemes.remove(getColourSchemeShortName(name));
     }
   }
 
@@ -150,7 +162,7 @@ public class ColourSchemes
     {
       return null;
     }
-    ColourSchemeI cs = schemes.get(name.toLowerCase(Locale.ROOT));
+    ColourSchemeI cs = schemes.get(getColourSchemeShortName(name));
     return cs == null ? null : cs.getInstance(viewport, forData);
   }
 
@@ -194,6 +206,6 @@ public class ColourSchemes
     {
       return false;
     }
-    return schemes.containsKey(name.toLowerCase(Locale.ROOT));
+    return schemes.containsKey(getColourSchemeShortName(name));
   }
 }
index 9d2c738..fe71d31 100755 (executable)
@@ -46,7 +46,7 @@ public class Consensus
     this.mask = setNums(s);
 
     // for (int i=0; i < mask.length; i++) {
-    // System.out.println(mask[i] + " " + ResidueProperties.aa[mask[i]]);
+    // jalview.bin.Console.outPrintln(mask[i] + " " + ResidueProperties.aa[mask[i]]);
     // }
   }
 
@@ -56,7 +56,7 @@ public class Consensus
   @Deprecated
   public boolean isConserved(int[][] cons2, int col, int size)
   {
-    System.out.println("DEPRECATED!!!!");
+    jalview.bin.Console.outPrintln("DEPRECATED!!!!");
     return isConserved(cons2, col, size, true);
   }
 
@@ -75,7 +75,7 @@ public class Consensus
 
     if (tot > ((threshold * size) / 100))
     {
-      // System.out.println("True conserved "+tot+" from "+threshold+" out of
+      // jalview.bin.Console.outPrintln("True conserved "+tot+" from "+threshold+" out of
       // "+size+" : "+maskstr);
       return true;
     }
index dc7971b..4884283 100644 (file)
@@ -65,9 +65,9 @@ public class CovariationColourScheme extends ResidueColourScheme
 
     for (int x = 0; x < this.annotation._rnasecstr.length; x++)
     {
-      // System.out.println(this.annotation._rnasecstr[x] + " Begin" +
+      // jalview.bin.Console.outPrintln(this.annotation._rnasecstr[x] + " Begin" +
       // this.annotation._rnasecstr[x].getBegin());
-      // System.out.println(this.annotation._rnasecstr[x].getFeatureGroup());
+      // jalview.bin.Console.outPrintln(this.annotation._rnasecstr[x].getFeatureGroup());
       // pairs.put(this.annotation._rnasecstr[x].getBegin(),
       // this.annotation._rnasecstr[x].getEnd());
 
@@ -104,7 +104,7 @@ public class CovariationColourScheme extends ResidueColourScheme
   @Override
   public Color findColour(char c)
   {
-    // System.out.println("called"); log.debug
+    // jalview.bin.Console.outPrintln("called"); log.debug
     // Generate a random pastel color
 
     return ResidueProperties.purinepyrimidine[ResidueProperties.purinepyrimidineIndex[c]];// jalview.util.ColorUtils.generateRandomColor(Color.white);
@@ -124,16 +124,16 @@ public class CovariationColourScheme extends ResidueColourScheme
   {
     Color currentColour = Color.white;
     String currentHelix = null;
-    // System.out.println(c + " " + j);
+    // jalview.bin.Console.outPrintln(c + " " + j);
     currentHelix = positionsToHelix.get(j);
-    // System.out.println(positionsToHelix.get(j));
+    // jalview.bin.Console.outPrintln(positionsToHelix.get(j));
 
     if (currentHelix != null)
     {
       currentColour = helixcolorhash.get(currentHelix);
     }
 
-    // System.out.println(c + " " + j + " helix " + currentHelix + " " +
+    // jalview.bin.Console.outPrintln(c + " " + j + " helix " + currentHelix + " " +
     // currentColour);
     return currentColour;
   }
index f1bade1..3d91b58 100644 (file)
@@ -395,7 +395,7 @@ public class FeatureColour implements FeatureColourI
         {
           if (!ttype.toLowerCase(Locale.ROOT).startsWith("no"))
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Ignoring unrecognised threshold type : " + ttype);
           }
         }
@@ -409,19 +409,19 @@ public class FeatureColour implements FeatureColourI
           featureColour.setThreshold(Float.valueOf(tval).floatValue());
         } catch (Exception e)
         {
-          System.err.println("Couldn't parse threshold value as a float: ("
+          jalview.bin.Console.errPrintln("Couldn't parse threshold value as a float: ("
                   + tval + ")");
         }
       }
       if (gcol.hasMoreTokens())
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Ignoring additional tokens in parameters in graduated colour specification\n");
         while (gcol.hasMoreTokens())
         {
-          System.err.println(BAR + gcol.nextToken());
+          jalview.bin.Console.errPrintln(BAR + gcol.nextToken());
         }
-        System.err.println("\n");
+        jalview.bin.Console.errPrintln("\n");
       }
       return featureColour;
     } catch (Exception e)
index accdc8a..da49fac 100644 (file)
@@ -34,10 +34,10 @@ public enum JalviewColourScheme
   PID("% Identity", PIDColourScheme.class),
   Zappo("Zappo", ZappoColourScheme.class),
   Taylor("Taylor", TaylorColourScheme.class),
-  Flower("gecos:flower", FlowerColourScheme.class),
-  Blossom("gecos:blossom", BlossomColourScheme.class),
-  Sunset("gecos:sunset", SunsetColourScheme.class),
-  Ocean("gecos:ocean", OceanColourScheme.class),
+  Flower("gecos-flower", FlowerColourScheme.class),
+  Blossom("gecos-blossom", BlossomColourScheme.class),
+  Sunset("gecos-sunset", SunsetColourScheme.class),
+  Ocean("gecos-ocean", OceanColourScheme.class),
   Hydrophobic("Hydrophobic", HydrophobicColourScheme.class),
   Helix("Helix Propensity", HelixColourScheme.class),
   Strand("Strand Propensity", StrandColourScheme.class),
index 33b275d..62b4579 100644 (file)
@@ -142,10 +142,10 @@ public class RNAHelicesColour extends ResidueColourScheme
       {
 
         /*
-         * System.out.println(this.annotation._rnasecstr[x] + " Begin" +
+         * jalview.bin.Console.outPrintln(this.annotation._rnasecstr[x] + " Begin" +
          * this.annotation._rnasecstr[x].getBegin());
          */
-        // System.out.println(this.annotation._rnasecstr[x].getFeatureGroup());
+        // jalview.bin.Console.outPrintln(this.annotation._rnasecstr[x].getFeatureGroup());
 
         positionsToHelix.put(this.annotation._rnasecstr[x].getBegin(),
                 this.annotation._rnasecstr[x].getFeatureGroup());
index 42d03ec..f8b7856 100755 (executable)
@@ -2414,7 +2414,7 @@ public class ResidueProperties
   public static void main(String[] args)
   {
     Hashtable<String, Vector<String>> aaProps = new Hashtable<>();
-    System.out.println("my %aa = {");
+    jalview.bin.Console.outPrintln("my %aa = {");
     // invert property hashes
     for (String pname : propHash.keySet())
     {
@@ -2446,12 +2446,12 @@ public class ResidueProperties
         System.out.print("'" + props.nextElement() + "'");
         if (props.hasMoreElements())
         {
-          System.out.println(", ");
+          jalview.bin.Console.outPrintln(", ");
         }
       }
-      System.out.println("]" + (res.hasMoreElements() ? "," : ""));
+      jalview.bin.Console.outPrintln("]" + (res.hasMoreElements() ? "," : ""));
     }
-    System.out.println("};");
+    jalview.bin.Console.outPrintln("};");
   }
 
   // to here
index d55ffbf..ec0f008 100755 (executable)
@@ -108,7 +108,7 @@ public class UserColourScheme extends ResidueColourScheme
 
     if (col == null)
     {
-      System.out.println("Making colour from name: " + colour);
+      jalview.bin.Console.outPrintln("Making colour from name: " + colour);
       col = ColorUtils.createColourFromName(colour);
     }
 
@@ -234,7 +234,7 @@ public class UserColourScheme extends ResidueColourScheme
       }
     } catch (Exception ex)
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "Error parsing userDefinedColours:\n" + token + "\n" + ex);
     }
 
index 3194cce..9bd247a 100644 (file)
@@ -155,16 +155,16 @@ public class StructureSelectionManager
   {
     if (mappings.isEmpty())
     {
-      System.err.println("reportMapping: No PDB/Sequence mappings.");
+      jalview.bin.Console.errPrintln("reportMapping: No PDB/Sequence mappings.");
     }
     else
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "reportMapping: There are " + mappings.size() + " mappings.");
       int i = 0;
       for (StructureMapping sm : mappings)
       {
-        System.err.println("mapping " + i++ + " : " + sm.pdbfile);
+        jalview.bin.Console.errPrintln("mapping " + i++ + " : " + sm.pdbfile);
       }
     }
   }
@@ -327,7 +327,7 @@ public class StructureSelectionManager
           IProgressIndicator progress)
   {
     return computeMapping(true, sequence, targetChains, pdbFile, protocol,
-            progress, null, null);
+            progress, null, null, true);
   }
 
   /**
@@ -353,8 +353,42 @@ public class StructureSelectionManager
           String pdbFile, DataSourceType sourceType, TFType tft,
           String paeFilename)
   {
+    return setMapping(forStructureView, sequenceArray, targetChainIds,
+            pdbFile, sourceType, tft, paeFilename, true);
+  }
+
+
+  /**
+   * create sequence structure mappings between each sequence and the given
+   * pdbFile (retrieved via the given protocol). Either constructs a mapping
+   * using NW alignment or derives one from any available SIFTS mapping data.
+   * 
+   * @param forStructureView
+   *          when true, record the mapping for use in mouseOvers
+   * 
+   * @param sequenceArray
+   *          - one or more sequences to be mapped to pdbFile
+   * @param targetChainIds
+   *          - optional chain specification for mapping each sequence to pdb
+   *          (may be nill, individual elements may be nill) - JBPNote: JAL-2693
+   *          - this should be List<List<String>>, empty lists indicate no
+   *          predefined mappings
+   * @param pdbFile
+   *          - structure data resource
+   * @param sourceType
+   *          - how to resolve data from resource
+   * @param tft - specify how to interpret the temperature factor column in the atom data
+   * @param paeFilename - when not null, specifies a filename containing a matrix formatted in JSON using one of the known PAE formats
+   * @param doXferSettings - when true, transfer annotation to mapped sequences in sequenceArray 
+   * @return null or the structure data parsed as a pdb file
+   */
+  synchronized public StructureFile setMapping(boolean forStructureView,
+          SequenceI[] sequenceArray, String[] targetChainIds,
+          String pdbFile, DataSourceType sourceType, TFType tft,
+          String paeFilename, boolean doXferSettings)
+  {
     return computeMapping(forStructureView, sequenceArray, targetChainIds,
-            pdbFile, sourceType, null, tft, paeFilename);
+            pdbFile, sourceType, null, tft, paeFilename, doXferSettings);
   }
 
   /**
@@ -379,12 +413,16 @@ public class StructureSelectionManager
    * @param IProgressIndicator
    *          reference to UI component that maintains a progress bar for the
    *          mapping operation
+   * @param tft - specify how to interpret the temperature factor column in the atom data
+   * @param paeFilename - when not null, specifies a filename containing a matrix formatted in JSON using one of the known PAE formats
+   * @param doXferSettings - when true, transfer annotation to mapped sequences in sequenceArray 
    * @return null or the structure data parsed as a pdb file
    */
   synchronized public StructureFile computeMapping(boolean forStructureView,
           SequenceI[] sequenceArray, String[] targetChainIds,
           String pdbFile, DataSourceType sourceType,
-          IProgressIndicator progress, TFType tft, String paeFilename)
+          IProgressIndicator progress, TFType tft, String paeFilename,
+          boolean doXferSettings)
   {
     long progressSessionId = System.currentTimeMillis() * 3;
 
@@ -394,8 +432,7 @@ public class StructureSelectionManager
     // FIXME: possibly should just delete
 
     boolean parseSecStr = processSecondaryStructure
-            ? isStructureFileProcessed(pdbFile, sequenceArray)
-            : false;
+            && !isStructureFileProcessed(pdbFile, sequenceArray);
 
     StructureFile pdb = null;
     boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
@@ -412,7 +449,11 @@ public class StructureSelectionManager
       pdb.addSettings(parseSecStr && processSecondaryStructure,
               parseSecStr && addTempFacAnnot,
               parseSecStr && secStructServices);
+      // save doXferSettings and reset after doParse()
+      boolean temp = pdb.getDoXferSettings();
+      pdb.setDoXferSettings(doXferSettings);
       pdb.doParse();
+      pdb.setDoXferSettings(temp);
       if (pdb.getId() != null && pdb.getId().trim().length() > 0
               && DataSourceType.FILE == sourceType)
       {
@@ -601,12 +642,12 @@ public class StructureSelectionManager
               chain.transferResidueAnnotation(siftsMapping, null);
             } catch (SiftsException e)
             {
-              System.err.println(e.getMessage());
+              jalview.bin.Console.errPrintln(e.getMessage());
             } catch (Exception e)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Unexpected exception during SIFTS mapping - falling back to NW for this sequence/structure pair");
-              System.err.println(e.getMessage());
+              jalview.bin.Console.errPrintln(e.getMessage());
             }
           }
           if (!foundSiftsMappings.isEmpty())
@@ -667,7 +708,7 @@ public class StructureSelectionManager
   private boolean isStructureFileProcessed(String pdbFile,
           SequenceI[] sequenceArray)
   {
-    boolean parseSecStr = true;
+    boolean processed = false;
     if (isPDBFileRegistered(pdbFile))
     {
       for (SequenceI sq : sequenceArray)
@@ -687,13 +728,13 @@ public class StructureSelectionManager
             // passed, not the structure data ID -
             if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
             {
-              parseSecStr = false;
+              processed = true;
             }
           }
         }
       }
     }
-    return parseSecStr;
+    return processed;
   }
 
   public void addStructureMapping(StructureMapping sm)
@@ -1238,7 +1279,7 @@ public class StructureSelectionManager
      * 
      * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
      * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
-     * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
+     * jalview.bin.Console.outPrintln(pdbid+" "+mappings[j].getPdbId() +"
      * "+mappings[j].pdbfile);
      * 
      * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
@@ -1335,7 +1376,7 @@ public class StructureSelectionManager
       boolean removed = seqmappings.remove(acf);
       if (removed && seqmappings.isEmpty())
       { // debug
-        System.out.println("All mappings removed");
+        jalview.bin.Console.outPrintln("All mappings removed");
       }
     }
   }
index 8436b48..9f15e55 100644 (file)
@@ -780,7 +780,7 @@ public abstract class AAStructureBindingModel
 
     if (waiting)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Timed out waiting for structure viewer to load file "
                       + notLoaded);
       return false;
@@ -973,7 +973,10 @@ public abstract class AAStructureBindingModel
       }
       List<StructureCommandI> finalView = commandGenerator
               .centerViewOn(models);
-      executeCommands(finalView, false, "Centered on Superposition");
+      if (finalView != null && finalView.size() > 0)
+      {
+        executeCommands(finalView, false, "Centered on Superposition");
+      }
     }
     return error;
   }
index 850a230..c298639 100644 (file)
@@ -99,7 +99,7 @@ public class IdentifiersUrlProvider extends UrlProviderImpl
       }
       else
       {
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "Unexpected key returned from identifiers jalview service");
         return idData;
       }
@@ -132,7 +132,7 @@ public class IdentifiersUrlProvider extends UrlProviderImpl
     // BH 2018 -- added more valuable report
     if (errorMessage != null)
     {
-      System.err.println("IdentifiersUrlProvider: cannot read " + idFileName
+      jalview.bin.Console.errPrintln("IdentifiersUrlProvider: cannot read " + idFileName
               + ": " + errorMessage);
     }
     return idData;
index 2cb0173..7d8e4e4 100644 (file)
@@ -84,7 +84,7 @@ public class UrlProvider implements UrlProviderI
       }
     }
 
-    System.out.println(
+    jalview.bin.Console.outPrintln(
             "Error initialising UrlProvider - no custom url provider");
     return null;
   }
index 9286794..f6145c2 100644 (file)
@@ -48,6 +48,8 @@ import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
 import java.io.PrintStream;
 
+import jalview.bin.Jalview;
+
 public class AWTConsole extends WindowAdapter
         implements WindowListener, ActionListener, Runnable
 {
@@ -136,20 +138,20 @@ public class AWTConsole extends WindowAdapter
     // testing part
     // you may omit this part for your application
     //
-    System.out.println("Hello World 2");
-    System.out.println("All fonts available to Graphic2D:\n");
+    jalview.bin.Console.outPrintln("Hello World 2");
+    jalview.bin.Console.outPrintln("All fonts available to Graphic2D:\n");
     GraphicsEnvironment ge = GraphicsEnvironment
             .getLocalGraphicsEnvironment();
     String[] fontNames = ge.getAvailableFontFamilyNames();
     for (int n = 0; n < fontNames.length; n++)
     {
-      System.out.println(fontNames[n]);
+      jalview.bin.Console.outPrintln(fontNames[n]);
     }
     // Testing part: simple an error thrown anywhere in this JVM will be printed
     // on the Console
     // We do it with a seperate Thread becasue we don't wan't to break a Thread
     // used by the Console.
-    System.out.println("\nLets throw an error on this console");
+    jalview.bin.Console.outPrintln("\nLets throw an error on this console");
     errorThrower = new Thread(this);
     errorThrower.setDaemon(true);
     errorThrower.start();
@@ -174,7 +176,7 @@ public class AWTConsole extends WindowAdapter
     } catch (Exception e)
     {
     }
-    System.exit(0);
+    Jalview.exit("Window closing. Bye!", 0);
   }
 
   @Override
index c05dac5..8142f8a 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.util;
 
+import java.util.Arrays;
+
 public class ArrayUtils
 {
   /**
@@ -44,4 +46,27 @@ public class ArrayUtils
       }
     }
   }
+
+  public static <T> T[] concatArrays(T[]... arrays)
+  {
+    if (arrays == null)
+      return null;
+    if (arrays.length == 1)
+      return arrays[0];
+
+    T[] result = arrays[0];
+    for (int i = 1; i < arrays.length; i++)
+    {
+      result = concatTwoArrays(result, arrays[i]);
+    }
+    return result;
+  }
+
+  private static <T> T[] concatTwoArrays(T[] array1, T[] array2)
+  {
+    T[] result = Arrays.copyOf(array1, array1.length + array2.length);
+    System.arraycopy(array2, 0, result, array1.length, array2.length);
+    return result;
+  }
+
 }
index 4832588..b0f25eb 100644 (file)
@@ -86,7 +86,7 @@ public class ChannelProperties
     if (channelPropsURL == null)
     {
       // complete failure of channel_properties, set all properties to defaults
-      System.err.println("Failed to find '/" + CHANNEL_PROPERTIES_FILENAME
+      jalview.bin.Console.errPrintln("Failed to find '/" + CHANNEL_PROPERTIES_FILENAME
               + "' file at '"
               + (channelPropsURL == null ? "null"
                       : channelPropsURL.toString())
@@ -102,7 +102,7 @@ public class ChannelProperties
         channelPropsIS.close();
       } catch (IOException e)
       {
-        System.err.println(e.getMessage());
+        jalview.bin.Console.errPrintln(e.getMessage());
         // return false;
       }
     }
@@ -157,10 +157,10 @@ public class ChannelProperties
         channelProps.load(is);
       } catch (FileNotFoundException e)
       {
-        System.err.println(e.getMessage());
+        jalview.bin.Console.errPrintln(e.getMessage());
       } catch (IOException e)
       {
-        System.err.println(e.getMessage());
+        jalview.bin.Console.errPrintln(e.getMessage());
       }
     }
   }
@@ -214,7 +214,7 @@ public class ChannelProperties
       }
       else
       {
-        System.err.println("Failed to get channel property '" + key + "'");
+        jalview.bin.Console.errPrintln("Failed to get channel property '" + key + "'");
       }
     }
     return null;
@@ -266,7 +266,7 @@ public class ChannelProperties
       img = imgIcon == null ? null : imgIcon.getImage();
       if (img == null)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Failed to load channel image " + key + "=" + path);
         if (!useClassDefaultImage)
         {
@@ -293,7 +293,7 @@ public class ChannelProperties
       {
         return urlMap().getOrDefault(key, null);
       }
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Do not use getImageURL(key) before using getImage(key...)");
     }
     return null;
index 6734735..b728c9d 100644 (file)
@@ -68,7 +68,18 @@ public class ColorUtils
     return color;
 
   }
+  
+  /**
+   * 
+   * @return random color
+   */
+  public static final Color getARandomColor()
+  {
 
+    Color col = new Color((int) (Math.random() * 255),
+            (int) (Math.random() * 255), (int) (Math.random() * 255));
+    return col;
+  }
   /**
    * Convert to Tk colour code format
    * 
index 9fea705..e9ff931 100644 (file)
@@ -337,9 +337,9 @@ public class Comparison
         // a long sequence.
         // check for at least 55% nucleotide, and nucleotide and ambiguity codes
         // (including N) must make up 95%
-        return ntCount * 100 > NUCLEOTIDE_COUNT_PERCENT * allCount
+        return ntCount * 100 >= NUCLEOTIDE_COUNT_PERCENT * allCount
                 && 100 * (ntCount + nCount
-                        + ntaCount) > NUCLEOTIDE_COUNT_LONG_SEQUENCE_AMBIGUITY_PERCENT
+                        + ntaCount) >= NUCLEOTIDE_COUNT_LONG_SEQUENCE_AMBIGUITY_PERCENT
                                 * allCount;
       }
       else if (allCount > NUCLEOTIDE_COUNT_VERY_SHORT_SEQUENCE)
@@ -347,7 +347,7 @@ public class Comparison
         // a short sequence.
         // check if a short sequence is at least 55% nucleotide and the rest of
         // the symbols are all X or all N
-        if (ntCount * 100 > NUCLEOTIDE_COUNT_PERCENT * allCount
+        if (ntCount * 100 >= NUCLEOTIDE_COUNT_PERCENT * allCount
                 && (nCount == aaCount || xCount == aaCount))
         {
           return true;
index 98d5e11..a101d82 100755 (executable)
@@ -406,7 +406,7 @@ public class DBRefUtils
         }
         else
         {
-          System.err.println("Malformed PDB DR line:" + acn);
+          jalview.bin.Console.errPrintln("Malformed PDB DR line:" + acn);
         }
       }
       else
diff --git a/src/jalview/util/FileUtils.java b/src/jalview/util/FileUtils.java
new file mode 100644 (file)
index 0000000..e62a7d6
--- /dev/null
@@ -0,0 +1,192 @@
+package jalview.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import jalview.bin.Console;
+
+public class FileUtils
+{
+  /*
+   * Given string glob pattern (see
+   * https://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)
+   * ) return a List of Files that match the pattern.
+   * Note this is a java style glob, not necessarily a bash-style glob, though there are sufficient similarities. 
+   */
+  public static List<File> getFilesFromGlob(String pattern)
+  {
+    return getFilesFromGlob(pattern, true);
+  }
+
+  public static List<File> getFilesFromGlob(String pattern,
+          boolean allowSingleFilenameThatDoesNotExist)
+  {
+    pattern = substituteHomeDir(pattern);
+    List<File> files = new ArrayList<>();
+    /*
+     * For efficiency of the Files.walkFileTree(), let's find the longest path that doesn't need globbing.
+     * We look for the first glob character * { ? and then look for the last File.separator before that.
+     * Then we can reset the path to look at and shorten the globbing pattern.
+     * Relative paths can be used in pattern, which work from the pwd (though these are converted into
+     * full paths in the match). 
+     */
+    int firstGlobChar = -1;
+    boolean foundGlobChar = false;
+    for (char c : new char[] { '*', '{', '?' })
+    {
+      if (pattern.indexOf(c) > -1
+              && (pattern.indexOf(c) < firstGlobChar || !foundGlobChar))
+      {
+        firstGlobChar = pattern.indexOf(c);
+        foundGlobChar = true;
+      }
+    }
+    int lastFS = pattern.lastIndexOf(File.separatorChar, firstGlobChar);
+    if (foundGlobChar)
+    {
+      String pS = pattern.substring(0, lastFS + 1);
+      String rest = pattern.substring(lastFS + 1);
+      Path parentDir = Paths.get(pS).toAbsolutePath();
+      if (parentDir.toFile().exists())
+      {
+        try
+        {
+          String glob = "glob:" + parentDir.toString() + File.separator
+                  + rest;
+          PathMatcher pm = FileSystems.getDefault().getPathMatcher(glob);
+          int maxDepth = rest.contains("**") ? 1028
+                  : (int) (rest.chars()
+                          .filter(ch -> ch == File.separatorChar).count())
+                          + 1;
+
+          Files.walkFileTree(parentDir,
+                  EnumSet.of(FileVisitOption.FOLLOW_LINKS), maxDepth,
+                  new SimpleFileVisitor<Path>()
+                  {
+                    @Override
+                    public FileVisitResult visitFile(Path path,
+                            BasicFileAttributes attrs) throws IOException
+                    {
+                      if (pm.matches(path))
+                      {
+                        files.add(path.toFile());
+                      }
+                      return FileVisitResult.CONTINUE;
+                    }
+
+                    @Override
+                    public FileVisitResult visitFileFailed(Path file,
+                            IOException exc) throws IOException
+                    {
+                      return FileVisitResult.CONTINUE;
+                    }
+                  });
+        } catch (IOException e)
+        {
+          e.printStackTrace();
+        }
+      }
+    }
+    else
+    {
+      // no wildcards
+      File f = new File(pattern);
+      if (allowSingleFilenameThatDoesNotExist || f.exists())
+      {
+        files.add(f);
+      }
+    }
+    Collections.sort(files);
+
+    return files;
+  }
+
+  public static List<String> getFilenamesFromGlob(String pattern)
+  {
+    // convert list of Files to list of File.getPath() Strings
+    return getFilesFromGlob(pattern).stream().map(f -> f.getPath())
+            .collect(Collectors.toList());
+  }
+
+  public static String substituteHomeDir(String path)
+  {
+    return path.startsWith("~" + File.separator)
+            ? System.getProperty("user.home") + path.substring(1)
+            : path;
+  }
+
+  /*
+   * This method returns the basename of File file
+   */
+  public static String getBasename(File file)
+  {
+    return getBasenameOrExtension(file, false);
+  }
+
+  /*
+   * This method returns the extension of File file.
+   */
+  public static String getExtension(File file)
+  {
+    return getBasenameOrExtension(file, true);
+  }
+
+  public static String getBasenameOrExtension(File file, boolean extension)
+  {
+    if (file == null)
+      return null;
+
+    String value = null;
+    String filename = file.getName();
+    int lastDot = filename.lastIndexOf('.');
+    if (lastDot > 0) // don't truncate if starts with '.'
+    {
+      value = extension ? filename.substring(lastDot + 1)
+              : filename.substring(0, lastDot);
+    }
+    else
+    {
+      value = extension ? "" : filename;
+    }
+    return value;
+  }
+
+  /*
+   * This method returns the dirname of the first --append or --open value. 
+   * Used primarily for substitutions in output filenames.
+   */
+  public static String getDirname(File file)
+  {
+    if (file == null)
+      return null;
+
+    String dirname = null;
+    try
+    {
+      File p = file.getParentFile();
+      File d = new File(substituteHomeDir(p.getPath()));
+      dirname = d.getCanonicalPath();
+    } catch (IOException e)
+    {
+      Console.debug(
+              "Exception when getting dirname of '" + file.getPath() + "'",
+              e);
+      dirname = "";
+    }
+    return dirname;
+  }
+}
index 67309a0..bd375bb 100644 (file)
@@ -585,7 +585,7 @@ public class GroupUrlLink
               // debug
               /*
                * for (int s = 0; s <= rg.numSubs(); s++) {
-               * System.err.println("Sub " + s + " : " + rg.matchedFrom(s) +
+               * jalview.bin.Console.errPrintln("Sub " + s + " : " + rg.matchedFrom(s) +
                * " : " + rg.matchedTo(s) + " : '" + rg.stringMatched(s) + "'");
                * }
                */
@@ -787,32 +787,32 @@ public class GroupUrlLink
 
     if (url == null)
     {
-      System.out.println("Created NO urls.");
+      jalview.bin.Console.outPrintln("Created NO urls.");
     }
     else
     {
-      System.out.println("Created a url from " + ((int[]) url[0])[0]
+      jalview.bin.Console.outPrintln("Created a url from " + ((int[]) url[0])[0]
               + "out of " + idstring[0].length + " sequences.");
-      System.out.println("Sequences that did not match:");
+      jalview.bin.Console.outPrintln("Sequences that did not match:");
       for (int sq = 0; sq < idstring[0].length; sq++)
       {
         if (!((boolean[]) url[1])[sq])
         {
-          System.out.println("Seq " + sq + ": " + idstring[0][sq] + "\t: "
+          jalview.bin.Console.outPrintln("Seq " + sq + ": " + idstring[0][sq] + "\t: "
                   + idstring[1][sq]);
         }
       }
-      System.out.println("Sequences that DID match:");
+      jalview.bin.Console.outPrintln("Sequences that DID match:");
       for (int sq = 0; sq < idstring[0].length; sq++)
       {
         if (((boolean[]) url[1])[sq])
         {
-          System.out.println("Seq " + sq + ": " + idstring[0][sq] + "\t: "
+          jalview.bin.Console.outPrintln("Seq " + sq + ": " + idstring[0][sq] + "\t: "
                   + idstring[1][sq]);
         }
       }
-      System.out.println("The generated URL:");
-      System.out.println(((String[]) url[3])[0]);
+      jalview.bin.Console.outPrintln("The generated URL:");
+      jalview.bin.Console.outPrintln(((String[]) url[3])[0]);
     }
   }
 
@@ -849,15 +849,15 @@ public class GroupUrlLink
       GroupUrlLink ul = new GroupUrlLink(links[i]);
       if (ul.isValid())
       {
-        System.out.println("\n\n\n");
-        System.out.println(
+        jalview.bin.Console.outPrintln("\n\n\n");
+        jalview.bin.Console.outPrintln(
                 "Link " + i + " " + links[i] + " : " + ul.toString());
-        System.out.println(" pref : " + ul.getUrl_prefix());
-        System.out.println(" IdReplace : " + ul.getIDRegexReplace());
-        System.out.println(" SeqReplace : " + ul.getSeqRegexReplace());
-        System.out.println(" Suffixes : " + ul.getUrl_suffix());
+        jalview.bin.Console.outPrintln(" pref : " + ul.getUrl_prefix());
+        jalview.bin.Console.outPrintln(" IdReplace : " + ul.getIDRegexReplace());
+        jalview.bin.Console.outPrintln(" SeqReplace : " + ul.getSeqRegexReplace());
+        jalview.bin.Console.outPrintln(" Suffixes : " + ul.getUrl_suffix());
 
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "<insert input id and sequence strings here> Without onlyIfMatches:");
         Object[] urls;
         try
@@ -867,9 +867,9 @@ public class GroupUrlLink
           testUrls(ul, seqsandids, urls);
         } catch (UrlStringTooLongException ex)
         {
-          System.out.println("too long exception " + ex);
+          jalview.bin.Console.outPrintln("too long exception " + ex);
         }
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "<insert input id and sequence strings here> With onlyIfMatches set:");
         try
         {
@@ -878,12 +878,12 @@ public class GroupUrlLink
           testUrls(ul, seqsandids, urls);
         } catch (UrlStringTooLongException ex)
         {
-          System.out.println("too long exception " + ex);
+          jalview.bin.Console.outPrintln("too long exception " + ex);
         }
       }
       else
       {
-        System.err.println("Invalid URLLink : " + links[i] + " : "
+        jalview.bin.Console.errPrintln("Invalid URLLink : " + links[i] + " : "
                 + ul.getInvalidMessage());
       }
     }
index 0454cab..5438d4e 100644 (file)
@@ -25,10 +25,11 @@ import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.ProtocolException;
 import java.net.URL;
-import java.util.List;
 
 import javax.ws.rs.HttpMethod;
 
+import jalview.bin.Cache;
+
 public class HttpUtils
 {
 
@@ -87,7 +88,7 @@ public class HttpUtils
   public static boolean checkUrlAvailable(URL url, int readTimeout)
           throws IOException, ProtocolException
   {
-    // System.out.println(System.currentTimeMillis() + " " + url);
+    // jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url);
 
     HttpURLConnection connection = (HttpURLConnection) url.openConnection();
 
@@ -101,4 +102,46 @@ public class HttpUtils
     return connection.getResponseCode() == 200;
   }
 
+  public static String getUserAgent()
+  {
+    return getUserAgent(null);
+  }
+
+  public static String getUserAgent(String className)
+  {
+    StringBuilder sb = new StringBuilder();
+    sb.append("Jalview");
+    sb.append('/');
+    sb.append(Cache.getDefault("VERSION", "Unknown"));
+    sb.append(" (");
+    sb.append(System.getProperty("os.name"));
+    sb.append("; ");
+    sb.append(System.getProperty("os.arch"));
+    sb.append(' ');
+    sb.append(System.getProperty("os.name"));
+    sb.append(' ');
+    sb.append(System.getProperty("os.version"));
+    sb.append("; ");
+    sb.append("java/");
+    sb.append(System.getProperty("java.version"));
+    sb.append("; ");
+    sb.append("jalview/");
+    sb.append(ChannelProperties.getProperty("channel"));
+    if (className != null)
+    {
+      sb.append("; ");
+      sb.append(className);
+    }
+    String installation = Cache.applicationProperties
+            .getProperty("INSTALLATION");
+    if (installation != null)
+    {
+      sb.append("; ");
+      sb.append(installation);
+    }
+    sb.append(')');
+    sb.append(" help@jalview.org");
+    return sb.toString();
+  }
+
 }
index 0cd017f..3306b0d 100755 (executable)
@@ -20,8 +20,6 @@
  */
 package jalview.util;
 
-import jalview.io.JalviewFileChooser;
-
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.RenderingHints;
@@ -36,6 +34,10 @@ import org.jfree.graphics2d.svg.SVGGraphics2D;
 import org.jfree.graphics2d.svg.SVGHints;
 import org.jibble.epsgraphics.EpsGraphics2D;
 
+import jalview.bin.Console;
+import jalview.io.JalviewFileChooser;
+import jalview.util.imagemaker.BitmapImageSizing;
+
 public class ImageMaker
 {
   public static final String SVG_DESCRIPTION = "Scalable Vector Graphics";
@@ -110,10 +112,12 @@ public class ImageMaker
    * @param file
    * @param fileTitle
    * @param useLineart
+   * @param bitmapscale
    * @throws IOException
    */
   public ImageMaker(TYPE imageType, int width, int height, File file,
-          String fileTitle, boolean useLineart) throws IOException
+          String fileTitle, boolean useLineart, BitmapImageSizing userBis)
+          throws IOException
   {
     this.type = imageType;
 
@@ -127,7 +131,7 @@ public class ImageMaker
       setupEPS(width, height, fileTitle, useLineart);
       break;
     case PNG:
-      setupPNG(width, height);
+      setupPNG(width, height, userBis);
       break;
     default:
     }
@@ -176,14 +180,28 @@ public class ImageMaker
    * 
    * @param width
    * @param height
+   * @param scale
    */
-  protected void setupPNG(int width, int height)
+  protected void setupPNG(int width, int height, BitmapImageSizing userBis)
   {
-    bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+    if (width == 0 || height == 0)
+      return;
+
+    BitmapImageSizing bis = ImageMaker.getScaleWidthHeight(width, height,
+            userBis);
+    float usescale = bis.scale;
+    int usewidth = bis.width;
+    int useheight = bis.height;
+
+    bi = new BufferedImage(usewidth, useheight, BufferedImage.TYPE_INT_RGB);
     graphics = bi.getGraphics();
     Graphics2D ig2 = (Graphics2D) graphics;
     ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
             RenderingHints.VALUE_ANTIALIAS_ON);
+    if (usescale > 0.0f)
+    {
+      ig2.scale(usescale, usescale);
+    }
   }
 
   /**
@@ -227,4 +245,120 @@ public class ImageMaker
     pg.setAccurateTextMode(useLineart);
     graphics = pg;
   }
+
+  /**
+   * Takes suggested float scale, int width, int height and create a bounding
+   * box returned as a BitmapImageSizing object with consistent scale, width,
+   * height fields.
+   * 
+   * @param scale
+   * @param bitmapwidth
+   * @param bitmapheight
+   * @return BitmapImageSizing
+   */
+  public static BitmapImageSizing getScaleWidthHeight(int width, int height,
+          float scale, int bitmapwidth, int bitmapheight)
+  {
+    float usescale = 0.0f;
+    int usewidth = width;
+    int useheight = height;
+
+    // use the smallest positive scale (i.e. fit in the box)
+    if (scale > 0.0f)
+    {
+      usescale = scale;
+      usewidth = Math.round(scale * width);
+      useheight = Math.round(scale * height);
+    }
+    if (bitmapwidth > 0)
+    {
+      float wscale = (float) bitmapwidth / width;
+      if (wscale > 0.0f && (usescale == 0.0f || wscale < usescale))
+      {
+        usescale = wscale;
+        usewidth = bitmapwidth;
+        useheight = Math.round(usescale * height);
+      }
+    }
+    if (bitmapheight > 0)
+    {
+      float hscale = (float) bitmapheight / height;
+      if (hscale > 0.0f && (usescale == 0.0f || hscale < usescale))
+      {
+        usescale = hscale;
+        usewidth = Math.round(usescale * width);
+        useheight = bitmapheight;
+      }
+    }
+    return new BitmapImageSizing(usescale, usewidth, useheight);
+  }
+
+  /**
+   * Takes suggested scale, width, height as a BitmapImageSizing object and
+   * create a bounding box returned as a BitmapImageSizing object with
+   * consistent scale, width, height fields.
+   * 
+   * @param bis
+   * @return BitmapImageSizing
+   */
+  public static BitmapImageSizing getScaleWidthHeight(int width, int height,
+          BitmapImageSizing bis)
+  {
+    return ImageMaker.getScaleWidthHeight(width, height, bis.scale,
+            bis.width, bis.height);
+  }
+
+  /**
+   * Takes String versions of suggested float scale, int width, int height and
+   * create a bounding box returned as a BitmapImageSizing object with
+   * consistent scale, width, height fields.
+   * 
+   * @param scaleS
+   * @param widthS
+   * @param heightS
+   * @return BitmapImageSizing
+   */
+  public static BitmapImageSizing parseScaleWidthHeightStrings(
+          String scaleS, String widthS, String heightS)
+  {
+    float scale = 0.0f;
+    int width = 0;
+    int height = 0;
+
+    if (scaleS != null)
+    {
+      try
+      {
+        scale = Float.parseFloat(scaleS);
+      } catch (NumberFormatException e)
+      {
+        Console.warn("Did not understand scale '" + scaleS
+                + "', won't be used.");
+      }
+    }
+    if (widthS != null)
+    {
+      try
+      {
+        width = Integer.parseInt(widthS);
+      } catch (NumberFormatException e)
+      {
+        Console.warn("Did not understand width '" + widthS
+                + "', won't be used.");
+      }
+    }
+    if (heightS != null)
+    {
+      try
+      {
+        height = Integer.parseInt(heightS);
+      } catch (NumberFormatException e)
+      {
+        Console.warn("Did not understand height '" + heightS
+                + "', won't be used.");
+      }
+    }
+
+    return new BitmapImageSizing(scale, width, height);
+  }
 }
index 5bd4a08..e4f393c 100644 (file)
@@ -29,9 +29,21 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Properties;
 
+import jalview.bin.Console;
+
 public class LaunchUtils
 {
 
+  // setting these is LaunchUtils so don't need to import Platform
+  public final static boolean isMac = System.getProperty("os.name")
+          .indexOf("Mac") > -1;
+
+  public final static boolean isWindows = System.getProperty("os.name")
+          .indexOf("Win") > -1;
+
+  private static boolean isJS = /** @j2sNative true || */
+          false;
+
   public static void loadChannelProps(File dir)
   {
     ChannelProperties.loadProps(dir);
@@ -65,7 +77,7 @@ public class LaunchUtils
         return null;
       } catch (IOException e)
       {
-        System.err.println(e.getMessage());
+        jalview.bin.Console.errPrintln(e.getMessage());
         return null;
       }
     }
@@ -81,7 +93,7 @@ public class LaunchUtils
 
   public static int getJavaCompileVersion()
   {
-    if (Platform.isJS())
+    if (LaunchUtils.isJS)
     {
       return -1;
     }
@@ -103,22 +115,22 @@ public class LaunchUtils
               null);
       if (JCV == null)
       {
-        System.out.println(
+        Console.errPrintln(
                 "Could not obtain JAVA_COMPILE_VERSION for comparison");
         return -2;
       }
       JAVA_COMPILE_VERSION = Integer.parseInt(JCV);
     } catch (MalformedURLException e)
     {
-      System.err.println("Could not find " + buildDetails);
+      jalview.bin.Console.errPrintln("Could not find " + buildDetails);
       return -3;
     } catch (IOException e)
     {
-      System.err.println("Could not load " + buildDetails);
+      jalview.bin.Console.errPrintln("Could not load " + buildDetails);
       return -4;
     } catch (NumberFormatException e)
     {
-      System.err.println("Could not parse JAVA_COMPILE_VERSION");
+      jalview.bin.Console.errPrintln("Could not parse JAVA_COMPILE_VERSION");
       return -5;
     }
 
@@ -129,7 +141,7 @@ public class LaunchUtils
 
   public static int getJavaVersion()
   {
-    if (Platform.isJS())
+    if (LaunchUtils.isJS)
     {
       return -1;
     }
@@ -142,7 +154,7 @@ public class LaunchUtils
       String JV = System.getProperty("java.version");
       if (JV == null)
       {
-        System.out.println("Could not obtain java.version for comparison");
+        Console.errPrintln("Could not obtain java.version for comparison");
         return -2;
       }
       if (JV.startsWith("1."))
@@ -153,7 +165,7 @@ public class LaunchUtils
               : Integer.parseInt(JV.substring(0, JV.indexOf(".")));
     } catch (NumberFormatException e)
     {
-      System.err.println("Could not parse java.version");
+      jalview.bin.Console.errPrintln("Could not parse java.version");
       return -3;
     }
     return JAVA_VERSION;
@@ -161,7 +173,7 @@ public class LaunchUtils
 
   public static boolean checkJavaVersion()
   {
-    if (Platform.isJS())
+    if (LaunchUtils.isJS)
     {
       return true;
     }
@@ -174,7 +186,7 @@ public class LaunchUtils
 
     if (java_compile_version <= 0 || java_version <= 0)
     {
-      System.out.println("Could not make Java version check");
+      Console.errPrintln("Could not make Java version check");
       return true;
     }
     // Warn if these java.version and JAVA_COMPILE_VERSION conditions exist
@@ -186,4 +198,88 @@ public class LaunchUtils
 
     return true;
   }
+
+  public static String findJavaBin(boolean winConsole)
+  {
+    return findJavaBin(System.getProperty("java.home"), winConsole, true);
+  }
+
+  /*
+   * Returns a string path to the most likely java binary wanted to run this
+   * installation of Jalview.
+   * 
+   * @param  winConsole  whether to use java.exe (console) in preference to javaw.exe
+   *                     (only affects Windows).
+   * @param  javaHome    Try this javaHome dir (defaults to the running java.home).
+   * @param  generic     Return a generic java command if not found.
+   */
+  public static String findJavaBin(String javaHome, boolean winConsole,
+          boolean generic)
+  {
+    String javaBin = null;
+    final String javaExe = winConsole ? "java.exe" : "javaw.exe";
+    final String java = "java";
+
+    if (javaHome != null)
+    {
+      // property "channel.app_name" is set by install4j when launching getdown
+      String propertyAppName = System.getProperty("channel.app_name");
+      final String appName = (propertyAppName != null
+              && propertyAppName.length() > 0) ? propertyAppName
+                      : ChannelProperties.getProperty("app_name");
+
+      final String javaBinDir = javaHome + File.separator + "bin"
+              + File.separator;
+
+      // appName and "Jalview" will not point to javaw.exe or java.exe but in
+      // this case that's okay because the taskbar display name problem doesn't
+      // manifest in Windows. See JAL-3820, JAL-4189.
+      for (String name : new String[] { appName, "Jalview", java, javaExe })
+      {
+        if (LaunchUtils.checkJVMSymlink(javaBinDir + name, winConsole))
+        {
+          javaBin = javaBinDir + name;
+          break;
+        }
+      }
+    }
+
+    if (javaBin == null && generic)
+    {
+      javaBin = LaunchUtils.isWindows ? javaExe : java;
+    }
+
+    return javaBin;
+  }
+
+  /*
+   * checkJVMSymlink returns true if the path in testBin *is* a java binary, or
+   * points to a java binary.
+   * @param  testBin     The binary or symbolic link to check
+   * @param  winConsole  whether we are in/want a Windows console (only relevant for Windows,
+   *                     determines whether we use java.exe or javaw.exe)
+   */
+  private static boolean checkJVMSymlink(String testBin, boolean winConsole)
+  {
+    File testBinFile = new File(testBin);
+    if (!testBinFile.exists())
+    {
+      return false;
+    }
+    File targetFile = null;
+    try
+    {
+      targetFile = testBinFile.getCanonicalFile();
+    } catch (IOException e)
+    {
+      return false;
+    }
+    final String javaExe = winConsole ? "java.exe" : "javaw.exe";
+    if (targetFile != null && ("java".equals(targetFile.getName())
+            || javaExe.equals(targetFile.getName())))
+    {
+      return true;
+    }
+    return false;
+  }
 }
index 60eef4c..de8f719 100644 (file)
@@ -96,7 +96,7 @@ public class Log4j
       init = true;
     } catch (Exception e)
     {
-      System.err.println("Problems initializing the log4j system\n");
+      jalview.bin.Console.errPrintln("Problems initializing the log4j system\n");
       e.printStackTrace(System.err);
     }
   }
index 573e2d5..4ecf637 100644 (file)
@@ -20,8 +20,6 @@
  */
 package jalview.util;
 
-import jalview.javascript.json.JSON;
-
 import java.awt.Toolkit;
 import java.awt.event.MouseEvent;
 import java.io.BufferedReader;
@@ -40,6 +38,8 @@ import javax.swing.SwingUtilities;
 import org.json.simple.parser.JSONParser;
 import org.json.simple.parser.ParseException;
 
+import jalview.javascript.json.JSON;
+
 /**
  * System platform information used by Applet and Application
  * 
@@ -56,6 +56,27 @@ public class Platform
 
   private static Boolean isHeadless = null;
 
+  // If launched from CLI with launcher script then -DCOLUMNWIDTH is set
+  private static final int CONSOLEWIDTH;
+
+  private static final String CONSOLEWIDTHPROPERTY = "CONSOLEWIDTH";
+
+  static
+  {
+    int cw = 80;
+    if (System.getProperty(CONSOLEWIDTHPROPERTY) != null
+            && System.getProperty(CONSOLEWIDTHPROPERTY).length() > 0)
+    {
+      try
+      {
+        cw = Integer.parseInt(System.getProperty(CONSOLEWIDTHPROPERTY));
+      } catch (NumberFormatException e)
+      {
+      }
+    }
+    CONSOLEWIDTH = cw;
+  }
+
   /**
    * added to group mouse events into Windows and nonWindows (mac, unix, linux)
    * 
@@ -288,7 +309,7 @@ public class Platform
       time = mark = t;
       if (msg != null)
       {
-        System.err.println("Platform: timer reset\t\t\t" + msg);
+        jalview.bin.Console.errPrintln("Platform: timer reset\t\t\t" + msg);
       }
       break;
     case TIME_MARK:
@@ -304,7 +325,7 @@ public class Platform
         }
         if (msg != null)
         {
-          System.err.println("Platform: timer mark\t" + ((t - time) / 1000f)
+          jalview.bin.Console.errPrintln("Platform: timer mark\t" + ((t - time) / 1000f)
                   + "\t" + ((t - mark) / 1000f) + "\t" + msg);
         }
         mark = t;
@@ -316,7 +337,7 @@ public class Platform
     case TIME_GET:
       if (msg != null)
       {
-        System.err.println("Platform: timer dur\t" + ((t - time) / 1000f)
+        jalview.bin.Console.errPrintln("Platform: timer dur\t" + ((t - time) / 1000f)
                 + "\t" + ((duration) / 1000f) + "\t" + msg);
       }
       set = 0;
@@ -473,7 +494,7 @@ public class Platform
      *            info[key];
      */
 
-    System.out.println(
+    jalview.bin.Console.outPrintln(
             "Platform id=" + id + " reading Info." + key + " = " + value);
     p.put(id + "_" + key, value);
 
@@ -599,7 +620,7 @@ public class Platform
 
     if (isJS())
     {
-      System.out.println(
+      jalview.bin.Console.outPrintln(
               "Platform adding known access-control-allow-origin * for domain "
                       + domain);
       /**
@@ -623,11 +644,11 @@ public class Platform
        * @j2sNative var a =
        *            decodeURI((document.location.href.replace("&","?").split("?j2s")[0]
        *            + "?").split("?")[1].split("#")[0]); a &&
-       *            (System.out.println("URL arguments detected were "+a)) &&
+       *            (jalview.bin.Console.outPrintln("URL arguments detected were "+a)) &&
        *            (J2S.thisApplet.__Info.urlargs = a.split(" "));
        *            (!J2S.thisApplet.__Info.args || J2S.thisApplet.__Info.args
        *            == "" || J2S.thisApplet.__Info.args == "??") &&
-       *            (J2S.thisApplet.__Info.args = a) && (System.out.println("URL
+       *            (J2S.thisApplet.__Info.args = a) && (jalview.bin.Console.outPrintln("URL
        *            arguments were passed to J2S main."));
        */
     } catch (Throwable t)
@@ -657,4 +678,12 @@ public class Platform
     String p2 = path2.replace('\\', '/');
     return p1.equals(p2);
   }
+
+  /**
+   * If started on command line using launch script, return the console width
+   */
+  public static int consoleWidth()
+  {
+    return CONSOLEWIDTH;
+  }
 }
index 7e1b8ad..89bc36d 100644 (file)
@@ -202,18 +202,18 @@ public class StringUtils
       jv.clear();
       if (DEBUG)
       {
-        System.err.println("Array from '" + delimiter
+        jalview.bin.Console.errPrintln("Array from '" + delimiter
                 + "' separated List:\n" + v.length);
         for (int i = 0; i < v.length; i++)
         {
-          System.err.println("item " + i + " '" + v[i] + "'");
+          jalview.bin.Console.errPrintln("item " + i + " '" + v[i] + "'");
         }
       }
       return v;
     }
     if (DEBUG)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Empty Array from '" + delimiter + "' separated List");
     }
     return null;
@@ -249,13 +249,13 @@ public class StringUtils
       {
         System.err
                 .println("Returning '" + separator + "' separated List:\n");
-        System.err.println(v);
+        jalview.bin.Console.errPrintln(v);
       }
       return v.toString();
     }
     if (DEBUG)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Returning empty '" + separator + "' separated List\n");
     }
     return "" + separator;
@@ -586,6 +586,15 @@ public class StringUtils
     return min < text.length() + 1 ? min : -1;
   }
 
+  public static boolean equalsIgnoreCase(String s1, String s2)
+  {
+    if (s1 == null || s2 == null)
+    {
+      return s1 == s2;
+    }
+    return s1.toLowerCase(Locale.ROOT).equals(s2.toLowerCase(Locale.ROOT));
+  }
+
   public static int indexOfFirstWhitespace(String text)
   {
     int index = -1;
@@ -600,6 +609,7 @@ public class StringUtils
 
   /*
    * implementation of String.replaceLast.
+   * Replaces only the last occurrence of toReplace in string with replacement.
    */
   public static String replaceLast(String string, String toReplace,
           String replacement)
@@ -607,13 +617,31 @@ public class StringUtils
     int pos = string.lastIndexOf(toReplace);
     if (pos > -1)
     {
-      return string.substring(0, pos) + replacement
-              + string.substring(pos + toReplace.length());
+      return new StringBuilder().append(string.substring(0, pos))
+              .append(replacement)
+              .append(string.substring(pos + toReplace.length()))
+              .toString();
     }
     else
     {
       return string;
     }
+
   }
 
+  /* 
+   * return the maximum length of a List of Strings
+   */
+  public static int maxLength(List<String> l)
+  {
+    int max = 0;
+    for (String s : l)
+    {
+      if (s == null)
+        continue;
+      if (s.length() > max)
+        max = s.length();
+    }
+    return max;
+  }
 }
index 0141a6a..78d0b4c 100644 (file)
@@ -322,7 +322,7 @@ public class UrlLink
             // debug
             for (int s = 0; s <= rg.numSubs(); s++)
             {
-              System.err.println("Sub " + s + " : " + rg.matchedFrom(s)
+              jalview.bin.Console.errPrintln("Sub " + s + " : " + rg.matchedFrom(s)
                       + " : " + rg.matchedTo(s) + " : '"
                       + rg.stringMatched(s) + "'");
             }
index 1fc41e7..ce96bad 100644 (file)
@@ -20,8 +20,6 @@
  */
 package jalview.util.dialogrunner;
 
-import java.util.concurrent.Callable;
-
 /**
  * An interface for blocking dialog response handling. This is motivated by
  * JalviewJS - when running as Javascript, there is only a single thread, and
@@ -43,7 +41,7 @@ public interface DialogRunnerI
    * @param action
    * @return
    */
-  DialogRunnerI setResponseHandler(Object response, Callable<Void> action);
+  DialogRunnerI setResponseHandler(Object response, Runnable action);
 
   // DialogRunnerI setResponseHandler(Object response, Runnable action);
 
diff --git a/src/jalview/util/imagemaker/BitmapImageSizing.java b/src/jalview/util/imagemaker/BitmapImageSizing.java
new file mode 100644 (file)
index 0000000..450b01b
--- /dev/null
@@ -0,0 +1,41 @@
+package jalview.util.imagemaker;
+
+import jalview.bin.Cache;
+
+public class BitmapImageSizing
+{
+  public final float scale;
+
+  public final int width;
+
+  public final int height;
+
+  public BitmapImageSizing(float scale, int width, int height)
+  {
+    this.scale = scale;
+    this.width = width;
+    this.height = height;
+  }
+
+  public static BitmapImageSizing nullBitmapImageSizing()
+  {
+    return new BitmapImageSizing(0.0f, 0, 0);
+  }
+  
+  public static final String BITMAP_SCALE = "BITMAP_SCALE";
+
+  public static final String BITMAP_HEIGHT = "BITMAP_HEIGHT";
+
+  public static final String BITMAP_WIDTH = "BITMAP_WIDTH";
+
+  /**
+   * 
+   * @return bean configured from Cache keys
+   */
+  public static BitmapImageSizing defaultBitmapImageSizing()
+  {
+    
+    return new BitmapImageSizing(Cache.getDefault(BITMAP_SCALE,0)/10f,Cache.getDefault(BITMAP_WIDTH,0),Cache.getDefault(BITMAP_HEIGHT,0));
+    
+  }
+}
index d41a5be..7e0b6b4 100644 (file)
@@ -935,7 +935,7 @@ public abstract class AlignmentViewport
     }
     if (calculator.workingInvolvedWith(alignmentAnnotation))
     {
-      // System.err.println("grey out ("+alignmentAnnotation.label+")");
+      // jalview.bin.Console.errPrintln("grey out ("+alignmentAnnotation.label+")");
       return true;
     }
     return false;
@@ -1208,7 +1208,7 @@ public abstract class AlignmentViewport
   {
     if (sequenceSetID != null)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Warning - overwriting a sequenceSetId for a viewport!");
     }
     sequenceSetID = new String(newid);
@@ -2101,7 +2101,7 @@ public abstract class AlignmentViewport
       {
         if (aa == null)
         {
-          System.err.println("Null annotation row: ignoring.");
+          jalview.bin.Console.errPrintln("Null annotation row: ignoring.");
           continue;
         }
         if (!aa.visible)
@@ -2133,7 +2133,7 @@ public abstract class AlignmentViewport
 
         if (aa.graph > 0)
         {
-          aa.height += aa.graphHeight;
+          aa.height += aa.graphHeight+20;
         }
 
         if (aa.height == 0)
@@ -2294,7 +2294,7 @@ public abstract class AlignmentViewport
   {
     if (this == av)
     {
-      System.err.println("Ignoring recursive setCodingComplement request");
+      jalview.bin.Console.errPrintln("Ignoring recursive setCodingComplement request");
     }
     else
     {
@@ -2957,7 +2957,6 @@ public abstract class AlignmentViewport
     return alignment.getContactMatrixFor(alignmentAnnotation);
   }
 
-
   /**
    * get the consensus sequence as displayed under the PID consensus annotation
    * row.
index 104fb62..33c4c26 100644 (file)
@@ -224,7 +224,7 @@ public class ViewportRanges extends ViewportProperties
    */
   public void setStartEndSeq(int start, int end)
   {
-    // System.out.println("ViewportRange setStartEndSeq " + start + " " + end);
+    // jalview.bin.Console.outPrintln("ViewportRange setStartEndSeq " + start + " " + end);
     int[] oldvalues = updateStartEndSeq(start, end);
     int oldstartseq = oldvalues[0];
     int oldendseq = oldvalues[1];
@@ -438,7 +438,7 @@ public class ViewportRanges extends ViewportProperties
     {
       vpstart = visHeight - h;
     }
-    // System.out.println("ViewportRanges setviewportStartAndHeight " + vpstart
+    // jalview.bin.Console.outPrintln("ViewportRanges setviewportStartAndHeight " + vpstart
     // + " " + start + " " + h + " " + getVisibleAlignmentHeight());
 
     setStartEndSeq(vpstart, vpstart + h - 1);
index 91f2f0c..715645a 100644 (file)
  */
 package jalview.viewmodel.styles;
 
-import jalview.api.ViewStyleI;
-
 import java.awt.Color;
 
+import jalview.api.ViewStyleI;
+
 /**
  * A container for holding alignment view properties. View properties are
  * data-independent, which means they can be safely copied between views
index 08ef3a2..435d40c 100644 (file)
@@ -25,6 +25,7 @@ import jalview.api.AlignCalcWorkerI;
 import jalview.datamodel.AlignmentAnnotation;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Hashtable;
@@ -144,7 +145,7 @@ public class AlignCalcManager implements AlignCalcManagerI
   {
     synchronized (inProgress)
     {
-      // System.err.println("Worker " + worker + " marked as complete.");
+      // jalview.bin.Console.errPrintln("Worker " + worker + " marked as complete.");
       inProgress.remove(worker);
       List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
       if (upd != null)
@@ -191,7 +192,7 @@ public class AlignCalcManager implements AlignCalcManagerI
   public boolean isWorking(AlignCalcWorkerI worker)
   {
     synchronized (inProgress)
-    {// System.err.println("isWorking : worker "+(worker!=null ?
+    {// jalview.bin.Console.errPrintln("isWorking : worker "+(worker!=null ?
      // worker.getClass():"null")+ " "+hashCode());
       return worker != null && inProgress.contains(worker);
     }
@@ -200,11 +201,29 @@ public class AlignCalcManager implements AlignCalcManagerI
   @Override
   public boolean isWorking()
   {
+    boolean working=false;
     synchronized (inProgress)
     {
-      // System.err.println("isWorking "+hashCode());
-      return inProgress.size() > 0;
+      // jalview.bin.Console.errPrintln("isWorking "+hashCode());
+      working |= inProgress.size() > 0;
     }
+    synchronized (updating)
+    {
+      Collection<List<AlignCalcWorkerI>> workersLists = updating.values();
+      synchronized (workersLists)
+      {
+        for (List<AlignCalcWorkerI> workers : workersLists)
+        {
+          if (workers!=null)
+          {
+            synchronized (workers) {
+              working |= workers.size() > 0;
+            }
+          }
+        }
+      }
+    }
+    return working;
   }
 
   @Override
@@ -348,7 +367,7 @@ public class AlignCalcManager implements AlignCalcManagerI
      * {
      * 
      * if (isPending(worker)) { worker.abortAndDestroy(); startWorker(worker); }
-     * else { System.err.println("Pending exists for " + workerClass); } }
+     * else { jalview.bin.Console.errPrintln("Pending exists for " + workerClass); } }
      */
   }
 
index 2507bb5..c4e4b04 100644 (file)
@@ -56,7 +56,7 @@ public class AlignmentAnnotationFactory
             .getCurrentAlignFrame().alignPanel;
     if (currentAlignFrame == null)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Can't register calculator as no alignment window has focus");
       return;
     }
@@ -82,7 +82,7 @@ public class AlignmentAnnotationFactory
     }
     else
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Can't register calculator as no alignment window has focus");
     }
   }
index 1a5aaa4..8882b53 100644 (file)
@@ -58,7 +58,7 @@ public class ConsensusThread extends AlignCalcWorker
       }
       while (!calcMan.notifyWorking(this))
       {
-        // System.err.println("Thread
+        // jalview.bin.Console.errPrintln("Thread
         // (Consensus"+Thread.currentThread().getName()+") Waiting around.");
         try
         {
index 6746d1a..2e3dddd 100644 (file)
@@ -186,7 +186,7 @@ public abstract class AWSThread extends Thread
         {
           Console.debug("Interrupted sleep waiting for next job poll.", e);
         }
-        // System.out.println("I'm alive "+alTitle);
+        // jalview.bin.Console.outPrintln("I'm alive "+alTitle);
       }
     }
     if (jobComplete && jobs != null)
index d8858a9..0ebd3c3 100644 (file)
@@ -302,7 +302,7 @@ public class DBRefFetcher implements Runnable
       }
     } catch (Exception e)
     {
-      System.err.println("Couldn't locate PICR service instance.\n");
+      jalview.bin.Console.errPrintln("Couldn't locate PICR service instance.\n");
       e.printStackTrace();
     }
 
@@ -316,7 +316,7 @@ public class DBRefFetcher implements Runnable
     while (sdataset.size() > 0 && db < dbSources.length)
     {
       int maxqlen = 1; // default number of queries made at one time
-      System.out.println("Verifying against " + dbSources[db].getDbName());
+      jalview.bin.Console.outPrintln("Verifying against " + dbSources[db].getDbName());
 
       // iterate through db for each remaining un-verified sequence
       SequenceI[] currSeqs = new SequenceI[sdataset.size()];
@@ -425,7 +425,7 @@ public class DBRefFetcher implements Runnable
                             true);
                   } catch (Exception e)
                   {
-                    System.err.println(
+                    jalview.bin.Console.errPrintln(
                             "Exception with Picr for '" + token + "'\n");
                     e.printStackTrace();
                   }
@@ -438,7 +438,7 @@ public class DBRefFetcher implements Runnable
                     // present, and do a transferReferences
                     // otherwise transfer non sequence x-references directly.
                   }
-                  System.out.println(
+                  jalview.bin.Console.outPrintln(
                           "Validated ID against PICR... (for what its worth):"
                                   + token);
                   addSeqId(sequence, token);
@@ -447,7 +447,7 @@ public class DBRefFetcher implements Runnable
                 else
                 {
                   // if ()
-                  // System.out.println("Not querying source with
+                  // jalview.bin.Console.outPrintln("Not querying source with
                   // token="+token+"\n");
                   addSeqId(sequence, token);
                   queries.addElement(token.toUpperCase(Locale.ROOT));
@@ -512,7 +512,7 @@ public class DBRefFetcher implements Runnable
           DbSourceProxy dbSourceProxy, AlignmentI retrievedAl,
           boolean trimDatasetSeqs, List<String> warningMessages)
   {
-    // System.out.println("trimming ? " + trimDatasetSeqs);
+    // jalview.bin.Console.outPrintln("trimming ? " + trimDatasetSeqs);
     if (retrievedAl == null || retrievedAl.getHeight() == 0)
     {
       return false;
@@ -678,7 +678,7 @@ public class DBRefFetcher implements Runnable
           }
         }
 
-        System.out.println("Adding dbrefs to " + sequence.getName()
+        jalview.bin.Console.outPrintln("Adding dbrefs to " + sequence.getName()
                 + " from " + dbSource + " sequence : "
                 + retrievedSeq.getName());
         sequence.transferAnnotation(retrievedSeq, mp);
index 6b86775..ff6f74f 100644 (file)
@@ -153,7 +153,7 @@ public class JobStateSummary
         }
         // } catch (OutOfMemoryError e)
         // {
-        // System.err.println("Out of memory when displaying status. Squashing
+        // jalview.bin.Console.errPrintln("Out of memory when displaying status. Squashing
         // error.");
         // wsInfo.appendProgressText(j.jobnum,
         // "..\n(Out of memory when displaying status)\n");
diff --git a/src/jalview/ws/datamodel/MappableContactMatrixI.java b/src/jalview/ws/datamodel/MappableContactMatrixI.java
new file mode 100644 (file)
index 0000000..9762428
--- /dev/null
@@ -0,0 +1,76 @@
+package jalview.ws.datamodel;
+
+import jalview.datamodel.ContactListI;
+import jalview.datamodel.ContactMatrixI;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.SequenceI;
+import jalview.util.MapList;
+
+public interface MappableContactMatrixI extends ContactMatrixI
+{
+
+  boolean hasReferenceSeq();
+
+  SequenceI getReferenceSeq();
+
+  /**
+   * remaps the matrix to a new reference sequence
+   * 
+   * @param dsq
+   * @param sqmpping
+   *          - mapping from current reference to new reference - 1:1 only
+   * @return new ContactMatrixI instance with updated mapping
+   */
+  MappableContactMatrixI liftOver(SequenceI dsq, Mapping sqmpping);
+
+  /**
+   * like ContactMatrixI.getContactList(int column) but
+   * 
+   * @param localFrame
+   *          - sequence or other object that this contact matrix is associated
+   *          with
+   * @param column
+   *          - position in localFrame
+   * @return ContactListI that returns contacts w.r.t. localFrame
+   */
+
+  ContactListI getMappableContactList(SequenceI localFrame, int column);
+
+  /**
+   * 
+   * Similar to AlignedCodonFrame.getMappingBetween
+   * 
+   * @param sequenceRef
+   *          - a reference sequence mappable to this contactMatrix - may be
+   *          null
+   * @return null or the MapList mapping to the coordinates of the reference
+   *         sequence (or if hasReferenceSeq() is false, and sequenceRef is
+   *         null, any mapping present)
+   * 
+   */
+  MapList getMapFor(SequenceI sequenceRef);
+
+  /**
+   * Locate a position in the mapped sequence for a single column in the matrix. 
+   * this to resolve positions corresponding to column clusters
+   * 
+   * @param localFrame
+   *          - sequence derivced from reference sequence
+   * @param column
+   *          - matrix row/column
+   * @return sequence position(s) corresponding to column in contact matrix
+   */
+  int[] getMappedPositionsFor(SequenceI localFrame, int column);
+
+  /**
+   * Locate a position in the mapped sequence for a contiguous range of columns in the matrix 
+   * use this to resolve positions corresponding to column clusters
+   * 
+   * @param localFrame
+   *          - sequence derivced from reference sequence
+   * @param column
+   *          - matrix row/column
+   * @return sequence position(s) corresponding to column in contact matrix
+   */
+  int[] getMappedPositionsFor(SequenceI localFrame, int from, int to);
+}
diff --git a/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java b/src/jalview/ws/datamodel/alphafold/MappableContactMatrix.java
new file mode 100644 (file)
index 0000000..d545741
--- /dev/null
@@ -0,0 +1,452 @@
+package jalview.ws.datamodel.alphafold;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.BitSet;
+
+import jalview.datamodel.ContactListI;
+import jalview.datamodel.ContactListImpl;
+import jalview.datamodel.ContactListProviderI;
+import jalview.datamodel.GroupSet;
+import jalview.datamodel.GroupSetI;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.SequenceI;
+import jalview.util.MapList;
+import jalview.ws.datamodel.MappableContactMatrixI;
+
+public abstract class MappableContactMatrix<T extends MappableContactMatrix<T>>
+        implements MappableContactMatrixI
+{
+  SequenceI refSeq = null;
+
+  MapList toSeq = null;
+
+  /**
+   * the length that refSeq is expected to be (excluding gaps, of course)
+   */
+  int length;
+
+  @Override
+  public boolean hasReferenceSeq()
+  {
+    return (refSeq != null);
+  }
+
+  @Override
+  public SequenceI getReferenceSeq()
+  {
+    return refSeq;
+  }
+
+  /**
+   * container for groups - defined on matrix columns
+   */
+  GroupSet grps = new GroupSet();
+
+  @Override
+  public GroupSetI getGroupSet()
+  {
+    return grps;
+  };
+
+  @Override
+  public void setGroupSet(GroupSet makeGroups)
+  {
+    grps = makeGroups;
+  }
+
+  @Override
+  public MapList getMapFor(SequenceI mapSeq)
+  {
+    if (refSeq != null)
+    {
+      while (mapSeq != refSeq && mapSeq.getDatasetSequence() != null)
+      {
+        mapSeq = mapSeq.getDatasetSequence();
+      }
+      if (mapSeq != refSeq)
+      {
+        return null;
+      }
+    }
+    else
+    {
+      if (mapSeq != null)
+      {
+        // our MapList does not concern this seq
+        return null;
+      }
+    }
+
+    return toSeq;
+  }
+
+  /**
+   * set the reference sequence and construct the mapping between the start-end
+   * positions of given sequence and row/columns of contact matrix
+   * 
+   * @param _refSeq
+   */
+  public void setRefSeq(SequenceI _refSeq)
+  {
+    refSeq = _refSeq;
+    while (refSeq.getDatasetSequence() != null)
+    {
+      refSeq = refSeq.getDatasetSequence();
+    }
+    length = _refSeq.getEnd() - _refSeq.getStart() + 1;
+    // if (length!=refSeq.getLength() || _refSeq.getStart()!=1)
+    {
+      toSeq = new MapList(
+              new int[]
+              { _refSeq.getStart(), _refSeq.getEnd() },
+              new int[]
+              { 0, length - 1 }, 1, 1);
+    }
+  }
+
+  public T liftOver(SequenceI newRefSeq, Mapping sp2sq)
+  {
+    if (sp2sq.getMappedWidth() != sp2sq.getWidth())
+    {
+      // TODO: employ getWord/MappedWord to transfer annotation between cDNA and
+      // Protein reference frames
+      throw new Error(
+              "liftOver currently not implemented for transfer of annotation between different types of seqeunce");
+    }
+    boolean mapIsTo = (sp2sq != null) ? (sp2sq.getTo() == refSeq) : false;
+
+    /**
+     * map from matrix to toSeq's coordinate frame
+     */
+    int[] refMap = toSeq.locateInFrom(0, length - 1);
+    ArrayList<Integer> newFromMap = new ArrayList<Integer>();
+    int last = -1;
+    for (int i = 0; i < refMap.length; i += 2)
+    {
+      /*
+       * for each contiguous range in toSeq, locate corresponding range in sequence mapped to toSeq by sp2sq
+       */
+      int[] sp2map = mapIsTo
+              ? sp2sq.getMap().locateInFrom(refMap[i], refMap[i + 1])
+              : sp2sq.getMap().locateInTo(refMap[i], refMap[i + 1]);
+      if (sp2map == null)
+      {
+        continue;
+      }
+
+      for (int spm = 0; spm < sp2map.length; spm += 2)
+      {
+
+        if (last > -1)
+        {
+          if (sp2map[spm] != last + 1)
+          {
+            newFromMap.add(sp2map[spm]);
+          }
+          else
+          {
+            newFromMap.remove(newFromMap.size() - 1);
+          }
+        }
+        else
+        {
+          newFromMap.add(sp2map[spm]);
+        }
+        last = sp2map[spm + 1];
+        newFromMap.add(last);
+      }
+    }
+    if ((newFromMap.size() % 2) != 0)
+    {
+      // should have had an even number of int ranges!
+      throw new Error("PAEMatrix liftover failed.");
+    }
+    int fromIntMap[] = new int[newFromMap.size()];
+    int ipos = 0;
+    for (Integer i : newFromMap)
+    {
+      fromIntMap[ipos++] = i;
+    }
+    MapList newFromMapList = new MapList(fromIntMap,
+            new int[]
+            { 0, length - 1 }, 1, 1);
+
+    T newCM = newMappableContactMatrix(newRefSeq, newFromMapList);
+    return newCM;
+  }
+
+  protected abstract T newMappableContactMatrix(SequenceI newRefSeq,
+          MapList newFromMapList);
+
+  @Override
+  public int[] getMappedPositionsFor(final SequenceI localFrame,
+          final int column)
+  {
+    return getMappedPositionsFor(localFrame, column, column);
+  }
+
+  @Override
+  public int[] getMappedPositionsFor(final SequenceI localFrame, int from,
+          int to)
+  {
+    if (localFrame == null)
+    {
+      throw new Error("Unimplemented when no local sequence given.");
+    }
+    SequenceI lf = localFrame, uf = refSeq;
+
+    // check that localFrame is derived from refSeq
+    // just look for dataset sequences and check they are the same.
+    // in future we could use DBRefMappings/whatever.
+    while (lf.getDatasetSequence() != null
+            || uf.getDatasetSequence() != null)
+    {
+      if (lf.getDatasetSequence() != null)
+      {
+        lf = lf.getDatasetSequence();
+      }
+      if (uf.getDatasetSequence() != null)
+      {
+        uf = uf.getDatasetSequence();
+      }
+    }
+    if (lf != uf)
+    {
+      // could try harder to find a mapping
+      throw new Error("This Matrix associated with '" + refSeq.getName()
+              + "' is not mappable for the given localFrame sequence. ("
+              + localFrame.getName() + ")");
+    }
+    
+    // now look up from-to matrix columns in toSeq frame
+    
+    if (toSeq == null)
+    {
+      // no mapping - so we assume 1:1
+      return new int[] { from, to };
+    }
+    // from-to are matrix columns
+    // first locate on reference sequence
+
+    int[] mappedPositions = toSeq.locateInFrom(from, to);
+    if (mappedPositions==null)
+    {
+      return null;
+    }
+    
+    // and now map to localFrame
+    // from-to columns on the associated sequence should be
+    // i. restricted to positions in localFrame
+    // ii. 
+
+//    int s = -1, e = -1;
+//    for (int p = 0; p < mappedPositions.length; p++)
+//    {
+//      if (s == -1 && mappedPositions[p] >= localFrame.getStart())
+//      {
+//        s = p; // remember first position within local frame
+//      }
+//      if (e == -1 || mappedPositions[p] <= localFrame.getEnd())
+//      {
+//        // update end pointer
+//        e = p;
+//        // compute local map
+//        mappedPositions[p] = localFrame.findIndex(mappedPositions[p]);
+//      }
+//    }
+//    int[] _trimmed = new int[e - s + 1];
+//    return _trimmed;
+    return mappedPositions;
+  }
+
+  @Override
+  public ContactListI getMappableContactList(final SequenceI localFrame,
+          final int column)
+  {
+    final int _column;
+    final int _lcolumn;
+    if (localFrame == null)
+    {
+      throw new Error("Unimplemented when no local sequence given.");
+    }
+    // return a ContactListI for column
+    // column is index into localFrame
+    // 1. map column to corresponding column in matrix
+    final MappableContactMatrix us = this;
+    _lcolumn = localFrame.findPosition(column);
+
+    if (toSeq != null)
+    {
+      SequenceI lf = localFrame, uf = refSeq;
+
+      // just look for dataset sequences and check they are the same.
+      // in future we could use DBRefMappings/whatever.
+      while (lf.getDatasetSequence() != null
+              || uf.getDatasetSequence() != null)
+      {
+        if (lf.getDatasetSequence() != null)
+        {
+          lf = lf.getDatasetSequence();
+        }
+        if (uf.getDatasetSequence() != null)
+        {
+          uf = uf.getDatasetSequence();
+        }
+      }
+      if (lf != uf)
+      {
+        // could try harder to find a mapping
+        throw new Error("This Matrix associated with '" + refSeq.getName()
+                + "' is not mappable for the given localFrame sequence. ("
+                + localFrame.getName() + ")");
+      }
+      // check the mapping to see if localFrame _lcolumn exists
+      int[] word = toSeq.locateInTo(_lcolumn, _lcolumn);
+      if (word == null)
+      {
+        return null;
+      }
+      _column = word[0];
+    }
+    else
+    {
+      // no mapping
+      _column = _lcolumn;
+    }
+
+    // TODO - remove ? this may be a redundant check
+    if (_column < 0 || ((toSeq != null && _column > toSeq.getToHighest())
+            || (toSeq == null && getHeight() <= _column)))
+    {
+      return null;
+    }
+
+    // 2. resolve ranges in matrix corresponding to range in localFrame
+    final int[] matrixRange = toSeq == null
+            ? new int[]
+            { localFrame.getStart(), localFrame.getEnd() }
+            : toSeq.locateInTo(localFrame.getStart(), localFrame.getEnd());
+
+    int h = 0;
+    for (int p = 0; p < matrixRange.length; p += 2)
+    {
+      h += 1 + Math.abs(matrixRange[p + 1] - matrixRange[p]);
+    }
+    final int rangeHeight = h;
+    // 3. Construct ContactListImpl instance for just those segments.
+
+    return new ContactListImpl(new ContactListProviderI()
+    {
+
+      public int getColumn()
+      {
+        return column;
+      }
+
+      @Override
+      public int getPosition()
+      {
+        return _column;
+      }
+
+      @Override
+      public int getContactHeight()
+      {
+        return rangeHeight;
+      }
+
+      @Override
+      public double getContactAt(int mcolumn)
+      {
+        if (mcolumn < 0 || mcolumn >= rangeHeight)
+        {
+          return -1;
+        }
+        return getElementAt(_column, locateInRange(mcolumn));
+
+        // this code maps from mcolumn to localFrame - but that isn't what's
+        // needed
+        // int loccolumn = localFrame.findPosition(mcolumn);
+        // int[] lcolumn=(toSeq==null) ? new int[] {mcolumn} :
+        // toSeq.locateInTo(loccolumn,loccolumn);
+        // if (lcolumn==null || lcolumn[0] < 0 || lcolumn[0] >= rangeHeight)
+        // {
+        // return -1;
+        // }
+        // return getElementAt(_column,lcolumn[0]);
+      }
+
+      @Override
+      public int[] getMappedPositionsFor(int cStart, int cEnd)
+      {
+        if (!hasReferenceSeq())
+        {
+          return ContactListProviderI.super.getMappedPositionsFor(cStart,
+                  cEnd);
+        }
+        // map into segment of matrix being shown
+        int realCstart = locateInRange(cStart);
+        int realCend = locateInRange(cEnd);
+
+        // TODO account for discontinuities in the mapping
+
+        int[] mappedPositions = toSeq.locateInFrom(realCstart, realCend);
+        if (mappedPositions != null)
+        {
+          int s = -1, e = -1;
+          for (int p = 0; p < mappedPositions.length; p++)
+          {
+            if (s == -1 && mappedPositions[p] >= localFrame.getStart())
+            {
+              s = p; // remember first position within local frame
+            }
+            if (e == -1 || mappedPositions[p] <= localFrame.getEnd())
+            {
+              // update end pointer
+              e = p;
+              // compute local map
+              mappedPositions[p] = localFrame.findIndex(mappedPositions[p]);
+            }
+          }
+        }
+        return mappedPositions;
+      }
+
+      /**
+       * @return the mcolumn'th position in the matrixRange window on the matrix
+       */
+      private int locateInRange(int mcolumn)
+      {
+
+        int h = 0, p = 0;
+        while (h < mcolumn && p + 2 < matrixRange.length)
+        {
+          h += 1 + Math.abs(matrixRange[p + 1] - matrixRange[p]);
+          p += 2;
+        }
+        return matrixRange[p] + mcolumn - h;
+      }
+
+      @Override
+      public Color getColourForGroup()
+      {
+        BitSet gp = us.getGroupsFor(_column);
+        Color col = us.getColourForGroup(gp);
+        return col;
+      }
+    });
+  }
+
+  /**
+   * get a specific element of the contact matrix in its data-local coordinates
+   * rather than the mapped frame. Implementations are allowed to throw
+   * RunTimeExceptions if _column/i are out of bounds
+   * 
+   * @param _column
+   * @param i
+   * @return
+   */
+  protected abstract double getElementAt(int _column, int i);
+
+}
index 41e677a..22884f1 100644 (file)
@@ -1,53 +1,57 @@
 package jalview.ws.datamodel.alphafold;
 
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashMap;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import jalview.analysis.AverageDistanceEngine;
-import jalview.bin.Console;
-import jalview.datamodel.BinaryNode;
+import org.json.simple.JSONObject;
+
 import jalview.datamodel.ContactListI;
 import jalview.datamodel.ContactListImpl;
 import jalview.datamodel.ContactListProviderI;
 import jalview.datamodel.ContactMatrixI;
+import jalview.datamodel.GroupSet;
+import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceI;
+import jalview.io.FileFormatException;
+import jalview.util.MapList;
 import jalview.util.MapUtils;
-
-public class PAEContactMatrix implements ContactMatrixI
+import jalview.ws.dbsources.EBIAlfaFold;
+
+/**
+ * routines and class for holding predicted alignment error matrices as produced
+ * by alphafold et al.
+ * 
+ * getContactList(column) returns the vector of predicted alignment errors for
+ * reference position given by column getElementAt(column, i) returns the
+ * predicted superposition error for the ith position when column is used as
+ * reference
+ * 
+ * Many thanks to Ora Schueler Furman for noticing that earlier development
+ * versions did not show the PAE oriented correctly
+ *
+ * @author jprocter
+ *
+ */
+public class PAEContactMatrix extends
+        MappableContactMatrix<PAEContactMatrix> implements ContactMatrixI
 {
 
-  SequenceI refSeq = null;
-
-  /**
-   * the length that refSeq is expected to be (excluding gaps, of course)
-   */
-  int length;
 
   int maxrow = 0, maxcol = 0;
 
-  int[] indices1, indices2;
 
   float[][] elements;
 
   float maxscore;
 
-  private void setRefSeq(SequenceI _refSeq)
-  {
-    refSeq = _refSeq;
-    while (refSeq.getDatasetSequence() != null)
-    {
-      refSeq = refSeq.getDatasetSequence();
-    }
-    length = _refSeq.getEnd() - _refSeq.getStart() + 1;
-  }
 
   @SuppressWarnings("unchecked")
   public PAEContactMatrix(SequenceI _refSeq, Map<String, Object> pae_obj)
+          throws FileFormatException
   {
     setRefSeq(_refSeq);
     // convert the lists to primitive arrays and store
@@ -94,6 +98,22 @@ public class PAEContactMatrix implements ContactMatrixI
   }
 
   /**
+   * new matrix with specific mapping to a reference sequence
+   * 
+   * @param newRefSeq
+   * @param newFromMapList
+   * @param elements2
+   * @param grps2
+   */
+  public PAEContactMatrix(SequenceI newRefSeq, MapList newFromMapList,
+          float[][] elements2, GroupSet grps2)
+  {
+    this(newRefSeq, elements2);
+    toSeq = newFromMapList;
+    grps = grps2;
+  }
+
+  /**
    * parse a sane JSON representation of the pAE
    * 
    * @param pae_obj
@@ -101,9 +121,17 @@ public class PAEContactMatrix implements ContactMatrixI
   @SuppressWarnings("unchecked")
   private void parse_version_2_pAE(Map<String, Object> pae_obj)
   {
-    // this is never going to be reached by the integer rounding.. or is it ?
-    maxscore = ((Double) MapUtils.getFirst(pae_obj,
-            "max_predicted_aligned_error", "max_pae")).floatValue();
+    maxscore = -1;
+    // look for a maxscore element - if there is one...
+    try
+    {
+      // this is never going to be reached by the integer rounding.. or is it ?
+      maxscore = ((Double) MapUtils.getFirst(pae_obj,
+              "max_predicted_aligned_error", "max_pae")).floatValue();
+    } catch (Throwable t)
+    {
+      // ignore if a key is not found.
+    }
     List<List<Long>> scoreRows = ((List<List<Long>>) MapUtils
             .getFirst(pae_obj, "predicted_aligned_error", "pae"));
     elements = new float[scoreRows.size()][scoreRows.size()];
@@ -115,9 +143,19 @@ public class PAEContactMatrix implements ContactMatrixI
       {
         Object d = scores.next();
         if (d instanceof Double)
-          elements[row][col++] = ((Double) d).longValue();
+        {
+          elements[col][row] = ((Double) d).longValue();
+        }
         else
-          elements[row][col++] = (float) ((Long) d).longValue();
+        {
+          elements[col][row] = (float) ((Long) d).longValue();
+        }
+
+        if (maxscore < elements[col][row])
+        {
+          maxscore = elements[col][row];
+        }
+        col++;
       }
       row++;
       col = 0;
@@ -139,10 +177,26 @@ public class PAEContactMatrix implements ContactMatrixI
     // dataset refSeq
     Iterator<Long> rows = ((List<Long>) pae_obj.get("residue1")).iterator();
     Iterator<Long> cols = ((List<Long>) pae_obj.get("residue2")).iterator();
+    // two pass - to allocate the elements array
+    while (rows.hasNext())
+    {
+      int row = rows.next().intValue();
+      int col = cols.next().intValue();
+      if (maxrow < row)
+      {
+        maxrow = row;
+      }
+      if (maxcol < col)
+      {
+        maxcol = col;
+      }
+
+    }
+    rows = ((List<Long>) pae_obj.get("residue1")).iterator();
+    cols = ((List<Long>) pae_obj.get("residue2")).iterator();
     Iterator<Double> scores = ((List<Double>) pae_obj.get("distance"))
             .iterator();
-    // assume square matrix
-    elements = new float[length][length];
+    elements = new float[maxcol][maxrow];
     while (scores.hasNext())
     {
       float escore = scores.next().floatValue();
@@ -156,17 +210,21 @@ public class PAEContactMatrix implements ContactMatrixI
       {
         maxcol = col;
       }
-      elements[row - 1][col - 1] = escore;
+      elements[col - 1][row-1] = escore;
     }
 
     maxscore = ((Double) MapUtils.getFirst(pae_obj,
             "max_predicted_aligned_error", "max_pae")).floatValue();
   }
 
+  /**
+   * getContactList(column) @returns the vector of predicted alignment errors
+   * for reference position given by column
+   */
   @Override
-  public ContactListI getContactList(final int _column)
+  public ContactListI getContactList(final int column)
   {
-    if (_column < 0 || _column >= elements.length)
+    if (column < 0 || column >= elements.length)
     {
       return null;
     }
@@ -176,7 +234,7 @@ public class PAEContactMatrix implements ContactMatrixI
       @Override
       public int getPosition()
       {
-        return _column;
+        return column;
       }
 
       @Override
@@ -186,55 +244,54 @@ public class PAEContactMatrix implements ContactMatrixI
       }
 
       @Override
-      public double getContactAt(int column)
+      public double getContactAt(int mcolumn)
       {
-        if (column < 0 || column >= elements[_column].length)
+        if (mcolumn < 0 || mcolumn >= elements[column].length)
         {
           return -1;
         }
-        return elements[_column][column];
+        return elements[column][mcolumn];
       }
     });
   }
 
+  /**
+   * getElementAt(column, i) @returns the predicted superposition error for the
+   * ith position when column is used as reference
+   */
   @Override
-  public float getMin()
-  {
-    return 0;
-  }
-
-  @Override
-  public float getMax()
+  protected double getElementAt(int _column, int i)
   {
-    return maxscore;
+    return elements[_column][i];
   }
 
   @Override
-  public boolean hasReferenceSeq()
+  public float getMin()
   {
-    return (refSeq != null);
+    return 0;
   }
 
   @Override
-  public SequenceI getReferenceSeq()
+  public float getMax()
   {
-    return refSeq;
+    return maxscore;
   }
 
   @Override
   public String getAnnotDescr()
   {
-    return "Predicted Alignment Error"+((refSeq==null) ? "" : (" for " + refSeq.getName()));
+    return "Predicted Alignment Error"
+            + ((refSeq == null) ? "" : (" for " + refSeq.getName()));
   }
 
   @Override
   public String getAnnotLabel()
   {
     StringBuilder label = new StringBuilder("PAE Matrix");
-    //if (this.getReferenceSeq() != null)
-    //{
-    //  label.append(":").append(this.getReferenceSeq().getDisplayId(false));
-    //}
+    // if (this.getReferenceSeq() != null)
+    // {
+    // label.append(":").append(this.getReferenceSeq().getDisplayId(false));
+    // }
     return label.toString();
   }
 
@@ -249,128 +306,49 @@ public class PAEContactMatrix implements ContactMatrixI
   @Override
   public int getWidth()
   {
-    return length;
+    return maxcol;
   }
 
   @Override
   public int getHeight()
   {
-    return length;
+    return maxrow;
   }
-  List<BitSet> groups=null;
-  @Override
-  public boolean hasGroups()
+  public static void validateContactMatrixFile(String fileName)
+          throws FileFormatException, IOException
   {
-    return groups!=null;
-  }
-  String newick=null;
-  @Override
-  public String getNewick()
-  {
-    return newick;
-  }
-  @Override
-  public boolean hasTree()
-  {
-    return newick!=null && newick.length()>0;
-  }
-  boolean abs;
-  double thresh;
-  String treeType=null;
-  public void makeGroups(float thresh,boolean abs)
-  {
-    AverageDistanceEngine clusterer = new AverageDistanceEngine(null, null, this);
-    double height = clusterer.findHeight(clusterer.getTopNode());
-    newick = new jalview.io.NewickFile(clusterer.getTopNode(),false,true).print();
-    treeType = "UPGMA";
-    Console.trace("Newick string\n"+newick);
-
-    List<BinaryNode> nodegroups;
-    if (abs ? height > thresh : 0 < thresh && thresh < 1)
+    FileInputStream infile = null;
+    try
     {
-      float cut = abs ? (float) (thresh / height) : thresh;
-      Console.debug("Threshold "+cut+" for height="+height);
-
-      nodegroups = clusterer.groupNodes(cut);
-    }
-    else
+      infile = new FileInputStream(new File(fileName));
+    } catch (Throwable t)
     {
-      nodegroups = new ArrayList<BinaryNode>();
-      nodegroups.add(clusterer.getTopNode());
+      new IOException("Couldn't open " + fileName, t);
     }
-    this.abs=abs;
-    this.thresh=thresh;
-    groups = new ArrayList<>();
-    for (BinaryNode root:nodegroups)
+    JSONObject paeDict = null;
+    try
     {
-      BitSet gpset=new BitSet();
-      for (BinaryNode leaf:clusterer.findLeaves(root))
-      {
-        gpset.set((Integer)leaf.element());
-      }
-      groups.add(gpset);
-    }
-  }
-  @Override
-  public void updateGroups(List<BitSet> colGroups)
-  {
-    if (colGroups!=null)
+      paeDict = EBIAlfaFold.parseJSONtoPAEContactMatrix(infile);
+    } catch (Throwable t)
     {
-      groups=colGroups;
-    }    
-  }
-  @Override
-  public BitSet getGroupsFor(int column)
-  {
-    for (BitSet gp:groups) {
-      if (gp.get(column))
-      {
-        return gp;
-      }
+      new FileFormatException("Couldn't parse " + fileName
+              + " as a JSON dict or array containing a dict");
     }
-    return ContactMatrixI.super.getGroupsFor(column);
-  }
 
-  HashMap<BitSet,Color> colorMap = new HashMap<>();
-  @Override 
-  public Color getColourForGroup(BitSet bs)
-  {
-    if (bs==null) {
-      return Color.white;
-    }
-    Color groupCol=colorMap.get(bs);
-    if (groupCol==null)
+    PAEContactMatrix matrix = new PAEContactMatrix(
+            new SequenceDummy("Predicted"), (Map<String, Object>) paeDict);
+    if (matrix.getWidth() <= 0)
     {
-      return Color.white;
+      throw new FileFormatException(
+              "No data in PAE matrix read from '" + fileName + "'");
     }
-    return groupCol;
-  }
-  @Override 
-  public void setColorForGroup(BitSet bs,Color color)
-  {
-    colorMap.put(bs,color);
-  }
-  public void restoreGroups(List<BitSet> newgroups, String treeMethod,
-          String tree, double thresh2)
-  {
-    treeType=treeMethod;
-    groups = newgroups;
-    thresh=thresh2;
-    newick =tree;
-    
-  }
-  @Override
-  public boolean hasCutHeight() {
-    return groups!=null && thresh!=0;
-  }
-  @Override
-  public double getCutHeight()
-  {
-    return thresh;
   }
   @Override
-  public String getTreeMethod()
+  protected PAEContactMatrix newMappableContactMatrix(SequenceI newRefSeq,
+          MapList newFromMapList)
   {
-    return treeType;
+    PAEContactMatrix pae = new PAEContactMatrix(newRefSeq, newFromMapList,
+            elements, new GroupSet(grps));
+    return pae;
   }
 }
index d9cbbd9..6b27488 100644 (file)
@@ -44,6 +44,7 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ContactMatrixI;
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.GroupSet;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
@@ -175,7 +176,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
 
     if (!isValidReference(id))
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "(AFClient) Ignoring invalid alphafold query: '" + id + "'");
       stopQuery();
       return null;
@@ -294,11 +295,12 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
           AlignmentI pdbAlignment, String retrievalUrl) throws IOException
   {
     File pae = fetchAlphaFoldPAE(id, retrievalUrl);
-    addAlphaFoldPAE(pdbAlignment, pae, 0, null, false, false);
+    addAlphaFoldPAE(pdbAlignment, pae, 0, null, false, false, null);
   }
 
   public static void addAlphaFoldPAE(AlignmentI pdbAlignment, File pae,
-          int index, String id, boolean isStruct, boolean isStructId)
+          int index, String id, boolean isStruct, boolean isStructId,
+          String label)
   {
     FileInputStream paeInput = null;
     try
@@ -313,12 +315,14 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
 
     if (isStruct)
     {
+      // ###### WRITE A TEST for this bit of the logic addAlphaFoldPAE with
+      // different params.
       StructureSelectionManager ssm = StructureSelectionManager
               .getStructureSelectionManager(Desktop.instance);
       if (ssm != null)
       {
         String structFilename = isStructId ? ssm.findFileForPDBId(id) : id;
-        addPAEToStructure(ssm, structFilename, pae);
+        addPAEToStructure(ssm, structFilename, pae, label);
       }
 
     }
@@ -328,7 +332,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
       try
       {
         if (!importPaeJSONAsContactMatrixToSequence(pdbAlignment, paeInput,
-                index, id))
+                index, id, label))
         {
           Console.warn("Could not import contact matrix from '"
                   + pae.getAbsolutePath() + "' to sequence.");
@@ -347,7 +351,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
   }
 
   public static void addPAEToStructure(StructureSelectionManager ssm,
-          String structFilename, File pae)
+          String structFilename, File pae, String label)
   {
     FileInputStream paeInput = null;
     try
@@ -370,7 +374,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
 
       try
       {
-        if (!importPaeJSONAsContactMatrixToStructure(smArray, paeInput))
+        if (!importPaeJSONAsContactMatrixToStructure(smArray, paeInput,
+                label))
         {
           Console.warn("Could not import contact matrix from '"
                   + pae.getAbsolutePath() + "' to structure.");
@@ -400,7 +405,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
    */
   public static boolean importPaeJSONAsContactMatrixToSequence(
           AlignmentI pdbAlignment, InputStream pae_input, int index,
-          String seqId) throws IOException, ParseException
+          String seqId, String label) throws IOException, ParseException
   {
     SequenceI sequence = null;
     if (seqId == null)
@@ -427,12 +432,13 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
       return false;
     }
     return importPaeJSONAsContactMatrixToSequence(pdbAlignment, pae_input,
-            sequence);
+            sequence, label);
   }
 
   public static boolean importPaeJSONAsContactMatrixToSequence(
           AlignmentI pdbAlignment, InputStream pae_input,
-          SequenceI sequence) throws IOException, ParseException
+          SequenceI sequence, String label)
+          throws IOException, ParseException
   {
     JSONObject paeDict = parseJSONtoPAEContactMatrix(pae_input);
     if (paeDict == null)
@@ -442,9 +448,10 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
     }
     ContactMatrixI matrix = new PAEContactMatrix(sequence,
             (Map<String, Object>) paeDict);
-    ((PAEContactMatrix) matrix).makeGroups(5f, true);
 
     AlignmentAnnotation cmannot = sequence.addContactList(matrix);
+    if (label != null)
+      cmannot.label = label;
     pdbAlignment.addAnnotation(cmannot);
 
     return true;
@@ -469,22 +476,23 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
     return paeDict;
   }
 
+  // ###### TEST THIS
   public static boolean importPaeJSONAsContactMatrixToStructure(
-          StructureMapping[] smArray, InputStream paeInput)
+          StructureMapping[] smArray, InputStream paeInput, String label)
           throws IOException, ParseException
   {
     boolean someDone = false;
     for (StructureMapping sm : smArray)
     {
       boolean thisDone = importPaeJSONAsContactMatrixToStructure(sm,
-              paeInput);
+              paeInput, label);
       someDone |= thisDone;
     }
     return someDone;
   }
 
   public static boolean importPaeJSONAsContactMatrixToStructure(
-          StructureMapping sm, InputStream paeInput)
+          StructureMapping sm, InputStream paeInput, String label)
           throws IOException, ParseException
   {
     JSONObject pae_obj = parseJSONtoPAEContactMatrix(paeInput);
@@ -494,12 +502,13 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy
       return false;
     }
 
-    ContactMatrixI matrix = new PAEContactMatrix(sm.getSequence(),
+    SequenceI seq = sm.getSequence();
+    ContactMatrixI matrix = new PAEContactMatrix(seq,
             (Map<String, Object>) pae_obj);
-    ((PAEContactMatrix) matrix).makeGroups(5f, true);
     AlignmentAnnotation cmannot = sm.getSequence().addContactList(matrix);
-    sm.getSequence().addAlignmentAnnotation(cmannot);
-
+    /* this already happens in Sequence.addContactList()
+     seq.addAlignmentAnnotation(cmannot);
+     */
     return true;
   }
 
index 7ac6936..bef6976 100644 (file)
@@ -57,7 +57,7 @@ public abstract class EbiFileRetrievedProxy extends DbSourceProxyImpl
       }
     } catch (Exception e)
     {
-      System.err.println("Warning: problems reading temp file " + file);
+      jalview.bin.Console.errPrintln("Warning: problems reading temp file " + file);
       return null;
     }
     return bf;
index 034ea4f..a4d9633 100644 (file)
@@ -161,7 +161,7 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
       }
       else
       {
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "No record found for '" + emprefx + ":" + query + "'");
       }
     }
@@ -283,11 +283,11 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
       }
     } catch (Exception e)
     {
-      System.err.println("EMBL Record Features parsing error!");
+      jalview.bin.Console.errPrintln("EMBL Record Features parsing error!");
       System.err
               .println("Please report the following to help@jalview.org :");
-      System.err.println("EMBL Record " + accession);
-      System.err.println("Resulted in exception: " + e.getMessage());
+      jalview.bin.Console.errPrintln("EMBL Record " + accession);
+      jalview.bin.Console.errPrintln("Resulted in exception: " + e.getMessage());
       e.printStackTrace(System.err);
     }
 
@@ -354,7 +354,7 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
             codonStart = Integer.parseInt(value.trim());
           } catch (NumberFormatException e)
           {
-            System.err.println("Invalid codon_start in XML for "
+            jalview.bin.Console.errPrintln("Invalid codon_start in XML for "
                     + entry.getAccession() + ": " + e.getMessage());
           }
         }
@@ -406,13 +406,13 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
          * workaround until we handle dna location for CDS sequence
          * e.g. location="X53828.1:60..1058" correctly
          */
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Implementation Notice: EMBLCDS records not properly supported yet - Making up the CDNA region of this sequence... may be incorrect ("
                         + sourceDb + ":" + entry.getAccession() + ")");
         int dnaLength = dna.getLength();
         if (translationLength * 3 == (1 - codonStart + dnaLength))
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Not allowing for additional stop codon at end of cDNA fragment... !");
           // this might occur for CDS sequences where no features are marked
           exons = new int[] { dna.getStart() + (codonStart - 1),
@@ -423,7 +423,7 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
         }
         if ((translationLength + 1) * 3 == (1 - codonStart + dnaLength))
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Allowing for additional stop codon at end of cDNA fragment... will probably cause an error in VAMSAs!");
           exons = new int[] { dna.getStart() + (codonStart - 1),
               dna.getEnd() - 3 };
index bb5c165..68a7328 100644 (file)
@@ -138,7 +138,7 @@ public class Pdb extends EbiFileRetrievedProxy
 
     if (!isValidReference(id))
     {
-      System.err.println("Ignoring invalid pdb query: '" + id + "'");
+      jalview.bin.Console.errPrintln("Ignoring invalid pdb query: '" + id + "'");
       stopQuery();
       return null;
     }
index 65b9655..3eef460 100644 (file)
@@ -136,8 +136,8 @@ public class EBIFetchClient
     String database = parseIds(ids, querystring);
     if (database == null)
     {
-      System.err.println("Invalid Query string : '" + ids + "'");
-      System.err.println("Should be of form 'dbname:q1;q2;q3;q4'");
+      jalview.bin.Console.errPrintln("Invalid Query string : '" + ids + "'");
+      jalview.bin.Console.errPrintln("Should be of form 'dbname:q1;q2;q3;q4'");
       return null;
     }
 
@@ -227,11 +227,11 @@ public class EBIFetchClient
         }
         return (String[]) arl.toArray();
       }
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Warning: response code " + responseCode + " for " + url);
     } catch (OutOfMemoryError er)
     {
-      System.out.println("OUT OF MEMORY DOWNLOADING QUERY FROM " + database
+      jalview.bin.Console.outPrintln("OUT OF MEMORY DOWNLOADING QUERY FROM " + database
               + ":\n" + ids);
       throw er;
     } catch (Exception ex)
@@ -239,7 +239,7 @@ public class EBIFetchClient
       if (!ex.getMessage().startsWith(
               "uk.ac.ebi.jdbfetch.exceptions.DbfNoEntryFoundException"))
       {
-        System.err.println("Unexpected exception when retrieving from "
+        jalview.bin.Console.errPrintln("Unexpected exception when retrieving from "
                 + database + "\nQuery was : '" + ids + "'");
         ex.printStackTrace(System.err);
       }
index 022ae6d..4165eae 100644 (file)
@@ -44,7 +44,7 @@ public class Annotate3D
 
   public Annotate3D()
   {
-    System.out.println("Annotate3D");
+    jalview.bin.Console.outPrintln("Annotate3D");
     // try {
     // Create a URL for the desired page
     // String id = "1HR2";
@@ -55,7 +55,7 @@ public class Annotate3D
     // OutputStream out1 = null;
     // out = new BufferedWriter(new OutputStreamWriter(out1, "temp.rnaml"));
     // while ((str = in.readLine()) != null) {
-    // System.out.println(str);
+    // jalview.bin.Console.outPrintln(str);
     // out.write(str);
     // }
     // in.close();
@@ -117,19 +117,19 @@ public class Annotate3D
 
   public Annotate3D(String path) throws InterruptedException
   {
-    System.out.println("Annotate3D");
+    jalview.bin.Console.outPrintln("Annotate3D");
     try
     {
       // //URL url = new
       // URL("http://paradise-ibmc.u-strasbg.fr/webservices/annotate3d?data="+inFile);
-      // System.out.println("Step1");
+      // jalview.bin.Console.outPrintln("Step1");
       // FileReader r = new FileReader(inFile);
       // BufferedReader in = new BufferedReader(r);
       // StringBuffer content = new StringBuffer();
-      // System.out.println("Step2");
+      // jalview.bin.Console.outPrintln("Step2");
       // while(in.readLine()!=null){
       // content.append(in.readLine());
-      // //System.out.println("Step3"+in.readLine());
+      // //jalview.bin.Console.outPrintln("Step3"+in.readLine());
       // }
       //
       // String data = URLEncoder.encode("data", "UTF-8") + "=" +
@@ -145,21 +145,21 @@ public class Annotate3D
       // FileReader r = new FileReader(path);
       // BufferedReader in = new BufferedReader(r);
       // StringBuffer content = new StringBuffer();
-      // System.out.println("Step1");
+      // jalview.bin.Console.outPrintln("Step1");
       // while(in.readLine()!=null){
       // content.append(in.readLine());
       //
       // }
-      // System.out.println("Step2");
+      // jalview.bin.Console.outPrintln("Step2");
       // String data = URLEncoder.encode("data", "UTF-8") + "=" +
       // URLEncoder.encode(content.toString(), "UTF-8");
-      // System.out.println("Step2");
+      // jalview.bin.Console.outPrintln("Step2");
       // URL url = new
       // URL("http://paradise-ibmc.u-strasbg.fr/webservices/annotate3d?data="+data);
       // DataInputStream is = new DataInputStream(url.openStream());
       // String str;
       // while ((str = is.readLine()) != null) {
-      // System.out.println(str);
+      // jalview.bin.Console.outPrintln(str);
       // //out.write(str);
       // }
       FileReader r = new FileReader(path);
@@ -169,14 +169,14 @@ public class Annotate3D
 
       while ((str = in.readLine()) != null)
       {
-        // System.out.println(str);
+        // jalview.bin.Console.outPrintln(str);
 
         content = content + str;
       }
-      System.out.println("pdbfile=" + content.toString());
-      System.out.println("capacité=" + content.length());
+      jalview.bin.Console.outPrintln("pdbfile=" + content.toString());
+      jalview.bin.Console.outPrintln("capacité=" + content.length());
       String paramfile = URLEncoder.encode(content.toString(), "UTF-8");
-      System.out.println("param=" + paramfile);
+      jalview.bin.Console.outPrintln("param=" + paramfile);
       URL url = new URL(
               "http://paradise-ibmc.u-strasbg.fr/webservices/annotate3d?data="
                       + content);
@@ -185,7 +185,7 @@ public class Annotate3D
       String str4;
       while ((str4 = is.readLine()) != null)
       {
-        System.out.println(str4);
+        jalview.bin.Console.outPrintln(str4);
         // out.write(str);
       }
       in.close();
@@ -207,7 +207,7 @@ public class Annotate3D
       // BufferedReader in1 = new BufferedReader(is);
 
       // OutputStream out1 = null;
-      // System.out.println("Step3");
+      // jalview.bin.Console.outPrintln("Step3");
       // BufferedWriter out = new BufferedWriter(new OutputStreamWriter(out1,
       // "temp.rnaml"));
       //
@@ -216,11 +216,11 @@ public class Annotate3D
 
       // return;
 
-      // System.out.println(data.length());
-      // System.out.println("step2");
+      // jalview.bin.Console.outPrintln(data.length());
+      // jalview.bin.Console.outPrintln("step2");
       // URL url = new
       // URL("http://paradise-ibmc.u-strasbg.fr/webservices/annotate3d?data="+data);
-      // System.out.println("step3");
+      // jalview.bin.Console.outPrintln("step3");
       // URLConnection conn = url.openConnection();
       // conn.setDoOutput(true);
       // OutputStreamWriter writer = new
@@ -237,7 +237,7 @@ public class Annotate3D
       // //String line;
       // while ((line = reader.readLine()) != null) {
       // answer.append(line);
-      // System.out.println(line);
+      // jalview.bin.Console.outPrintln(line);
       // }
       // writer.close();
       // reader.close();
@@ -261,9 +261,9 @@ public class Annotate3D
   // out = new BufferedWriter(new FileWriter("temp.rnaml"));
 
   // while ((str = in.readLine()) != null) {
-  // System.out.println(str);
+  // jalview.bin.Console.outPrintln(str);
   // out.write(str);
-  // System.out.println(str);
+  // jalview.bin.Console.outPrintln(str);
   // in.close();
 
   // out.close();
@@ -275,7 +275,7 @@ public class Annotate3D
 
   // public BufferedWriter getReader()
   // {
-  // System.out.println("The buffer");
+  // jalview.bin.Console.outPrintln("The buffer");
 
   // return out;
 
index 69e47a3..d4a2fd4 100644 (file)
@@ -222,7 +222,7 @@ public class Discoverer implements Runnable
 
     } catch (Exception e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "jalview.rootRegistry is not a proper url!\nWas set to "
                       + RootServiceURL + "\n" + e);
     }
@@ -404,7 +404,7 @@ public class Discoverer implements Runnable
     WS1Client instance = serviceClientBindings.get(sh.getAbstractName());
     if (instance == null)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "WARNING - POSSIBLE IMPLEMENTATION ERROR - cannot find WSClient implementation for "
                       + sh.getAbstractName());
     }
index a39945e..a042dee 100644 (file)
@@ -480,7 +480,7 @@ class JPredThread extends JWS1Thread implements WSClientI
         wsInfo.setProgressText(j.getJobnum(),
                 "Failed to submit the prediction. (Just close the window)\n"
                         + "It is most likely that there is a problem with the server.\n");
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "JPredWS Client: Failed to submit the prediction. Quite possibly because of a server error - see below)\n"
                         + e.getMessage() + "\n");
 
index e027038..727f5be 100644 (file)
@@ -479,7 +479,7 @@ class MsaWSThread extends JWS1Thread implements WSClientI
         j.setJobId(jobsubmit.getJobId());
         j.setSubmitted(true);
         j.setSubjobComplete(false);
-        // System.out.println(WsURL + " Job Id '" + jobId + "'");
+        // jalview.bin.Console.outPrintln(WsURL + " Job Id '" + jobId + "'");
       }
       else
       {
@@ -497,7 +497,7 @@ class MsaWSThread extends JWS1Thread implements WSClientI
     {
       // TODO: JBPNote catch timeout or other fault types explicitly
       // For unexpected errors
-      System.err.println(WebServiceName
+      jalview.bin.Console.errPrintln(WebServiceName
               + "Client: Failed to submit the sequences for alignment (probably a server side problem)\n"
               + "When contacting Server:" + WsUrl + "\n" + e.toString()
               + "\n");
@@ -544,9 +544,9 @@ class MsaWSThread extends JWS1Thread implements WSClientI
           results++;
           // if (Cache.isDebugEnabled())
           // {
-          // System.out.println("Job lob for job
+          // jalview.bin.Console.outPrintln("Job lob for job
           // "+jobs[j].getJobId()+":"+jobs[j].getJobnum());
-          // System.out.println(jobs[j].getStatus());
+          // jalview.bin.Console.outPrintln(jobs[j].getStatus());
           // }
 
           vamsas.objects.simple.Alignment valign = ((MsaResult) ((MsaWSJob) jobs[j]).result)
@@ -709,7 +709,7 @@ class MsaWSThread extends JWS1Thread implements WSClientI
     }
     else
     {
-      System.out.println("MERGE WITH OLD FRAME");
+      jalview.bin.Console.outPrintln("MERGE WITH OLD FRAME");
       // TODO: modify alignment in original frame, replacing old for new
       // alignment using the commands.EditCommand model to ensure the update can
       // be undone
index 0f28230..805f64c 100644 (file)
@@ -212,9 +212,9 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
           }
         } catch (Exception e)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Failed to parse the annotation file associated with the alignment.");
-          System.err.println(">>>EOF" + inFile + "\n<<<EOF\n");
+          jalview.bin.Console.errPrintln(">>>EOF" + inFile + "\n<<<EOF\n");
           e.printStackTrace(System.err);
         }
 
@@ -229,9 +229,9 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
           }
         } catch (Exception e)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Failed to parse the Features file associated with the alignment.");
-          System.err.println(">>>EOF" + inFile + "\n<<<EOF\n");
+          jalview.bin.Console.errPrintln(">>>EOF" + inFile + "\n<<<EOF\n");
           e.printStackTrace(System.err);
         }
         jalview.io.NewickFile nf = null;
@@ -250,9 +250,9 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
           }
         } catch (Exception e)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Failed to parse the treeFile associated with the alignment.");
-          System.err.println(">>>EOF" + inFile + "\n<<<EOF\n");
+          jalview.bin.Console.errPrintln(">>>EOF" + inFile + "\n<<<EOF\n");
           e.printStackTrace(System.err);
         }
 
@@ -496,7 +496,7 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
         j.setJobId(jobsubmit.getJobId());
         j.setSubmitted(true);
         j.setSubjobComplete(false);
-        // System.out.println(WsURL + " Job Id '" + jobId + "'");
+        // jalview.bin.Console.outPrintln(WsURL + " Job Id '" + jobId + "'");
       }
       else
       {
@@ -514,7 +514,7 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
     {
       // TODO: JBPNote catch timeout or other fault types explicitly
       // For unexpected errors
-      System.err.println(WebServiceName
+      jalview.bin.Console.errPrintln(WebServiceName
               + "Client: Failed to submit the sequences for alignment (probably a server side problem)\n"
               + "When contacting Server:" + WsUrl + "\n" + e.toString()
               + "\n");
@@ -616,7 +616,7 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
   {
     if (!newFrame)
     {
-      System.err.println("MERGE WITH OLD FRAME NOT IMPLEMENTED");
+      jalview.bin.Console.errPrintln("MERGE WITH OLD FRAME NOT IMPLEMENTED");
       return;
     }
     // each subjob is an independent alignment for the moment
index 9d56de4..3b56a70 100644 (file)
@@ -259,11 +259,11 @@ public abstract class AbstractJabaCalcWorker extends AlignCalcWorker
           {
             if (cancelJob(rslt))
             {
-              System.err.println("Cancelled AACon job: " + rslt);
+              jalview.bin.Console.errPrintln("Cancelled AACon job: " + rslt);
             }
             else
             {
-              System.err.println("FAILED TO CANCEL AACon job: " + rslt);
+              jalview.bin.Console.errPrintln("FAILED TO CANCEL AACon job: " + rslt);
             }
 
           } catch (Exception x)
@@ -356,13 +356,13 @@ public abstract class AbstractJabaCalcWorker extends AlignCalcWorker
     catch (JobSubmissionException x)
     {
 
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "submission error with " + getServiceActionText() + " :");
       x.printStackTrace();
       calcMan.disableWorker(this);
     } catch (ResultNotAvailableException x)
     {
-      System.err.println("collection error:\nJob ID: " + rslt);
+      jalview.bin.Console.errPrintln("collection error:\nJob ID: " + rslt);
       x.printStackTrace();
       calcMan.disableWorker(this);
 
@@ -441,11 +441,11 @@ public abstract class AbstractJabaCalcWorker extends AlignCalcWorker
       String id = rslt;
       if (cancelJob(rslt))
       {
-        System.err.println("Cancelled job " + id);
+        jalview.bin.Console.errPrintln("Cancelled job " + id);
       }
       else
       {
-        System.err.println("Job " + id + " couldn't be cancelled.");
+        jalview.bin.Console.errPrintln("Job " + id + " couldn't be cancelled.");
       }
     } catch (Exception q)
     {
index 5e034cd..5b46a97 100644 (file)
@@ -84,7 +84,7 @@ public class JabaParamStore implements ParamDatastoreI
           }
           else
           {
-            System.err.println(
+            jalview.bin.Console.errPrintln(
                     "Warning: Ignoring parameter set instance of type "
                             + paramset.getClass()
                             + " : Bound but not applicable for service at "
index 5831df8..e4d0669 100644 (file)
@@ -117,7 +117,7 @@ public class JabaWsServerQuery implements Runnable
           registry = Jws2Client.connectToRegistry(jwsserver);
           if (registry != null)
           {
-            // System.err.println("Test Services Output\n"
+            // jalview.bin.Console.errPrintln("Test Services Output\n"
             // + registry.testAllServices());
             // TODO: enumerate services and test those that haven't been tested
             // in the last n-days/hours/etc.
@@ -126,23 +126,23 @@ public class JabaWsServerQuery implements Runnable
             srv_set = registry.getSupportedServices();
 
             // dan test
-            System.out.println(
+            jalview.bin.Console.outPrintln(
                     "registry.getSupportedServices: " + srv_set.toString());
 
             svccategories = registry.getServiceCategories();
 
             // dan test
-            // System.out.println("registry.getServiceCategories: " +
+            // jalview.bin.Console.outPrintln("registry.getServiceCategories: " +
             // svccategories.toString());
 
           }
         } catch (Exception ex)
         {
-          System.err.println("Exception whilst trying to get at registry:");
+          jalview.bin.Console.errPrintln("Exception whilst trying to get at registry:");
           ex.printStackTrace();
           // if that failed, then we are probably working with a JABAWS1 server.
           // in that case, look for each service endpoint
-          System.err.println("JWS2 Discoverer: " + jwsserver
+          jalview.bin.Console.errPrintln("JWS2 Discoverer: " + jwsserver
                   + " is a JABAWS1 server. Using hardwired list.");
           for (Services srv : JABAWS1SERVERS)
           {
@@ -169,7 +169,7 @@ public class JabaWsServerQuery implements Runnable
               service = Jws2Client.connect(jwsserver, srv);
             } catch (Exception e)
             {
-              System.err.println("Jws2 Discoverer: Problem on " + jwsserver
+              jalview.bin.Console.errPrintln("Jws2 Discoverer: Problem on " + jwsserver
                       + " with service " + srv + ":\n" + e.getMessage());
               if (!(e instanceof javax.xml.ws.WebServiceException))
               {
@@ -245,11 +245,11 @@ public class JabaWsServerQuery implements Runnable
         result = true;
       } catch (MalformedURLException e)
       {
-        System.err.println("Invalid server URL: " + server);
+        jalview.bin.Console.errPrintln("Invalid server URL: " + server);
         result = false;
       } catch (IOException e)
       {
-        System.err.println("Error connecting to server: " + server + ": "
+        jalview.bin.Console.errPrintln("Error connecting to server: " + server + ": "
                 + e.toString());
         result = false;
       }
index fc36205..47e82de 100644 (file)
@@ -142,7 +142,7 @@ public abstract class JabawsCalcWorker extends AbstractJabaCalcWorker
           List<AlignmentAnnotation> ourAnnot, String typeName,
           String calcId, SequenceI dseq, int base, Score scr)
   {
-    System.out.println("Creating annotation on dseq:" + dseq.getStart()
+    jalview.bin.Console.outPrintln("Creating annotation on dseq:" + dseq.getStart()
             + " base is " + base + " and length=" + dseq.getLength()
             + " == " + scr.getScores().size());
     // AlignmentAnnotation annotation = new AlignmentAnnotation(
index ee36d4a..13d60de 100644 (file)
@@ -156,7 +156,7 @@ public abstract class JabawsMsaInterfaceAlignCalcWorker
           List<AlignmentAnnotation> ourAnnot, String typeName,
           String calcId, SequenceI dseq, int base, Score scr)
   {
-    System.out.println("Creating annotation on dseq:" + dseq.getStart()
+    jalview.bin.Console.outPrintln("Creating annotation on dseq:" + dseq.getStart()
             + " base is " + base + " and length=" + dseq.getLength()
             + " == " + scr.getScores().size());
     // AlignmentAnnotation annotation = new AlignmentAnnotation(
index b6b4b2e..ca36a51 100644 (file)
@@ -195,7 +195,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
               .loadClass("compbio.ws.client.Jws2Client");
     } catch (ClassNotFoundException e)
     {
-      System.err.println(
+      jalview.bin.Console.errPrintln(
               "Not enabling JABA Webservices : client jar is not available."
                       + "\nPlease check that your webstart JNLP file is up to date!");
       running = false;
@@ -314,7 +314,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     {
       services = new Vector<>();
     }
-    System.out.println(
+    jalview.bin.Console.outPrintln(
             "Discovered service: " + jwsservers + " " + service.toString());
     // Jws2Instance service = new Jws2Instance(jwsservers, srv.toString(),
     // service2);
@@ -600,12 +600,12 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
               {
                 if (getDiscoverer().services != null)
                 {
-                  System.out.println("Changesupport: There are now "
+                  jalview.bin.Console.outPrintln("Changesupport: There are now "
                           + getDiscoverer().services.size() + " services");
                   int i = 1;
                   for (Jws2Instance instance : getDiscoverer().services)
                   {
-                    System.out.println("Service " + i++ + " "
+                    jalview.bin.Console.outPrintln("Service " + i++ + " "
                             + instance.getClass() + "@" + instance.getHost()
                             + ": " + instance.getActionText());
                   }
index ee0fbc5..611aa79 100644 (file)
@@ -703,7 +703,7 @@ class MsaWSThread extends AWS2Thread implements WSClientI
       {
         j.setSubmitted(true);
         j.setSubjobComplete(false);
-        // System.out.println(WsURL + " Job Id '" + jobId + "'");
+        // jalview.bin.Console.outPrintln(WsURL + " Job Id '" + jobId + "'");
         return;
       }
       else
@@ -749,7 +749,7 @@ class MsaWSThread extends AWS2Thread implements WSClientI
     } catch (Error e)
     {
       // For unexpected errors
-      System.err.println(WebServiceName
+      jalview.bin.Console.errPrintln(WebServiceName
               + "Client: Failed to submit the sequences for alignment (probably a server side problem)\n"
               + "When contacting Server:" + WsUrl + "\n");
       e.printStackTrace(System.err);
@@ -759,7 +759,7 @@ class MsaWSThread extends AWS2Thread implements WSClientI
     } catch (Exception e)
     {
       // For unexpected errors
-      System.err.println(WebServiceName
+      jalview.bin.Console.errPrintln(WebServiceName
               + "Client: Failed to submit the sequences for alignment (probably a server side problem)\n"
               + "When contacting Server:" + WsUrl + "\n");
       e.printStackTrace(System.err);
@@ -837,10 +837,10 @@ class MsaWSThread extends AWS2Thread implements WSClientI
 
           if (Console.isDebugEnabled())
           {
-            System.out.println("Job Execution file for job: "
+            jalview.bin.Console.outPrintln("Job Execution file for job: "
                     + msjob.getJobId() + " on server " + WsUrl);
-            System.out.println(msjob.getStatus());
-            System.out.println("*** End of status");
+            jalview.bin.Console.outPrintln(msjob.getStatus());
+            jalview.bin.Console.outPrintln("*** End of status");
 
           }
           try
@@ -986,7 +986,7 @@ class MsaWSThread extends AWS2Thread implements WSClientI
     else
     {
       // TODO 2.9.x feature
-      System.out.println("MERGE WITH OLD FRAME");
+      jalview.bin.Console.outPrintln("MERGE WITH OLD FRAME");
       // TODO: modify alignment in original frame, replacing old for new
       // alignment using the commands.EditCommand model to ensure the update can
       // be undone
index c7fad05..0fb36ad 100644 (file)
@@ -79,7 +79,7 @@ public class ParameterUtils
       Option o = options.getArgumentByOptionName(oname);
       if (o == null)
       {
-        System.out.println("WARN ignoring unsuppoted parameter: " + oname);
+        jalview.bin.Console.outPrintln("WARN ignoring unsuppoted parameter: " + oname);
         continue;
       }
       if (o instanceof Parameter)
@@ -98,7 +98,7 @@ public class ParameterUtils
                   : param);
         } catch (WrongParameterException e)
         {
-          System.out.println(
+          jalview.bin.Console.outPrintln(
                   "Problem setting value for the parameter: " + param);
           e.printStackTrace();
         }
index e092192..9e49ce7 100644 (file)
@@ -114,7 +114,7 @@ public class Jws2Instance implements AutoCloseable
         }
       } catch (Exception ex)
       {
-        System.err.println("Exception when retrieving presets for service "
+        jalview.bin.Console.errPrintln("Exception when retrieving presets for service "
                 + serviceType + " at " + hosturl);
       }
     }
@@ -128,7 +128,7 @@ public class Jws2Instance implements AutoCloseable
      * try { URL serviceurl = new URL(hosturl); if (serviceurl.getPort()!=80) {
      * return serviceurl.getHost()+":"+serviceurl.getPort(); } return
      * serviceurl.getHost(); } catch (Exception e) {
-     * System.err.println("Failed to parse service URL '" + hosturl +
+     * jalview.bin.Console.errPrintln("Failed to parse service URL '" + hosturl +
      * "' as a valid URL!"); } return null;
      */
   }
@@ -190,7 +190,7 @@ public class Jws2Instance implements AutoCloseable
                         : null));
       } catch (Exception ex)
       {
-        System.err.println("Unexpected exception creating JabaParamStore.");
+        jalview.bin.Console.errPrintln("Unexpected exception creating JabaParamStore.");
         ex.printStackTrace();
       }
 
index fb291da..6ac720a 100644 (file)
@@ -142,7 +142,7 @@ public abstract class InputType
       }
     } catch (Exception ex)
     {
-      System.err.println("Couldn't transform string\n" + content
+      jalview.bin.Console.errPrintln("Couldn't transform string\n" + content
               + "\nException was :");
       ex.printStackTrace(System.err);
     }
index 255ab58..450f1b4 100644 (file)
@@ -134,7 +134,7 @@ public class RestClient extends WSClient
   @Override
   public void cancelJob()
   {
-    System.err.println("Cannot cancel this job type: " + service);
+    jalview.bin.Console.errPrintln("Cannot cancel this job type: " + service);
   }
 
   @Override
@@ -418,7 +418,7 @@ public class RestClient extends WSClient
         }
       } catch (Exception ex)
       {
-        System.err.println(
+        jalview.bin.Console.errPrintln(
                 "Serious - RSBS descriptions in user preferences are corrupt!");
         ex.printStackTrace();
       }
index eff38fb..c8efcda 100644 (file)
@@ -422,7 +422,7 @@ public class RestJobThread extends AWSThread
   public void pollJob(AWsJob job) throws Exception
   {
     assert (job instanceof RestJob);
-    System.err.println("Debug RestJob: Polling Job");
+    jalview.bin.Console.errPrintln("Debug RestJob: Polling Job");
     doPoll((RestJob) job);
   }
 
@@ -432,7 +432,7 @@ public class RestJobThread extends AWSThread
     assert (job instanceof RestJob);
     try
     {
-      System.err.println("Debug RestJob: Posting Job");
+      jalview.bin.Console.errPrintln("Debug RestJob: Posting Job");
       doPost((RestJob) job);
     } catch (NoValidInputDataException erex)
     {
@@ -1258,7 +1258,7 @@ public class RestJobThread extends AWSThread
         if (!rj.hasValidInput())
         {
           // invalid input for this job
-          System.err.println("Job " + rj.getJobnum()
+          jalview.bin.Console.errPrintln("Job " + rj.getJobnum()
                   + " has invalid input. ( " + rj.getStatus() + ")");
           if (rj.hasStatus() && !_warnings.contains(rj.getStatus()))
           {
index 0d0a314..374147a 100644 (file)
@@ -191,9 +191,9 @@ public class ASequenceFetcher
               seqset = fetcher.getSequenceRecords(qsb.toString());
             } catch (Exception ex)
             {
-              System.err.println(
+              jalview.bin.Console.errPrintln(
                       "Failed to retrieve the following from " + db);
-              System.err.println(qsb);
+              jalview.bin.Console.errPrintln(qsb);
               ex.printStackTrace(System.err);
             }
             // TODO: Merge alignment together - perhaps
@@ -222,7 +222,7 @@ public class ASequenceFetcher
               {
                 if (fetcher.getRawRecords() != null)
                 {
-                  System.out.println(
+                  jalview.bin.Console.outPrintln(
                           "# Retrieved from " + db + ":" + qsb.toString());
                   StringBuffer rrb = fetcher.getRawRecords();
                   /*
@@ -235,12 +235,12 @@ public class ASequenceFetcher
                   /*
                    * } else { hdr = "# part "+rr; }
                    */
-                  System.out.println(hdr);
+                  jalview.bin.Console.outPrintln(hdr);
                   if (rrb != null)
                   {
-                    System.out.println(rrb);
+                    jalview.bin.Console.outPrintln(rrb);
                   }
-                  System.out.println("# end of " + hdr);
+                  jalview.bin.Console.outPrintln("# end of " + hdr);
                 }
 
               }
@@ -253,7 +253,7 @@ public class ASequenceFetcher
         }
         if (queriesMade.size() > 0)
         {
-          System.out.println("# Adding " + queriesMade.size()
+          jalview.bin.Console.outPrintln("# Adding " + queriesMade.size()
                   + " ids back to queries list for searching again (" + db
                   + ")");
           queriesLeft.addAll(queriesMade);
@@ -279,7 +279,7 @@ public class ASequenceFetcher
           Exception ex)
   {
 
-    System.err.println(
+    jalview.bin.Console.errPrintln(
             "Failed to retrieve the following references from " + db);
     int n = 0;
     for (String qv : queriesMade)
@@ -287,11 +287,11 @@ public class ASequenceFetcher
       System.err.print(" " + qv + ";");
       if (n++ > 10)
       {
-        System.err.println();
+        jalview.bin.Console.errPrintln();
         n = 0;
       }
     }
-    System.err.println();
+    jalview.bin.Console.errPrintln();
     ex.printStackTrace();
   }
 
index 0c707e5..92cb7af 100644 (file)
@@ -57,6 +57,7 @@ import jalview.analysis.scoremodels.ScoreMatrix;
 import jalview.analysis.scoremodels.ScoreModels;
 import jalview.api.DBRefEntryI;
 import jalview.api.SiftsClientI;
+import jalview.bin.Console;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceI;
@@ -116,7 +117,7 @@ public class SiftsClient implements SiftsClientI
 
   private static final String NOT_OBSERVED = "Not_Observed";
 
-  private static final String SIFTS_FTP_BASE_URL = "http://ftp.ebi.ac.uk/pub/databases/msd/sifts/xml/";
+  private static final String SIFTS_SPLIT_FTP_BASE_URL = "https://ftp.ebi.ac.uk/pub/databases/msd/sifts/split_xml/";
 
   private final static String NEWLINE = System.lineSeparator();
 
@@ -188,7 +189,7 @@ public class SiftsClient implements SiftsClientI
     try (InputStream in = new FileInputStream(siftFile);
             GZIPInputStream gzis = new GZIPInputStream(in);)
     {
-      // System.out.println("File : " + siftFile.getAbsolutePath());
+      // jalview.bin.Console.outPrintln("File : " + siftFile.getAbsolutePath());
       JAXBContext jc = JAXBContext.newInstance("jalview.xml.binding.sifts");
       XMLStreamReader streamReader = XMLInputFactory.newInstance()
               .createXMLStreamReader(gzis);
@@ -226,7 +227,7 @@ public class SiftsClient implements SiftsClientI
     if (siftsFile.exists())
     {
       // The line below is required for unit testing... don't comment it out!!!
-      System.out.println(">>> SIFTS File already downloaded for " + pdbId);
+      jalview.bin.Console.outPrintln(">>> SIFTS File already downloaded for " + pdbId);
 
       if (isFileOlderThanThreshold(siftsFile,
               SiftsSettings.getCacheThresholdInDays()))
@@ -281,7 +282,7 @@ public class SiftsClient implements SiftsClientI
       diffInDays = (int) ((new Date().getTime()
               - attr.lastModifiedTime().toMillis())
               / (1000 * 60 * 60 * 24));
-      // System.out.println("Diff in days : " + diffInDays);
+      // jalview.bin.Console.outPrintln("Diff in days : " + diffInDays);
     } catch (IOException e)
     {
       e.printStackTrace();
@@ -305,7 +306,7 @@ public class SiftsClient implements SiftsClientI
       pdbId = pdbId.replace(".cif", "");
     }
     String siftFile = pdbId + ".xml.gz";
-    String siftsFileFTPURL = SIFTS_FTP_BASE_URL + siftFile;
+    String siftsFileFTPURL = getDownloadUrlFor(siftFile);
 
     /*
      * Download the file from URL to either
@@ -329,7 +330,7 @@ public class SiftsClient implements SiftsClientI
       }
     }
 
-    // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
+    // jalview.bin.Console.outPrintln(">> Download ftp url : " + siftsFileFTPURL);
     // long now = System.currentTimeMillis();
     URL url = new URL(siftsFileFTPURL);
     URLConnection conn = url.openConnection();
@@ -343,11 +344,19 @@ public class SiftsClient implements SiftsClientI
     }
     outputStream.close();
     inputStream.close();
-    // System.out.println(">>> File downloaded : " + downloadedSiftsFile
+    // jalview.bin.Console.outPrintln(">>> File downloaded : " + downloadedSiftsFile
     // + " took " + (System.currentTimeMillis() - now) + "ms");
     return downloadTo;
   }
 
+  public static String getDownloadUrlFor(String siftFile)
+  {
+    String durl = SIFTS_SPLIT_FTP_BASE_URL+siftFile.substring(1, 3)+"/"+siftFile;
+    Console.trace("SIFTS URL for "+siftFile+" is "+durl);
+    return durl;
+    
+  }
+
   /**
    * Delete the SIFTs file for the given PDB Id in the local SIFTs download
    * directory
@@ -450,7 +459,7 @@ public class SiftsClient implements SiftsClientI
       seq = seq.getDatasetSequence();
     }
     structId = (chain == null) ? pdbId : pdbId + "|" + chain;
-    System.out.println("Getting SIFTS mapping for " + structId + ": seq "
+    jalview.bin.Console.outPrintln("Getting SIFTS mapping for " + structId + ": seq "
             + seq.getName());
 
     final StringBuilder mappingDetails = new StringBuilder(128);
@@ -483,7 +492,7 @@ public class SiftsClient implements SiftsClientI
   {
     List<Integer> omitNonObserved = new ArrayList<>();
     int nonObservedShiftIndex = 0, pdbeNonObserved = 0;
-    // System.out.println("Generating mappings for : " + entityId);
+    // jalview.bin.Console.outPrintln("Generating mappings for : " + entityId);
     Entity entity = null;
     entity = getEntityById(entityId);
     String originalSeq = AlignSeq.extractGaps(
@@ -535,7 +544,7 @@ public class SiftsClient implements SiftsClientI
 
     if (mapping.isEmpty())
     {
-      throw new SiftsException("SIFTS mapping failed");
+      throw new SiftsException("SIFTS mapping failed for "+entityId+" and "+seq.getName());
     }
     // also construct a mapping object between the seq-coord sys and the PDB
     // seq's coord sys
@@ -653,7 +662,7 @@ public class SiftsClient implements SiftsClientI
     int firstPDBResNum = UNASSIGNED;
     for (Segment segment : segments)
     {
-      // System.out.println("Mapping segments : " + segment.getSegId() + "\\"s
+      // jalview.bin.Console.outPrintln("Mapping segments : " + segment.getSegId() + "\\"s
       // + segStartEnd);
       List<Residue> residues = segment.getListResidue().getResidue();
       for (Residue residue : residues)
@@ -922,8 +931,8 @@ public class SiftsClient implements SiftsClientI
     // Arrays.sort(keys);
     int firstIndex = keys[0];
     int lastIndex = keys[keys.length - 1];
-    // System.out.println("Min value " + firstIndex);
-    // System.out.println("Max value " + lastIndex);
+    // jalview.bin.Console.outPrintln("Min value " + firstIndex);
+    // jalview.bin.Console.outPrintln("Max value " + lastIndex);
     for (int x = firstIndex; x <= lastIndex; x++)
     {
       if (!resNumMap.containsKey(x) && !omitNonObserved.contains(x))
@@ -956,7 +965,7 @@ public class SiftsClient implements SiftsClientI
    */
   public Entity getEntityByMostOptimalMatchedId(String chainId)
   {
-    // System.out.println("---> advanced greedy entityId matching block
+    // jalview.bin.Console.outPrintln("---> advanced greedy entityId matching block
     // entered..");
     List<Entity> entities = siftsEntry.getEntity();
     SiftsEntitySortPojo[] sPojo = new SiftsEntitySortPojo[entities.size()];
@@ -992,8 +1001,8 @@ public class SiftsClient implements SiftsClientI
       ++count;
     }
     Arrays.sort(sPojo, Collections.reverseOrder());
-    // System.out.println("highest matched entity : " + sPojo[0].entityId);
-    // System.out.println("highest matched pid : " + sPojo[0].pid);
+    // jalview.bin.Console.outPrintln("highest matched entity : " + sPojo[0].entityId);
+    // jalview.bin.Console.outPrintln("highest matched pid : " + sPojo[0].pid);
 
     if (sPojo[0].entityId != null)
     {
index e2fb1b8..8299b02 100644 (file)
@@ -78,7 +78,7 @@ public class UrlDownloadClient
         }
       } catch (IOException e)
       {
-        System.out.println(
+        jalview.bin.Console.outPrintln(
                 "Exception while closing download file output stream: "
                         + e.getMessage());
       }
@@ -90,7 +90,7 @@ public class UrlDownloadClient
         }
       } catch (IOException e)
       {
-        System.out.println("Exception while closing download channel: "
+        jalview.bin.Console.outPrintln("Exception while closing download channel: "
                 + e.getMessage());
       }
       try
@@ -101,7 +101,7 @@ public class UrlDownloadClient
         }
       } catch (IOException e)
       {
-        System.out.println("Exception while deleting download temp file: "
+        jalview.bin.Console.outPrintln("Exception while deleting download temp file: "
                 + e.getMessage());
       }
     }
index 0479a34..0ec8f0b 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:45 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.embl;
 
 import java.util.ArrayList;
@@ -15,11 +14,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for EntrySetType complex type.
+ * <p>
+ * Java class for EntrySetType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="EntrySetType">
@@ -36,41 +37,42 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "EntrySetType", propOrder = {
-    "entry"
-})
-public class EntrySetType {
+@XmlType(name = "EntrySetType", propOrder = { "entry" })
+public class EntrySetType
+{
 
-    @XmlElement(required = true)
-    protected List<EntryType> entry;
+  @XmlElement(required = true)
+  protected List<EntryType> entry;
 
-    /**
-     * Gets the value of the entry property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the entry property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEntry().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EntryType }
-     * 
-     * 
-     */
-    public List<EntryType> getEntry() {
-        if (entry == null) {
-            entry = new ArrayList<EntryType>();
-        }
-        return this.entry;
+  /**
+   * Gets the value of the entry property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the entry property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEntry().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link EntryType }
+   * 
+   * 
+   */
+  public List<EntryType> getEntry()
+  {
+    if (entry == null)
+    {
+      entry = new ArrayList<EntryType>();
     }
+    return this.entry;
+  }
 
 }
index 6336ef1..d90651c 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:45 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.embl;
 
 import java.math.BigInteger;
@@ -20,11 +19,13 @@ import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.datatype.XMLGregorianCalendar;
 
-
 /**
- * <p>Java class for EntryType complex type.
+ * <p>
+ * Java class for EntryType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="EntryType">
@@ -225,669 +226,1666 @@ import javax.xml.datatype.XMLGregorianCalendar;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "EntryType", propOrder = {
-    "secondaryAccession",
-    "projectAccession",
-    "description",
-    "comment",
-    "keyword",
-    "reference",
-    "xref",
-    "feature",
-    "assembly",
-    "contig",
-    "sequence"
-})
-public class EntryType {
-
-    protected List<String> secondaryAccession;
-    protected List<String> projectAccession;
+@XmlType(
+  name = "EntryType",
+  propOrder =
+  { "secondaryAccession", "projectAccession", "description", "comment",
+      "keyword", "reference", "xref", "feature", "assembly", "contig",
+      "sequence" })
+public class EntryType
+{
+
+  protected List<String> secondaryAccession;
+
+  protected List<String> projectAccession;
+
+  @XmlElement(required = true)
+  protected String description;
+
+  protected String comment;
+
+  protected List<String> keyword;
+
+  protected List<EntryType.Reference> reference;
+
+  protected List<XrefType> xref;
+
+  protected List<EntryType.Feature> feature;
+
+  protected EntryType.Assembly assembly;
+
+  protected EntryType.Contig contig;
+
+  protected String sequence;
+
+  @XmlAttribute(name = "accession", required = true)
+  protected String accession;
+
+  @XmlAttribute(name = "version", required = true)
+  protected BigInteger version;
+
+  @XmlAttribute(name = "entryVersion")
+  protected BigInteger entryVersion;
+
+  @XmlAttribute(name = "dataClass", required = true)
+  protected String dataClass;
+
+  @XmlAttribute(name = "taxonomicDivision", required = true)
+  protected String taxonomicDivision;
+
+  @XmlAttribute(name = "moleculeType", required = true)
+  protected String moleculeType;
+
+  @XmlAttribute(name = "sequenceLength", required = true)
+  protected BigInteger sequenceLength;
+
+  @XmlAttribute(name = "topology", required = true)
+  protected String topology;
+
+  @XmlAttribute(name = "firstPublic")
+  @XmlSchemaType(name = "date")
+  protected XMLGregorianCalendar firstPublic;
+
+  @XmlAttribute(name = "firstPublicRelease")
+  protected BigInteger firstPublicRelease;
+
+  @XmlAttribute(name = "lastUpdated")
+  @XmlSchemaType(name = "date")
+  protected XMLGregorianCalendar lastUpdated;
+
+  @XmlAttribute(name = "lastUpdatedRelease")
+  protected BigInteger lastUpdatedRelease;
+
+  /**
+   * Gets the value of the secondaryAccession property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the secondaryAccession property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getSecondaryAccession().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getSecondaryAccession()
+  {
+    if (secondaryAccession == null)
+    {
+      secondaryAccession = new ArrayList<String>();
+    }
+    return this.secondaryAccession;
+  }
+
+  /**
+   * Gets the value of the projectAccession property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the projectAccession property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getProjectAccession().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getProjectAccession()
+  {
+    if (projectAccession == null)
+    {
+      projectAccession = new ArrayList<String>();
+    }
+    return this.projectAccession;
+  }
+
+  /**
+   * Gets the value of the description property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /**
+   * Sets the value of the description property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDescription(String value)
+  {
+    this.description = value;
+  }
+
+  /**
+   * Gets the value of the comment property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getComment()
+  {
+    return comment;
+  }
+
+  /**
+   * Sets the value of the comment property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setComment(String value)
+  {
+    this.comment = value;
+  }
+
+  /**
+   * Gets the value of the keyword property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the keyword property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getKeyword().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getKeyword()
+  {
+    if (keyword == null)
+    {
+      keyword = new ArrayList<String>();
+    }
+    return this.keyword;
+  }
+
+  /**
+   * Gets the value of the reference property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the reference property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getReference().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EntryType.Reference }
+   * 
+   * 
+   */
+  public List<EntryType.Reference> getReference()
+  {
+    if (reference == null)
+    {
+      reference = new ArrayList<EntryType.Reference>();
+    }
+    return this.reference;
+  }
+
+  /**
+   * Gets the value of the xref property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the xref property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getXref().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link XrefType }
+   * 
+   * 
+   */
+  public List<XrefType> getXref()
+  {
+    if (xref == null)
+    {
+      xref = new ArrayList<XrefType>();
+    }
+    return this.xref;
+  }
+
+  /**
+   * Gets the value of the feature property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the feature property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getFeature().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EntryType.Feature }
+   * 
+   * 
+   */
+  public List<EntryType.Feature> getFeature()
+  {
+    if (feature == null)
+    {
+      feature = new ArrayList<EntryType.Feature>();
+    }
+    return this.feature;
+  }
+
+  /**
+   * Gets the value of the assembly property.
+   * 
+   * @return possible object is {@link EntryType.Assembly }
+   * 
+   */
+  public EntryType.Assembly getAssembly()
+  {
+    return assembly;
+  }
+
+  /**
+   * Sets the value of the assembly property.
+   * 
+   * @param value
+   *          allowed object is {@link EntryType.Assembly }
+   * 
+   */
+  public void setAssembly(EntryType.Assembly value)
+  {
+    this.assembly = value;
+  }
+
+  /**
+   * Gets the value of the contig property.
+   * 
+   * @return possible object is {@link EntryType.Contig }
+   * 
+   */
+  public EntryType.Contig getContig()
+  {
+    return contig;
+  }
+
+  /**
+   * Sets the value of the contig property.
+   * 
+   * @param value
+   *          allowed object is {@link EntryType.Contig }
+   * 
+   */
+  public void setContig(EntryType.Contig value)
+  {
+    this.contig = value;
+  }
+
+  /**
+   * Gets the value of the sequence property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getSequence()
+  {
+    return sequence;
+  }
+
+  /**
+   * Sets the value of the sequence property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setSequence(String value)
+  {
+    this.sequence = value;
+  }
+
+  /**
+   * Gets the value of the accession property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getAccession()
+  {
+    return accession;
+  }
+
+  /**
+   * Sets the value of the accession property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setAccession(String value)
+  {
+    this.accession = value;
+  }
+
+  /**
+   * Gets the value of the version property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getVersion()
+  {
+    return version;
+  }
+
+  /**
+   * Sets the value of the version property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setVersion(BigInteger value)
+  {
+    this.version = value;
+  }
+
+  /**
+   * Gets the value of the entryVersion property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getEntryVersion()
+  {
+    return entryVersion;
+  }
+
+  /**
+   * Sets the value of the entryVersion property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setEntryVersion(BigInteger value)
+  {
+    this.entryVersion = value;
+  }
+
+  /**
+   * Gets the value of the dataClass property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDataClass()
+  {
+    return dataClass;
+  }
+
+  /**
+   * Sets the value of the dataClass property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDataClass(String value)
+  {
+    this.dataClass = value;
+  }
+
+  /**
+   * Gets the value of the taxonomicDivision property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getTaxonomicDivision()
+  {
+    return taxonomicDivision;
+  }
+
+  /**
+   * Sets the value of the taxonomicDivision property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setTaxonomicDivision(String value)
+  {
+    this.taxonomicDivision = value;
+  }
+
+  /**
+   * Gets the value of the moleculeType property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getMoleculeType()
+  {
+    return moleculeType;
+  }
+
+  /**
+   * Sets the value of the moleculeType property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setMoleculeType(String value)
+  {
+    this.moleculeType = value;
+  }
+
+  /**
+   * Gets the value of the sequenceLength property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getSequenceLength()
+  {
+    return sequenceLength;
+  }
+
+  /**
+   * Sets the value of the sequenceLength property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setSequenceLength(BigInteger value)
+  {
+    this.sequenceLength = value;
+  }
+
+  /**
+   * Gets the value of the topology property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getTopology()
+  {
+    return topology;
+  }
+
+  /**
+   * Sets the value of the topology property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setTopology(String value)
+  {
+    this.topology = value;
+  }
+
+  /**
+   * Gets the value of the firstPublic property.
+   * 
+   * @return possible object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public XMLGregorianCalendar getFirstPublic()
+  {
+    return firstPublic;
+  }
+
+  /**
+   * Sets the value of the firstPublic property.
+   * 
+   * @param value
+   *          allowed object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public void setFirstPublic(XMLGregorianCalendar value)
+  {
+    this.firstPublic = value;
+  }
+
+  /**
+   * Gets the value of the firstPublicRelease property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getFirstPublicRelease()
+  {
+    return firstPublicRelease;
+  }
+
+  /**
+   * Sets the value of the firstPublicRelease property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setFirstPublicRelease(BigInteger value)
+  {
+    this.firstPublicRelease = value;
+  }
+
+  /**
+   * Gets the value of the lastUpdated property.
+   * 
+   * @return possible object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public XMLGregorianCalendar getLastUpdated()
+  {
+    return lastUpdated;
+  }
+
+  /**
+   * Sets the value of the lastUpdated property.
+   * 
+   * @param value
+   *          allowed object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public void setLastUpdated(XMLGregorianCalendar value)
+  {
+    this.lastUpdated = value;
+  }
+
+  /**
+   * Gets the value of the lastUpdatedRelease property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getLastUpdatedRelease()
+  {
+    return lastUpdatedRelease;
+  }
+
+  /**
+   * Sets the value of the lastUpdatedRelease property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setLastUpdatedRelease(BigInteger value)
+  {
+    this.lastUpdatedRelease = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="range" maxOccurs="unbounded">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                 &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                 &lt;attribute name="primaryBegin" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                 &lt;attribute name="primaryEnd" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                 &lt;attribute name="accession" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                 &lt;attribute name="complement" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "range" })
+  public static class Assembly
+  {
+
     @XmlElement(required = true)
-    protected String description;
-    protected String comment;
-    protected List<String> keyword;
-    protected List<EntryType.Reference> reference;
-    protected List<XrefType> xref;
-    protected List<EntryType.Feature> feature;
-    protected EntryType.Assembly assembly;
-    protected EntryType.Contig contig;
-    protected String sequence;
-    @XmlAttribute(name = "accession", required = true)
-    protected String accession;
-    @XmlAttribute(name = "version", required = true)
-    protected BigInteger version;
-    @XmlAttribute(name = "entryVersion")
-    protected BigInteger entryVersion;
-    @XmlAttribute(name = "dataClass", required = true)
-    protected String dataClass;
-    @XmlAttribute(name = "taxonomicDivision", required = true)
-    protected String taxonomicDivision;
-    @XmlAttribute(name = "moleculeType", required = true)
-    protected String moleculeType;
-    @XmlAttribute(name = "sequenceLength", required = true)
-    protected BigInteger sequenceLength;
-    @XmlAttribute(name = "topology", required = true)
-    protected String topology;
-    @XmlAttribute(name = "firstPublic")
-    @XmlSchemaType(name = "date")
-    protected XMLGregorianCalendar firstPublic;
-    @XmlAttribute(name = "firstPublicRelease")
-    protected BigInteger firstPublicRelease;
-    @XmlAttribute(name = "lastUpdated")
-    @XmlSchemaType(name = "date")
-    protected XMLGregorianCalendar lastUpdated;
-    @XmlAttribute(name = "lastUpdatedRelease")
-    protected BigInteger lastUpdatedRelease;
+    protected List<EntryType.Assembly.Range> range;
 
     /**
-     * Gets the value of the secondaryAccession property.
+     * Gets the value of the range property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the secondaryAccession property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the range property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getSecondaryAccession().add(newItem);
+     * getRange().add(newItem);
      * </pre>
      * 
      * 
      * <p>
      * Objects of the following type(s) are allowed in the list
-     * {@link String }
+     * {@link EntryType.Assembly.Range }
      * 
      * 
      */
-    public List<String> getSecondaryAccession() {
-        if (secondaryAccession == null) {
-            secondaryAccession = new ArrayList<String>();
-        }
-        return this.secondaryAccession;
+    public List<EntryType.Assembly.Range> getRange()
+    {
+      if (range == null)
+      {
+        range = new ArrayList<EntryType.Assembly.Range>();
+      }
+      return this.range;
     }
 
     /**
-     * Gets the value of the projectAccession property.
-     * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the projectAccession property.
+     * Java class for anonymous complex type.
      * 
      * <p>
-     * For example, to add a new item, do as follows:
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
      * <pre>
-     *    getProjectAccession().add(newItem);
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="primaryBegin" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="primaryEnd" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="accession" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="complement" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
      * </pre>
      * 
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
      */
-    public List<String> getProjectAccession() {
-        if (projectAccession == null) {
-            projectAccession = new ArrayList<String>();
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Range
+    {
+
+      @XmlAttribute(name = "begin", required = true)
+      protected BigInteger begin;
+
+      @XmlAttribute(name = "end", required = true)
+      protected BigInteger end;
+
+      @XmlAttribute(name = "primaryBegin")
+      protected BigInteger primaryBegin;
+
+      @XmlAttribute(name = "primaryEnd")
+      protected BigInteger primaryEnd;
+
+      @XmlAttribute(name = "accession", required = true)
+      protected String accession;
+
+      @XmlAttribute(name = "version", required = true)
+      protected BigInteger version;
+
+      @XmlAttribute(name = "complement")
+      protected Boolean complement;
+
+      /**
+       * Gets the value of the begin property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getBegin()
+      {
+        return begin;
+      }
+
+      /**
+       * Sets the value of the begin property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setBegin(BigInteger value)
+      {
+        this.begin = value;
+      }
+
+      /**
+       * Gets the value of the end property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getEnd()
+      {
+        return end;
+      }
+
+      /**
+       * Sets the value of the end property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setEnd(BigInteger value)
+      {
+        this.end = value;
+      }
+
+      /**
+       * Gets the value of the primaryBegin property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getPrimaryBegin()
+      {
+        return primaryBegin;
+      }
+
+      /**
+       * Sets the value of the primaryBegin property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setPrimaryBegin(BigInteger value)
+      {
+        this.primaryBegin = value;
+      }
+
+      /**
+       * Gets the value of the primaryEnd property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getPrimaryEnd()
+      {
+        return primaryEnd;
+      }
+
+      /**
+       * Sets the value of the primaryEnd property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setPrimaryEnd(BigInteger value)
+      {
+        this.primaryEnd = value;
+      }
+
+      /**
+       * Gets the value of the accession property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getAccession()
+      {
+        return accession;
+      }
+
+      /**
+       * Sets the value of the accession property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setAccession(String value)
+      {
+        this.accession = value;
+      }
+
+      /**
+       * Gets the value of the version property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getVersion()
+      {
+        return version;
+      }
+
+      /**
+       * Sets the value of the version property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setVersion(BigInteger value)
+      {
+        this.version = value;
+      }
+
+      /**
+       * Gets the value of the complement property.
+       * 
+       * @return possible object is {@link Boolean }
+       * 
+       */
+      public boolean isComplement()
+      {
+        if (complement == null)
+        {
+          return false;
         }
-        return this.projectAccession;
-    }
-
-    /**
-     * Gets the value of the description property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDescription() {
-        return description;
-    }
-
-    /**
-     * Sets the value of the description property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDescription(String value) {
-        this.description = value;
-    }
+        else
+        {
+          return complement;
+        }
+      }
+
+      /**
+       * Sets the value of the complement property.
+       * 
+       * @param value
+       *          allowed object is {@link Boolean }
+       * 
+       */
+      public void setComplement(Boolean value)
+      {
+        this.complement = value;
+      }
 
-    /**
-     * Gets the value of the comment property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getComment() {
-        return comment;
     }
 
-    /**
-     * Sets the value of the comment property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setComment(String value) {
-        this.comment = value;
-    }
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;choice maxOccurs="unbounded" minOccurs="0">
+   *           &lt;element name="range">
+   *             &lt;complexType>
+   *               &lt;complexContent>
+   *                 &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                   &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                   &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                   &lt;attribute name="primaryBegin" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                   &lt;attribute name="primaryEnd" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                   &lt;attribute name="accession" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                   &lt;attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                   &lt;attribute name="complement" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *                 &lt;/restriction>
+   *               &lt;/complexContent>
+   *             &lt;/complexType>
+   *           &lt;/element>
+   *           &lt;element name="gap">
+   *             &lt;complexType>
+   *               &lt;complexContent>
+   *                 &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                   &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                   &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                   &lt;attribute name="length" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *                   &lt;attribute name="unknownLength" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *                 &lt;/restriction>
+   *               &lt;/complexContent>
+   *             &lt;/complexType>
+   *           &lt;/element>
+   *         &lt;/choice>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "rangeOrGap" })
+  public static class Contig
+  {
+
+    @XmlElements({
+        @XmlElement(name = "range", type = EntryType.Contig.Range.class),
+        @XmlElement(name = "gap", type = EntryType.Contig.Gap.class) })
+    protected List<Object> rangeOrGap;
 
     /**
-     * Gets the value of the keyword property.
+     * Gets the value of the rangeOrGap property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the keyword property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the rangeOrGap property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
-     * <pre>
-     *    getKeyword().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getKeyword() {
-        if (keyword == null) {
-            keyword = new ArrayList<String>();
-        }
-        return this.keyword;
-    }
-
-    /**
-     * Gets the value of the reference property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the reference property.
      * 
-     * <p>
-     * For example, to add a new item, do as follows:
      * <pre>
-     *    getReference().add(newItem);
+     * getRangeOrGap().add(newItem);
      * </pre>
      * 
      * 
      * <p>
      * Objects of the following type(s) are allowed in the list
-     * {@link EntryType.Reference }
+     * {@link EntryType.Contig.Range } {@link EntryType.Contig.Gap }
      * 
      * 
      */
-    public List<EntryType.Reference> getReference() {
-        if (reference == null) {
-            reference = new ArrayList<EntryType.Reference>();
-        }
-        return this.reference;
+    public List<Object> getRangeOrGap()
+    {
+      if (rangeOrGap == null)
+      {
+        rangeOrGap = new ArrayList<Object>();
+      }
+      return this.rangeOrGap;
     }
 
     /**
-     * Gets the value of the xref property.
-     * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the xref property.
+     * Java class for anonymous complex type.
      * 
      * <p>
-     * For example, to add a new item, do as follows:
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
      * <pre>
-     *    getXref().add(newItem);
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="length" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="unknownLength" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
      * </pre>
      * 
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link XrefType }
-     * 
-     * 
      */
-    public List<XrefType> getXref() {
-        if (xref == null) {
-            xref = new ArrayList<XrefType>();
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Gap
+    {
+
+      @XmlAttribute(name = "begin", required = true)
+      protected BigInteger begin;
+
+      @XmlAttribute(name = "end", required = true)
+      protected BigInteger end;
+
+      @XmlAttribute(name = "length", required = true)
+      protected BigInteger length;
+
+      @XmlAttribute(name = "unknownLength")
+      protected Boolean unknownLength;
+
+      /**
+       * Gets the value of the begin property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getBegin()
+      {
+        return begin;
+      }
+
+      /**
+       * Sets the value of the begin property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setBegin(BigInteger value)
+      {
+        this.begin = value;
+      }
+
+      /**
+       * Gets the value of the end property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getEnd()
+      {
+        return end;
+      }
+
+      /**
+       * Sets the value of the end property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setEnd(BigInteger value)
+      {
+        this.end = value;
+      }
+
+      /**
+       * Gets the value of the length property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getLength()
+      {
+        return length;
+      }
+
+      /**
+       * Sets the value of the length property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setLength(BigInteger value)
+      {
+        this.length = value;
+      }
+
+      /**
+       * Gets the value of the unknownLength property.
+       * 
+       * @return possible object is {@link Boolean }
+       * 
+       */
+      public boolean isUnknownLength()
+      {
+        if (unknownLength == null)
+        {
+          return false;
+        }
+        else
+        {
+          return unknownLength;
         }
-        return this.xref;
+      }
+
+      /**
+       * Sets the value of the unknownLength property.
+       * 
+       * @param value
+       *          allowed object is {@link Boolean }
+       * 
+       */
+      public void setUnknownLength(Boolean value)
+      {
+        this.unknownLength = value;
+      }
+
     }
 
     /**
-     * Gets the value of the feature property.
-     * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the feature property.
+     * Java class for anonymous complex type.
      * 
      * <p>
-     * For example, to add a new item, do as follows:
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
      * <pre>
-     *    getFeature().add(newItem);
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="primaryBegin" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="primaryEnd" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="accession" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *       &lt;attribute name="complement" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
      * </pre>
      * 
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EntryType.Feature }
-     * 
-     * 
      */
-    public List<EntryType.Feature> getFeature() {
-        if (feature == null) {
-            feature = new ArrayList<EntryType.Feature>();
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Range
+    {
+
+      @XmlAttribute(name = "begin", required = true)
+      protected BigInteger begin;
+
+      @XmlAttribute(name = "end", required = true)
+      protected BigInteger end;
+
+      @XmlAttribute(name = "primaryBegin")
+      protected BigInteger primaryBegin;
+
+      @XmlAttribute(name = "primaryEnd")
+      protected BigInteger primaryEnd;
+
+      @XmlAttribute(name = "accession", required = true)
+      protected String accession;
+
+      @XmlAttribute(name = "version", required = true)
+      protected BigInteger version;
+
+      @XmlAttribute(name = "complement")
+      protected Boolean complement;
+
+      /**
+       * Gets the value of the begin property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getBegin()
+      {
+        return begin;
+      }
+
+      /**
+       * Sets the value of the begin property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setBegin(BigInteger value)
+      {
+        this.begin = value;
+      }
+
+      /**
+       * Gets the value of the end property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getEnd()
+      {
+        return end;
+      }
+
+      /**
+       * Sets the value of the end property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setEnd(BigInteger value)
+      {
+        this.end = value;
+      }
+
+      /**
+       * Gets the value of the primaryBegin property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getPrimaryBegin()
+      {
+        return primaryBegin;
+      }
+
+      /**
+       * Sets the value of the primaryBegin property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setPrimaryBegin(BigInteger value)
+      {
+        this.primaryBegin = value;
+      }
+
+      /**
+       * Gets the value of the primaryEnd property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getPrimaryEnd()
+      {
+        return primaryEnd;
+      }
+
+      /**
+       * Sets the value of the primaryEnd property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setPrimaryEnd(BigInteger value)
+      {
+        this.primaryEnd = value;
+      }
+
+      /**
+       * Gets the value of the accession property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getAccession()
+      {
+        return accession;
+      }
+
+      /**
+       * Sets the value of the accession property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setAccession(String value)
+      {
+        this.accession = value;
+      }
+
+      /**
+       * Gets the value of the version property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getVersion()
+      {
+        return version;
+      }
+
+      /**
+       * Sets the value of the version property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setVersion(BigInteger value)
+      {
+        this.version = value;
+      }
+
+      /**
+       * Gets the value of the complement property.
+       * 
+       * @return possible object is {@link Boolean }
+       * 
+       */
+      public boolean isComplement()
+      {
+        if (complement == null)
+        {
+          return false;
         }
-        return this.feature;
-    }
+        else
+        {
+          return complement;
+        }
+      }
+
+      /**
+       * Sets the value of the complement property.
+       * 
+       * @param value
+       *          allowed object is {@link Boolean }
+       * 
+       */
+      public void setComplement(Boolean value)
+      {
+        this.complement = value;
+      }
 
-    /**
-     * Gets the value of the assembly property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link EntryType.Assembly }
-     *     
-     */
-    public EntryType.Assembly getAssembly() {
-        return assembly;
     }
 
-    /**
-     * Sets the value of the assembly property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link EntryType.Assembly }
-     *     
-     */
-    public void setAssembly(EntryType.Assembly value) {
-        this.assembly = value;
-    }
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="taxon" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;sequence>
+   *                   &lt;element name="lineage" minOccurs="0">
+   *                     &lt;complexType>
+   *                       &lt;complexContent>
+   *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                           &lt;sequence>
+   *                             &lt;element name="taxon" maxOccurs="unbounded">
+   *                               &lt;complexType>
+   *                                 &lt;complexContent>
+   *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                                     &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                                   &lt;/restriction>
+   *                                 &lt;/complexContent>
+   *                               &lt;/complexType>
+   *                             &lt;/element>
+   *                           &lt;/sequence>
+   *                         &lt;/restriction>
+   *                       &lt;/complexContent>
+   *                     &lt;/complexType>
+   *                   &lt;/element>
+   *                 &lt;/sequence>
+   *                 &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="commonName" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="taxId" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="xref" type="{}XrefType" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="qualifier" maxOccurs="unbounded" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;sequence>
+   *                   &lt;element name="value" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *                 &lt;/sequence>
+   *                 &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *       &lt;/sequence>
+   *       &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="location" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "taxon", "xref", "qualifier" })
+  public static class Feature
+  {
+
+    protected EntryType.Feature.FeatureTaxon taxon;
 
-    /**
-     * Gets the value of the contig property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link EntryType.Contig }
-     *     
-     */
-    public EntryType.Contig getContig() {
-        return contig;
-    }
+    protected List<XrefType> xref;
 
-    /**
-     * Sets the value of the contig property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link EntryType.Contig }
-     *     
-     */
-    public void setContig(EntryType.Contig value) {
-        this.contig = value;
-    }
+    protected List<EntryType.Feature.Qualifier> qualifier;
 
-    /**
-     * Gets the value of the sequence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getSequence() {
-        return sequence;
-    }
+    @XmlAttribute(name = "name", required = true)
+    protected String name;
 
-    /**
-     * Sets the value of the sequence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setSequence(String value) {
-        this.sequence = value;
-    }
+    @XmlAttribute(name = "location", required = true)
+    protected String location;
 
     /**
-     * Gets the value of the accession property.
+     * Gets the value of the taxon property.
+     * 
+     * @return possible object is {@link EntryType.Feature.FeatureTaxon }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getAccession() {
-        return accession;
+    public EntryType.Feature.FeatureTaxon getTaxon()
+    {
+      return taxon;
     }
 
     /**
-     * Sets the value of the accession property.
+     * Sets the value of the taxon property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setAccession(String value) {
-        this.accession = value;
-    }
-
-    /**
-     * Gets the value of the version property.
+     *          allowed object is {@link EntryType.Feature.FeatureTaxon }
      * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
      */
-    public BigInteger getVersion() {
-        return version;
+    public void setTaxon(EntryType.Feature.FeatureTaxon value)
+    {
+      this.taxon = value;
     }
 
     /**
-     * Sets the value of the version property.
+     * Gets the value of the xref property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setVersion(BigInteger value) {
-        this.version = value;
-    }
-
-    /**
-     * Gets the value of the entryVersion property.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the xref property.
      * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
-     */
-    public BigInteger getEntryVersion() {
-        return entryVersion;
-    }
-
-    /**
-     * Sets the value of the entryVersion property.
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setEntryVersion(BigInteger value) {
-        this.entryVersion = value;
-    }
-
-    /**
-     * Gets the value of the dataClass property.
+     * <pre>
+     * getXref().add(newItem);
+     * </pre>
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDataClass() {
-        return dataClass;
-    }
-
-    /**
-     * Sets the value of the dataClass property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDataClass(String value) {
-        this.dataClass = value;
-    }
-
-    /**
-     * Gets the value of the taxonomicDivision property.
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link XrefType
+     * }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getTaxonomicDivision() {
-        return taxonomicDivision;
-    }
-
-    /**
-     * Sets the value of the taxonomicDivision property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
      */
-    public void setTaxonomicDivision(String value) {
-        this.taxonomicDivision = value;
+    public List<XrefType> getXref()
+    {
+      if (xref == null)
+      {
+        xref = new ArrayList<XrefType>();
+      }
+      return this.xref;
     }
 
     /**
-     * Gets the value of the moleculeType property.
+     * Gets the value of the qualifier property.
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getMoleculeType() {
-        return moleculeType;
-    }
-
-    /**
-     * Sets the value of the moleculeType property.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the qualifier property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setMoleculeType(String value) {
-        this.moleculeType = value;
-    }
-
-    /**
-     * Gets the value of the sequenceLength property.
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
-     */
-    public BigInteger getSequenceLength() {
-        return sequenceLength;
-    }
-
-    /**
-     * Sets the value of the sequenceLength property.
+     * <pre>
+     * getQualifier().add(newItem);
+     * </pre>
      * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setSequenceLength(BigInteger value) {
-        this.sequenceLength = value;
-    }
-
-    /**
-     * Gets the value of the topology property.
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getTopology() {
-        return topology;
-    }
-
-    /**
-     * Sets the value of the topology property.
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EntryType.Feature.Qualifier }
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setTopology(String value) {
-        this.topology = value;
-    }
-
-    /**
-     * Gets the value of the firstPublic property.
      * 
-     * @return
-     *     possible object is
-     *     {@link XMLGregorianCalendar }
-     *     
      */
-    public XMLGregorianCalendar getFirstPublic() {
-        return firstPublic;
+    public List<EntryType.Feature.Qualifier> getQualifier()
+    {
+      if (qualifier == null)
+      {
+        qualifier = new ArrayList<EntryType.Feature.Qualifier>();
+      }
+      return this.qualifier;
     }
 
     /**
-     * Sets the value of the firstPublic property.
+     * Gets the value of the name property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public void setFirstPublic(XMLGregorianCalendar value) {
-        this.firstPublic = value;
-    }
-
-    /**
-     * Gets the value of the firstPublicRelease property.
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
      */
-    public BigInteger getFirstPublicRelease() {
-        return firstPublicRelease;
+    public String getName()
+    {
+      return name;
     }
 
     /**
-     * Sets the value of the firstPublicRelease property.
+     * Sets the value of the name property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setFirstPublicRelease(BigInteger value) {
-        this.firstPublicRelease = value;
-    }
-
-    /**
-     * Gets the value of the lastUpdated property.
+     *          allowed object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link XMLGregorianCalendar }
-     *     
      */
-    public XMLGregorianCalendar getLastUpdated() {
-        return lastUpdated;
+    public void setName(String value)
+    {
+      this.name = value;
     }
 
     /**
-     * Sets the value of the lastUpdated property.
+     * Gets the value of the location property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public void setLastUpdated(XMLGregorianCalendar value) {
-        this.lastUpdated = value;
-    }
-
-    /**
-     * Gets the value of the lastUpdatedRelease property.
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
      */
-    public BigInteger getLastUpdatedRelease() {
-        return lastUpdatedRelease;
+    public String getLocation()
+    {
+      return location;
     }
 
     /**
-     * Sets the value of the lastUpdatedRelease property.
+     * Sets the value of the location property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
+     *          allowed object is {@link String }
+     * 
      */
-    public void setLastUpdatedRelease(BigInteger value) {
-        this.lastUpdatedRelease = value;
+    public void setLocation(String value)
+    {
+      this.location = value;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * <p>
+     * Java class for anonymous complex type.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
      * 
      * <pre>
      * &lt;complexType>
      *   &lt;complexContent>
      *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
      *       &lt;sequence>
-     *         &lt;element name="range" maxOccurs="unbounded">
+     *         &lt;element name="lineage" minOccurs="0">
      *           &lt;complexType>
      *             &lt;complexContent>
      *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                 &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                 &lt;attribute name="primaryBegin" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                 &lt;attribute name="primaryEnd" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                 &lt;attribute name="accession" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                 &lt;attribute name="complement" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+     *                 &lt;sequence>
+     *                   &lt;element name="taxon" maxOccurs="unbounded">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                 &lt;/sequence>
      *               &lt;/restriction>
      *             &lt;/complexContent>
      *           &lt;/complexType>
      *         &lt;/element>
      *       &lt;/sequence>
+     *       &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="commonName" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="taxId" type="{http://www.w3.org/2001/XMLSchema}integer" />
      *     &lt;/restriction>
      *   &lt;/complexContent>
      * &lt;/complexType>
@@ -896,366 +1894,198 @@ public class EntryType {
      * 
      */
     @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "range"
-    })
-    public static class Assembly {
+    @XmlType(name = "", propOrder = { "lineage" })
+    public static class FeatureTaxon
+    {
+
+      protected EntryType.Feature.FeatureTaxon.Lineage lineage;
+
+      @XmlAttribute(name = "scientificName", required = true)
+      protected String scientificName;
+
+      @XmlAttribute(name = "commonName")
+      protected String commonName;
+
+      @XmlAttribute(name = "taxId")
+      protected BigInteger taxId;
+
+      /**
+       * Gets the value of the lineage property.
+       * 
+       * @return possible object is
+       *         {@link EntryType.Feature.FeatureTaxon.Lineage }
+       * 
+       */
+      public EntryType.Feature.FeatureTaxon.Lineage getLineage()
+      {
+        return lineage;
+      }
+
+      /**
+       * Sets the value of the lineage property.
+       * 
+       * @param value
+       *          allowed object is
+       *          {@link EntryType.Feature.FeatureTaxon.Lineage }
+       * 
+       */
+      public void setLineage(EntryType.Feature.FeatureTaxon.Lineage value)
+      {
+        this.lineage = value;
+      }
+
+      /**
+       * Gets the value of the scientificName property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getScientificName()
+      {
+        return scientificName;
+      }
+
+      /**
+       * Sets the value of the scientificName property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setScientificName(String value)
+      {
+        this.scientificName = value;
+      }
+
+      /**
+       * Gets the value of the commonName property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getCommonName()
+      {
+        return commonName;
+      }
+
+      /**
+       * Sets the value of the commonName property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setCommonName(String value)
+      {
+        this.commonName = value;
+      }
+
+      /**
+       * Gets the value of the taxId property.
+       * 
+       * @return possible object is {@link BigInteger }
+       * 
+       */
+      public BigInteger getTaxId()
+      {
+        return taxId;
+      }
+
+      /**
+       * Sets the value of the taxId property.
+       * 
+       * @param value
+       *          allowed object is {@link BigInteger }
+       * 
+       */
+      public void setTaxId(BigInteger value)
+      {
+        this.taxId = value;
+      }
+
+      /**
+       * <p>
+       * Java class for anonymous complex type.
+       * 
+       * <p>
+       * The following schema fragment specifies the expected content contained
+       * within this class.
+       * 
+       * <pre>
+       * &lt;complexType>
+       *   &lt;complexContent>
+       *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+       *       &lt;sequence>
+       *         &lt;element name="taxon" maxOccurs="unbounded">
+       *           &lt;complexType>
+       *             &lt;complexContent>
+       *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+       *                 &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+       *               &lt;/restriction>
+       *             &lt;/complexContent>
+       *           &lt;/complexType>
+       *         &lt;/element>
+       *       &lt;/sequence>
+       *     &lt;/restriction>
+       *   &lt;/complexContent>
+       * &lt;/complexType>
+       * </pre>
+       * 
+       * 
+       */
+      @XmlAccessorType(XmlAccessType.FIELD)
+      @XmlType(name = "", propOrder = { "taxon" })
+      public static class Lineage
+      {
 
         @XmlElement(required = true)
-        protected List<EntryType.Assembly.Range> range;
+        protected List<EntryType.Feature.FeatureTaxon.Lineage.Taxon> taxon;
 
         /**
-         * Gets the value of the range property.
+         * Gets the value of the taxon property.
          * 
          * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the range property.
+         * This accessor method returns a reference to the live list, not a
+         * snapshot. Therefore any modification you make to the returned list
+         * will be present inside the JAXB object. This is why there is not a
+         * <CODE>set</CODE> method for the taxon property.
          * 
          * <p>
          * For example, to add a new item, do as follows:
+         * 
          * <pre>
-         *    getRange().add(newItem);
+         * getTaxon().add(newItem);
          * </pre>
          * 
          * 
          * <p>
          * Objects of the following type(s) are allowed in the list
-         * {@link EntryType.Assembly.Range }
-         * 
-         * 
-         */
-        public List<EntryType.Assembly.Range> getRange() {
-            if (range == null) {
-                range = new ArrayList<EntryType.Assembly.Range>();
-            }
-            return this.range;
-        }
-
-
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="primaryBegin" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="primaryEnd" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="accession" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="complement" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
+         * {@link EntryType.Feature.FeatureTaxon.Lineage.Taxon }
          * 
          * 
          */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class Range {
-
-            @XmlAttribute(name = "begin", required = true)
-            protected BigInteger begin;
-            @XmlAttribute(name = "end", required = true)
-            protected BigInteger end;
-            @XmlAttribute(name = "primaryBegin")
-            protected BigInteger primaryBegin;
-            @XmlAttribute(name = "primaryEnd")
-            protected BigInteger primaryEnd;
-            @XmlAttribute(name = "accession", required = true)
-            protected String accession;
-            @XmlAttribute(name = "version", required = true)
-            protected BigInteger version;
-            @XmlAttribute(name = "complement")
-            protected Boolean complement;
-
-            /**
-             * Gets the value of the begin property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getBegin() {
-                return begin;
-            }
-
-            /**
-             * Sets the value of the begin property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setBegin(BigInteger value) {
-                this.begin = value;
-            }
-
-            /**
-             * Gets the value of the end property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getEnd() {
-                return end;
-            }
-
-            /**
-             * Sets the value of the end property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setEnd(BigInteger value) {
-                this.end = value;
-            }
-
-            /**
-             * Gets the value of the primaryBegin property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getPrimaryBegin() {
-                return primaryBegin;
-            }
-
-            /**
-             * Sets the value of the primaryBegin property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setPrimaryBegin(BigInteger value) {
-                this.primaryBegin = value;
-            }
-
-            /**
-             * Gets the value of the primaryEnd property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getPrimaryEnd() {
-                return primaryEnd;
-            }
-
-            /**
-             * Sets the value of the primaryEnd property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setPrimaryEnd(BigInteger value) {
-                this.primaryEnd = value;
-            }
-
-            /**
-             * Gets the value of the accession property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getAccession() {
-                return accession;
-            }
-
-            /**
-             * Sets the value of the accession property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setAccession(String value) {
-                this.accession = value;
-            }
-
-            /**
-             * Gets the value of the version property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getVersion() {
-                return version;
-            }
-
-            /**
-             * Sets the value of the version property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setVersion(BigInteger value) {
-                this.version = value;
-            }
-
-            /**
-             * Gets the value of the complement property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Boolean }
-             *     
-             */
-            public boolean isComplement() {
-                if (complement == null) {
-                    return false;
-                } else {
-                    return complement;
-                }
-            }
-
-            /**
-             * Sets the value of the complement property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Boolean }
-             *     
-             */
-            public void setComplement(Boolean value) {
-                this.complement = value;
-            }
-
+        public List<EntryType.Feature.FeatureTaxon.Lineage.Taxon> getTaxon()
+        {
+          if (taxon == null)
+          {
+            taxon = new ArrayList<EntryType.Feature.FeatureTaxon.Lineage.Taxon>();
+          }
+          return this.taxon;
         }
 
-    }
-
-
-    /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;choice maxOccurs="unbounded" minOccurs="0">
-     *           &lt;element name="range">
-     *             &lt;complexType>
-     *               &lt;complexContent>
-     *                 &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                   &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                   &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                   &lt;attribute name="primaryBegin" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                   &lt;attribute name="primaryEnd" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                   &lt;attribute name="accession" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                   &lt;attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                   &lt;attribute name="complement" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *                 &lt;/restriction>
-     *               &lt;/complexContent>
-     *             &lt;/complexType>
-     *           &lt;/element>
-     *           &lt;element name="gap">
-     *             &lt;complexType>
-     *               &lt;complexContent>
-     *                 &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                   &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                   &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                   &lt;attribute name="length" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *                   &lt;attribute name="unknownLength" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *                 &lt;/restriction>
-     *               &lt;/complexContent>
-     *             &lt;/complexType>
-     *           &lt;/element>
-     *         &lt;/choice>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
-     * 
-     * 
-     */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "rangeOrGap"
-    })
-    public static class Contig {
-
-        @XmlElements({
-            @XmlElement(name = "range", type = EntryType.Contig.Range.class),
-            @XmlElement(name = "gap", type = EntryType.Contig.Gap.class)
-        })
-        protected List<Object> rangeOrGap;
-
         /**
-         * Gets the value of the rangeOrGap property.
-         * 
          * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the rangeOrGap property.
+         * Java class for anonymous complex type.
          * 
          * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getRangeOrGap().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EntryType.Contig.Range }
-         * {@link EntryType.Contig.Gap }
-         * 
-         * 
-         */
-        public List<Object> getRangeOrGap() {
-            if (rangeOrGap == null) {
-                rangeOrGap = new ArrayList<Object>();
-            }
-            return this.rangeOrGap;
-        }
-
-
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
+         * The following schema fragment specifies the expected content
+         * contained within this class.
          * 
          * <pre>
          * &lt;complexType>
          *   &lt;complexContent>
          *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="length" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="unknownLength" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+         *       &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
          *     &lt;/restriction>
          *   &lt;/complexContent>
          * &lt;/complexType>
@@ -1265,397 +2095,57 @@ public class EntryType {
          */
         @XmlAccessorType(XmlAccessType.FIELD)
         @XmlType(name = "")
-        public static class Gap {
-
-            @XmlAttribute(name = "begin", required = true)
-            protected BigInteger begin;
-            @XmlAttribute(name = "end", required = true)
-            protected BigInteger end;
-            @XmlAttribute(name = "length", required = true)
-            protected BigInteger length;
-            @XmlAttribute(name = "unknownLength")
-            protected Boolean unknownLength;
-
-            /**
-             * Gets the value of the begin property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getBegin() {
-                return begin;
-            }
-
-            /**
-             * Sets the value of the begin property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setBegin(BigInteger value) {
-                this.begin = value;
-            }
-
-            /**
-             * Gets the value of the end property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getEnd() {
-                return end;
-            }
-
-            /**
-             * Sets the value of the end property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setEnd(BigInteger value) {
-                this.end = value;
-            }
-
-            /**
-             * Gets the value of the length property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getLength() {
-                return length;
-            }
-
-            /**
-             * Sets the value of the length property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setLength(BigInteger value) {
-                this.length = value;
-            }
-
-            /**
-             * Gets the value of the unknownLength property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Boolean }
-             *     
-             */
-            public boolean isUnknownLength() {
-                if (unknownLength == null) {
-                    return false;
-                } else {
-                    return unknownLength;
-                }
-            }
-
-            /**
-             * Sets the value of the unknownLength property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Boolean }
-             *     
-             */
-            public void setUnknownLength(Boolean value) {
-                this.unknownLength = value;
-            }
+        public static class Taxon
+        {
+
+          @XmlAttribute(name = "scientificName", required = true)
+          protected String scientificName;
+
+          /**
+           * Gets the value of the scientificName property.
+           * 
+           * @return possible object is {@link String }
+           * 
+           */
+          public String getScientificName()
+          {
+            return scientificName;
+          }
+
+          /**
+           * Sets the value of the scientificName property.
+           * 
+           * @param value
+           *          allowed object is {@link String }
+           * 
+           */
+          public void setScientificName(String value)
+          {
+            this.scientificName = value;
+          }
 
         }
 
-
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attribute name="begin" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="primaryBegin" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="primaryEnd" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="accession" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *       &lt;attribute name="complement" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class Range {
-
-            @XmlAttribute(name = "begin", required = true)
-            protected BigInteger begin;
-            @XmlAttribute(name = "end", required = true)
-            protected BigInteger end;
-            @XmlAttribute(name = "primaryBegin")
-            protected BigInteger primaryBegin;
-            @XmlAttribute(name = "primaryEnd")
-            protected BigInteger primaryEnd;
-            @XmlAttribute(name = "accession", required = true)
-            protected String accession;
-            @XmlAttribute(name = "version", required = true)
-            protected BigInteger version;
-            @XmlAttribute(name = "complement")
-            protected Boolean complement;
-
-            /**
-             * Gets the value of the begin property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getBegin() {
-                return begin;
-            }
-
-            /**
-             * Sets the value of the begin property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setBegin(BigInteger value) {
-                this.begin = value;
-            }
-
-            /**
-             * Gets the value of the end property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getEnd() {
-                return end;
-            }
-
-            /**
-             * Sets the value of the end property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setEnd(BigInteger value) {
-                this.end = value;
-            }
-
-            /**
-             * Gets the value of the primaryBegin property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getPrimaryBegin() {
-                return primaryBegin;
-            }
-
-            /**
-             * Sets the value of the primaryBegin property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setPrimaryBegin(BigInteger value) {
-                this.primaryBegin = value;
-            }
-
-            /**
-             * Gets the value of the primaryEnd property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getPrimaryEnd() {
-                return primaryEnd;
-            }
-
-            /**
-             * Sets the value of the primaryEnd property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setPrimaryEnd(BigInteger value) {
-                this.primaryEnd = value;
-            }
-
-            /**
-             * Gets the value of the accession property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getAccession() {
-                return accession;
-            }
-
-            /**
-             * Sets the value of the accession property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setAccession(String value) {
-                this.accession = value;
-            }
-
-            /**
-             * Gets the value of the version property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getVersion() {
-                return version;
-            }
-
-            /**
-             * Sets the value of the version property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setVersion(BigInteger value) {
-                this.version = value;
-            }
-
-            /**
-             * Gets the value of the complement property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Boolean }
-             *     
-             */
-            public boolean isComplement() {
-                if (complement == null) {
-                    return false;
-                } else {
-                    return complement;
-                }
-            }
-
-            /**
-             * Sets the value of the complement property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Boolean }
-             *     
-             */
-            public void setComplement(Boolean value) {
-                this.complement = value;
-            }
-
-        }
+      }
 
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * <p>
+     * Java class for anonymous complex type.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
      * 
      * <pre>
      * &lt;complexType>
      *   &lt;complexContent>
      *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
      *       &lt;sequence>
-     *         &lt;element name="taxon" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;sequence>
-     *                   &lt;element name="lineage" minOccurs="0">
-     *                     &lt;complexType>
-     *                       &lt;complexContent>
-     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                           &lt;sequence>
-     *                             &lt;element name="taxon" maxOccurs="unbounded">
-     *                               &lt;complexType>
-     *                                 &lt;complexContent>
-     *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                                     &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                                   &lt;/restriction>
-     *                                 &lt;/complexContent>
-     *                               &lt;/complexType>
-     *                             &lt;/element>
-     *                           &lt;/sequence>
-     *                         &lt;/restriction>
-     *                       &lt;/complexContent>
-     *                     &lt;/complexType>
-     *                   &lt;/element>
-     *                 &lt;/sequence>
-     *                 &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="commonName" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="taxId" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="xref" type="{}XrefType" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="qualifier" maxOccurs="unbounded" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;sequence>
-     *                   &lt;element name="value" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *                 &lt;/sequence>
-     *                 &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
+     *         &lt;element name="value" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
      *       &lt;/sequence>
      *       &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="location" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
      *     &lt;/restriction>
      *   &lt;/complexContent>
      * &lt;/complexType>
@@ -1664,1017 +2154,578 @@ public class EntryType {
      * 
      */
     @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "taxon",
-        "xref",
-        "qualifier"
-    })
-    public static class Feature {
-
-        protected EntryType.Feature.FeatureTaxon taxon;
-        protected List<XrefType> xref;
-        protected List<EntryType.Feature.Qualifier> qualifier;
-        @XmlAttribute(name = "name", required = true)
-        protected String name;
-        @XmlAttribute(name = "location", required = true)
-        protected String location;
+    @XmlType(name = "", propOrder = { "value" })
+    public static class Qualifier
+    {
+
+      protected String value;
+
+      @XmlAttribute(name = "name", required = true)
+      protected String name;
+
+      /**
+       * Gets the value of the value property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getValue()
+      {
+        return value;
+      }
+
+      /**
+       * Sets the value of the value property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setValue(String value)
+      {
+        this.value = value;
+      }
+
+      /**
+       * Gets the value of the name property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getName()
+      {
+        return name;
+      }
+
+      /**
+       * Sets the value of the name property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setName(String value)
+      {
+        this.name = value;
+      }
 
-        /**
-         * Gets the value of the taxon property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EntryType.Feature.FeatureTaxon }
-         *     
-         */
-        public EntryType.Feature.FeatureTaxon getTaxon() {
-            return taxon;
-        }
+    }
 
-        /**
-         * Sets the value of the taxon property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EntryType.Feature.FeatureTaxon }
-         *     
-         */
-        public void setTaxon(EntryType.Feature.FeatureTaxon value) {
-            this.taxon = value;
-        }
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="title" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="author" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="applicant" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="consortium" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="submissionDate" type="{http://www.w3.org/2001/XMLSchema}date" minOccurs="0"/>
+   *         &lt;element name="journal" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="year" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="volume" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="issue" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="firstPage" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="lastPage" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="comment" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="referenceLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+   *         &lt;element name="xref" type="{}XrefType" maxOccurs="unbounded" minOccurs="0"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="type" use="required">
+   *         &lt;simpleType>
+   *           &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+   *             &lt;enumeration value="submission"/>
+   *             &lt;enumeration value="book"/>
+   *             &lt;enumeration value="article"/>
+   *             &lt;enumeration value="patent"/>
+   *             &lt;enumeration value="thesis"/>
+   *             &lt;enumeration value="unpublished"/>
+   *           &lt;/restriction>
+   *         &lt;/simpleType>
+   *       &lt;/attribute>
+   *       &lt;attribute name="number" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *       &lt;attribute name="location" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(
+    name = "",
+    propOrder =
+    { "title", "author", "applicant", "consortium", "submissionDate",
+        "journal", "year", "volume", "issue", "firstPage", "lastPage",
+        "comment", "referenceLocation", "xref" })
+  public static class Reference
+  {
+
+    protected String title;
+
+    protected List<String> author;
+
+    protected List<String> applicant;
+
+    protected String consortium;
 
-        /**
-         * Gets the value of the xref property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the xref property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getXref().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link XrefType }
-         * 
-         * 
-         */
-        public List<XrefType> getXref() {
-            if (xref == null) {
-                xref = new ArrayList<XrefType>();
-            }
-            return this.xref;
-        }
+    @XmlSchemaType(name = "date")
+    protected XMLGregorianCalendar submissionDate;
 
-        /**
-         * Gets the value of the qualifier property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the qualifier property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getQualifier().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EntryType.Feature.Qualifier }
-         * 
-         * 
-         */
-        public List<EntryType.Feature.Qualifier> getQualifier() {
-            if (qualifier == null) {
-                qualifier = new ArrayList<EntryType.Feature.Qualifier>();
-            }
-            return this.qualifier;
-        }
+    protected String journal;
 
-        /**
-         * Gets the value of the name property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getName() {
-            return name;
-        }
+    protected String year;
 
-        /**
-         * Sets the value of the name property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setName(String value) {
-            this.name = value;
-        }
+    protected String volume;
 
-        /**
-         * Gets the value of the location property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getLocation() {
-            return location;
-        }
+    protected String issue;
 
-        /**
-         * Sets the value of the location property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setLocation(String value) {
-            this.location = value;
-        }
+    protected String firstPage;
 
+    protected String lastPage;
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;sequence>
-         *         &lt;element name="lineage" minOccurs="0">
-         *           &lt;complexType>
-         *             &lt;complexContent>
-         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *                 &lt;sequence>
-         *                   &lt;element name="taxon" maxOccurs="unbounded">
-         *                     &lt;complexType>
-         *                       &lt;complexContent>
-         *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *                           &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *                         &lt;/restriction>
-         *                       &lt;/complexContent>
-         *                     &lt;/complexType>
-         *                   &lt;/element>
-         *                 &lt;/sequence>
-         *               &lt;/restriction>
-         *             &lt;/complexContent>
-         *           &lt;/complexType>
-         *         &lt;/element>
-         *       &lt;/sequence>
-         *       &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="commonName" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="taxId" type="{http://www.w3.org/2001/XMLSchema}integer" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "", propOrder = {
-            "lineage"
-        })
-        public static class FeatureTaxon {
-
-            protected EntryType.Feature.FeatureTaxon.Lineage lineage;
-            @XmlAttribute(name = "scientificName", required = true)
-            protected String scientificName;
-            @XmlAttribute(name = "commonName")
-            protected String commonName;
-            @XmlAttribute(name = "taxId")
-            protected BigInteger taxId;
-
-            /**
-             * Gets the value of the lineage property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link EntryType.Feature.FeatureTaxon.Lineage }
-             *     
-             */
-            public EntryType.Feature.FeatureTaxon.Lineage getLineage() {
-                return lineage;
-            }
-
-            /**
-             * Sets the value of the lineage property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link EntryType.Feature.FeatureTaxon.Lineage }
-             *     
-             */
-            public void setLineage(EntryType.Feature.FeatureTaxon.Lineage value) {
-                this.lineage = value;
-            }
-
-            /**
-             * Gets the value of the scientificName property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getScientificName() {
-                return scientificName;
-            }
-
-            /**
-             * Sets the value of the scientificName property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setScientificName(String value) {
-                this.scientificName = value;
-            }
-
-            /**
-             * Gets the value of the commonName property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getCommonName() {
-                return commonName;
-            }
-
-            /**
-             * Sets the value of the commonName property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setCommonName(String value) {
-                this.commonName = value;
-            }
-
-            /**
-             * Gets the value of the taxId property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link BigInteger }
-             *     
-             */
-            public BigInteger getTaxId() {
-                return taxId;
-            }
-
-            /**
-             * Sets the value of the taxId property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link BigInteger }
-             *     
-             */
-            public void setTaxId(BigInteger value) {
-                this.taxId = value;
-            }
-
-
-            /**
-             * <p>Java class for anonymous complex type.
-             * 
-             * <p>The following schema fragment specifies the expected content contained within this class.
-             * 
-             * <pre>
-             * &lt;complexType>
-             *   &lt;complexContent>
-             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-             *       &lt;sequence>
-             *         &lt;element name="taxon" maxOccurs="unbounded">
-             *           &lt;complexType>
-             *             &lt;complexContent>
-             *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-             *                 &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *               &lt;/restriction>
-             *             &lt;/complexContent>
-             *           &lt;/complexType>
-             *         &lt;/element>
-             *       &lt;/sequence>
-             *     &lt;/restriction>
-             *   &lt;/complexContent>
-             * &lt;/complexType>
-             * </pre>
-             * 
-             * 
-             */
-            @XmlAccessorType(XmlAccessType.FIELD)
-            @XmlType(name = "", propOrder = {
-                "taxon"
-            })
-            public static class Lineage {
-
-                @XmlElement(required = true)
-                protected List<EntryType.Feature.FeatureTaxon.Lineage.Taxon> taxon;
-
-                /**
-                 * Gets the value of the taxon property.
-                 * 
-                 * <p>
-                 * This accessor method returns a reference to the live list,
-                 * not a snapshot. Therefore any modification you make to the
-                 * returned list will be present inside the JAXB object.
-                 * This is why there is not a <CODE>set</CODE> method for the taxon property.
-                 * 
-                 * <p>
-                 * For example, to add a new item, do as follows:
-                 * <pre>
-                 *    getTaxon().add(newItem);
-                 * </pre>
-                 * 
-                 * 
-                 * <p>
-                 * Objects of the following type(s) are allowed in the list
-                 * {@link EntryType.Feature.FeatureTaxon.Lineage.Taxon }
-                 * 
-                 * 
-                 */
-                public List<EntryType.Feature.FeatureTaxon.Lineage.Taxon> getTaxon() {
-                    if (taxon == null) {
-                        taxon = new ArrayList<EntryType.Feature.FeatureTaxon.Lineage.Taxon>();
-                    }
-                    return this.taxon;
-                }
-
-
-                /**
-                 * <p>Java class for anonymous complex type.
-                 * 
-                 * <p>The following schema fragment specifies the expected content contained within this class.
-                 * 
-                 * <pre>
-                 * &lt;complexType>
-                 *   &lt;complexContent>
-                 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-                 *       &lt;attribute name="scientificName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-                 *     &lt;/restriction>
-                 *   &lt;/complexContent>
-                 * &lt;/complexType>
-                 * </pre>
-                 * 
-                 * 
-                 */
-                @XmlAccessorType(XmlAccessType.FIELD)
-                @XmlType(name = "")
-                public static class Taxon {
-
-                    @XmlAttribute(name = "scientificName", required = true)
-                    protected String scientificName;
-
-                    /**
-                     * Gets the value of the scientificName property.
-                     * 
-                     * @return
-                     *     possible object is
-                     *     {@link String }
-                     *     
-                     */
-                    public String getScientificName() {
-                        return scientificName;
-                    }
-
-                    /**
-                     * Sets the value of the scientificName property.
-                     * 
-                     * @param value
-                     *     allowed object is
-                     *     {@link String }
-                     *     
-                     */
-                    public void setScientificName(String value) {
-                        this.scientificName = value;
-                    }
-
-                }
-
-            }
+    protected String comment;
 
-        }
+    protected String referenceLocation;
 
+    protected List<XrefType> xref;
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;sequence>
-         *         &lt;element name="value" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-         *       &lt;/sequence>
-         *       &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "", propOrder = {
-            "value"
-        })
-        public static class Qualifier {
-
-            protected String value;
-            @XmlAttribute(name = "name", required = true)
-            protected String name;
-
-            /**
-             * Gets the value of the value property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getValue() {
-                return value;
-            }
-
-            /**
-             * Sets the value of the value property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setValue(String value) {
-                this.value = value;
-            }
-
-            /**
-             * Gets the value of the name property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getName() {
-                return name;
-            }
-
-            /**
-             * Sets the value of the name property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setName(String value) {
-                this.name = value;
-            }
+    @XmlAttribute(name = "type", required = true)
+    protected String type;
 
-        }
+    @XmlAttribute(name = "number", required = true)
+    protected BigInteger number;
+
+    @XmlAttribute(name = "location")
+    protected String location;
 
+    /**
+     * Gets the value of the title property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getTitle()
+    {
+      return title;
     }
 
+    /**
+     * Sets the value of the title property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setTitle(String value)
+    {
+      this.title = value;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the author property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the author property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="title" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="author" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="applicant" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="consortium" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="submissionDate" type="{http://www.w3.org/2001/XMLSchema}date" minOccurs="0"/>
-     *         &lt;element name="journal" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="year" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="volume" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="issue" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="firstPage" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="lastPage" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="comment" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="referenceLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
-     *         &lt;element name="xref" type="{}XrefType" maxOccurs="unbounded" minOccurs="0"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="type" use="required">
-     *         &lt;simpleType>
-     *           &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
-     *             &lt;enumeration value="submission"/>
-     *             &lt;enumeration value="book"/>
-     *             &lt;enumeration value="article"/>
-     *             &lt;enumeration value="patent"/>
-     *             &lt;enumeration value="thesis"/>
-     *             &lt;enumeration value="unpublished"/>
-     *           &lt;/restriction>
-     *         &lt;/simpleType>
-     *       &lt;/attribute>
-     *       &lt;attribute name="number" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *       &lt;attribute name="location" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getAuthor().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link String }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "title",
-        "author",
-        "applicant",
-        "consortium",
-        "submissionDate",
-        "journal",
-        "year",
-        "volume",
-        "issue",
-        "firstPage",
-        "lastPage",
-        "comment",
-        "referenceLocation",
-        "xref"
-    })
-    public static class Reference {
-
-        protected String title;
-        protected List<String> author;
-        protected List<String> applicant;
-        protected String consortium;
-        @XmlSchemaType(name = "date")
-        protected XMLGregorianCalendar submissionDate;
-        protected String journal;
-        protected String year;
-        protected String volume;
-        protected String issue;
-        protected String firstPage;
-        protected String lastPage;
-        protected String comment;
-        protected String referenceLocation;
-        protected List<XrefType> xref;
-        @XmlAttribute(name = "type", required = true)
-        protected String type;
-        @XmlAttribute(name = "number", required = true)
-        protected BigInteger number;
-        @XmlAttribute(name = "location")
-        protected String location;
-
-        /**
-         * Gets the value of the title property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getTitle() {
-            return title;
-        }
-
-        /**
-         * Sets the value of the title property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setTitle(String value) {
-            this.title = value;
-        }
+    public List<String> getAuthor()
+    {
+      if (author == null)
+      {
+        author = new ArrayList<String>();
+      }
+      return this.author;
+    }
 
-        /**
-         * Gets the value of the author property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the author property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getAuthor().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link String }
-         * 
-         * 
-         */
-        public List<String> getAuthor() {
-            if (author == null) {
-                author = new ArrayList<String>();
-            }
-            return this.author;
-        }
-
-        /**
-         * Gets the value of the applicant property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the applicant property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getApplicant().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link String }
-         * 
-         * 
-         */
-        public List<String> getApplicant() {
-            if (applicant == null) {
-                applicant = new ArrayList<String>();
-            }
-            return this.applicant;
-        }
-
-        /**
-         * Gets the value of the consortium property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getConsortium() {
-            return consortium;
-        }
+    /**
+     * Gets the value of the applicant property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the applicant property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getApplicant().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link String }
+     * 
+     * 
+     */
+    public List<String> getApplicant()
+    {
+      if (applicant == null)
+      {
+        applicant = new ArrayList<String>();
+      }
+      return this.applicant;
+    }
 
-        /**
-         * Sets the value of the consortium property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setConsortium(String value) {
-            this.consortium = value;
-        }
+    /**
+     * Gets the value of the consortium property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getConsortium()
+    {
+      return consortium;
+    }
 
-        /**
-         * Gets the value of the submissionDate property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link XMLGregorianCalendar }
-         *     
-         */
-        public XMLGregorianCalendar getSubmissionDate() {
-            return submissionDate;
-        }
+    /**
+     * Sets the value of the consortium property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setConsortium(String value)
+    {
+      this.consortium = value;
+    }
 
-        /**
-         * Sets the value of the submissionDate property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link XMLGregorianCalendar }
-         *     
-         */
-        public void setSubmissionDate(XMLGregorianCalendar value) {
-            this.submissionDate = value;
-        }
+    /**
+     * Gets the value of the submissionDate property.
+     * 
+     * @return possible object is {@link XMLGregorianCalendar }
+     * 
+     */
+    public XMLGregorianCalendar getSubmissionDate()
+    {
+      return submissionDate;
+    }
 
-        /**
-         * Gets the value of the journal property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getJournal() {
-            return journal;
-        }
+    /**
+     * Sets the value of the submissionDate property.
+     * 
+     * @param value
+     *          allowed object is {@link XMLGregorianCalendar }
+     * 
+     */
+    public void setSubmissionDate(XMLGregorianCalendar value)
+    {
+      this.submissionDate = value;
+    }
 
-        /**
-         * Sets the value of the journal property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setJournal(String value) {
-            this.journal = value;
-        }
+    /**
+     * Gets the value of the journal property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getJournal()
+    {
+      return journal;
+    }
 
-        /**
-         * Gets the value of the year property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getYear() {
-            return year;
-        }
+    /**
+     * Sets the value of the journal property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setJournal(String value)
+    {
+      this.journal = value;
+    }
 
-        /**
-         * Sets the value of the year property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setYear(String value) {
-            this.year = value;
-        }
+    /**
+     * Gets the value of the year property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getYear()
+    {
+      return year;
+    }
 
-        /**
-         * Gets the value of the volume property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getVolume() {
-            return volume;
-        }
+    /**
+     * Sets the value of the year property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setYear(String value)
+    {
+      this.year = value;
+    }
 
-        /**
-         * Sets the value of the volume property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setVolume(String value) {
-            this.volume = value;
-        }
+    /**
+     * Gets the value of the volume property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getVolume()
+    {
+      return volume;
+    }
 
-        /**
-         * Gets the value of the issue property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getIssue() {
-            return issue;
-        }
+    /**
+     * Sets the value of the volume property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setVolume(String value)
+    {
+      this.volume = value;
+    }
 
-        /**
-         * Sets the value of the issue property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setIssue(String value) {
-            this.issue = value;
-        }
+    /**
+     * Gets the value of the issue property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getIssue()
+    {
+      return issue;
+    }
 
-        /**
-         * Gets the value of the firstPage property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getFirstPage() {
-            return firstPage;
-        }
+    /**
+     * Sets the value of the issue property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setIssue(String value)
+    {
+      this.issue = value;
+    }
 
-        /**
-         * Sets the value of the firstPage property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setFirstPage(String value) {
-            this.firstPage = value;
-        }
+    /**
+     * Gets the value of the firstPage property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getFirstPage()
+    {
+      return firstPage;
+    }
 
-        /**
-         * Gets the value of the lastPage property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getLastPage() {
-            return lastPage;
-        }
+    /**
+     * Sets the value of the firstPage property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setFirstPage(String value)
+    {
+      this.firstPage = value;
+    }
 
-        /**
-         * Sets the value of the lastPage property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setLastPage(String value) {
-            this.lastPage = value;
-        }
+    /**
+     * Gets the value of the lastPage property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getLastPage()
+    {
+      return lastPage;
+    }
 
-        /**
-         * Gets the value of the comment property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getComment() {
-            return comment;
-        }
+    /**
+     * Sets the value of the lastPage property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setLastPage(String value)
+    {
+      this.lastPage = value;
+    }
 
-        /**
-         * Sets the value of the comment property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setComment(String value) {
-            this.comment = value;
-        }
+    /**
+     * Gets the value of the comment property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getComment()
+    {
+      return comment;
+    }
 
-        /**
-         * Gets the value of the referenceLocation property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getReferenceLocation() {
-            return referenceLocation;
-        }
+    /**
+     * Sets the value of the comment property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setComment(String value)
+    {
+      this.comment = value;
+    }
 
-        /**
-         * Sets the value of the referenceLocation property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setReferenceLocation(String value) {
-            this.referenceLocation = value;
-        }
+    /**
+     * Gets the value of the referenceLocation property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getReferenceLocation()
+    {
+      return referenceLocation;
+    }
 
-        /**
-         * Gets the value of the xref property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the xref property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getXref().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link XrefType }
-         * 
-         * 
-         */
-        public List<XrefType> getXref() {
-            if (xref == null) {
-                xref = new ArrayList<XrefType>();
-            }
-            return this.xref;
-        }
+    /**
+     * Sets the value of the referenceLocation property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setReferenceLocation(String value)
+    {
+      this.referenceLocation = value;
+    }
 
-        /**
-         * Gets the value of the type property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getType() {
-            return type;
-        }
+    /**
+     * Gets the value of the xref property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the xref property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getXref().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link XrefType
+     * }
+     * 
+     * 
+     */
+    public List<XrefType> getXref()
+    {
+      if (xref == null)
+      {
+        xref = new ArrayList<XrefType>();
+      }
+      return this.xref;
+    }
 
-        /**
-         * Sets the value of the type property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setType(String value) {
-            this.type = value;
-        }
+    /**
+     * Gets the value of the type property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getType()
+    {
+      return type;
+    }
 
-        /**
-         * Gets the value of the number property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link BigInteger }
-         *     
-         */
-        public BigInteger getNumber() {
-            return number;
-        }
+    /**
+     * Sets the value of the type property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setType(String value)
+    {
+      this.type = value;
+    }
 
-        /**
-         * Sets the value of the number property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link BigInteger }
-         *     
-         */
-        public void setNumber(BigInteger value) {
-            this.number = value;
-        }
+    /**
+     * Gets the value of the number property.
+     * 
+     * @return possible object is {@link BigInteger }
+     * 
+     */
+    public BigInteger getNumber()
+    {
+      return number;
+    }
 
-        /**
-         * Gets the value of the location property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getLocation() {
-            return location;
-        }
+    /**
+     * Sets the value of the number property.
+     * 
+     * @param value
+     *          allowed object is {@link BigInteger }
+     * 
+     */
+    public void setNumber(BigInteger value)
+    {
+      this.number = value;
+    }
 
-        /**
-         * Sets the value of the location property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setLocation(String value) {
-            this.location = value;
-        }
+    /**
+     * Gets the value of the location property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getLocation()
+    {
+      return location;
+    }
 
+    /**
+     * Sets the value of the location property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setLocation(String value)
+    {
+      this.location = value;
     }
 
+  }
+
 }
index e1a917a..0bb5c59 100644 (file)
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:45 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.embl;
 
 import javax.xml.bind.annotation.XmlRegistry;
 
-
 /**
- * This object contains factory methods for each 
- * Java content interface and Java element interface 
- * generated in the jalview.xml.binding.embl package. 
- * <p>An ObjectFactory allows you to programatically 
- * construct new instances of the Java representation 
- * for XML content. The Java representation of XML 
- * content can consist of schema derived interfaces 
- * and classes representing the binding of schema 
- * type definitions, element declarations and model 
- * groups.  Factory methods for each of these are 
- * provided in this class.
+ * This object contains factory methods for each Java content interface and Java
+ * element interface generated in the jalview.xml.binding.embl package.
+ * <p>
+ * An ObjectFactory allows you to programatically construct new instances of the
+ * Java representation for XML content. The Java representation of XML content
+ * can consist of schema derived interfaces and classes representing the binding
+ * of schema type definitions, element declarations and model groups. Factory
+ * methods for each of these are provided in this class.
  * 
  */
 @XmlRegistry
-public class ObjectFactory {
-
-
-    /**
-     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: jalview.xml.binding.embl
-     * 
-     */
-    public ObjectFactory() {
-    }
-
-    /**
-     * Create an instance of {@link EntryType }
-     * 
-     */
-    public EntryType createEntryType() {
-        return new EntryType();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Contig }
-     * 
-     */
-    public EntryType.Contig createEntryTypeContig() {
-        return new EntryType.Contig();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Assembly }
-     * 
-     */
-    public EntryType.Assembly createEntryTypeAssembly() {
-        return new EntryType.Assembly();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Feature }
-     * 
-     */
-    public EntryType.Feature createEntryTypeFeature() {
-        return new EntryType.Feature();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Feature.FeatureTaxon }
-     * 
-     */
-    public EntryType.Feature.FeatureTaxon createEntryTypeFeatureFeatureTaxon() {
-        return new EntryType.Feature.FeatureTaxon();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Feature.FeatureTaxon.Lineage }
-     * 
-     */
-    public EntryType.Feature.FeatureTaxon.Lineage createEntryTypeFeatureFeatureTaxonLineage() {
-        return new EntryType.Feature.FeatureTaxon.Lineage();
-    }
-
-    /**
-     * Create an instance of {@link ROOT }
-     * 
-     */
-    public ROOT createROOT() {
-        return new ROOT();
-    }
-
-    /**
-     * Create an instance of {@link EntrySetType }
-     * 
-     */
-    public EntrySetType createEntrySetType() {
-        return new EntrySetType();
-    }
-
-    /**
-     * Create an instance of {@link XrefType }
-     * 
-     */
-    public XrefType createXrefType() {
-        return new XrefType();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Reference }
-     * 
-     */
-    public EntryType.Reference createEntryTypeReference() {
-        return new EntryType.Reference();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Contig.Range }
-     * 
-     */
-    public EntryType.Contig.Range createEntryTypeContigRange() {
-        return new EntryType.Contig.Range();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Contig.Gap }
-     * 
-     */
-    public EntryType.Contig.Gap createEntryTypeContigGap() {
-        return new EntryType.Contig.Gap();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Assembly.Range }
-     * 
-     */
-    public EntryType.Assembly.Range createEntryTypeAssemblyRange() {
-        return new EntryType.Assembly.Range();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Feature.Qualifier }
-     * 
-     */
-    public EntryType.Feature.Qualifier createEntryTypeFeatureQualifier() {
-        return new EntryType.Feature.Qualifier();
-    }
-
-    /**
-     * Create an instance of {@link EntryType.Feature.FeatureTaxon.Lineage.Taxon }
-     * 
-     */
-    public EntryType.Feature.FeatureTaxon.Lineage.Taxon createEntryTypeFeatureFeatureTaxonLineageTaxon() {
-        return new EntryType.Feature.FeatureTaxon.Lineage.Taxon();
-    }
+public class ObjectFactory
+{
+
+  /**
+   * Create a new ObjectFactory that can be used to create new instances of
+   * schema derived classes for package: jalview.xml.binding.embl
+   * 
+   */
+  public ObjectFactory()
+  {
+  }
+
+  /**
+   * Create an instance of {@link EntryType }
+   * 
+   */
+  public EntryType createEntryType()
+  {
+    return new EntryType();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Contig }
+   * 
+   */
+  public EntryType.Contig createEntryTypeContig()
+  {
+    return new EntryType.Contig();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Assembly }
+   * 
+   */
+  public EntryType.Assembly createEntryTypeAssembly()
+  {
+    return new EntryType.Assembly();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Feature }
+   * 
+   */
+  public EntryType.Feature createEntryTypeFeature()
+  {
+    return new EntryType.Feature();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Feature.FeatureTaxon }
+   * 
+   */
+  public EntryType.Feature.FeatureTaxon createEntryTypeFeatureFeatureTaxon()
+  {
+    return new EntryType.Feature.FeatureTaxon();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Feature.FeatureTaxon.Lineage }
+   * 
+   */
+  public EntryType.Feature.FeatureTaxon.Lineage createEntryTypeFeatureFeatureTaxonLineage()
+  {
+    return new EntryType.Feature.FeatureTaxon.Lineage();
+  }
+
+  /**
+   * Create an instance of {@link ROOT }
+   * 
+   */
+  public ROOT createROOT()
+  {
+    return new ROOT();
+  }
+
+  /**
+   * Create an instance of {@link EntrySetType }
+   * 
+   */
+  public EntrySetType createEntrySetType()
+  {
+    return new EntrySetType();
+  }
+
+  /**
+   * Create an instance of {@link XrefType }
+   * 
+   */
+  public XrefType createXrefType()
+  {
+    return new XrefType();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Reference }
+   * 
+   */
+  public EntryType.Reference createEntryTypeReference()
+  {
+    return new EntryType.Reference();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Contig.Range }
+   * 
+   */
+  public EntryType.Contig.Range createEntryTypeContigRange()
+  {
+    return new EntryType.Contig.Range();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Contig.Gap }
+   * 
+   */
+  public EntryType.Contig.Gap createEntryTypeContigGap()
+  {
+    return new EntryType.Contig.Gap();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Assembly.Range }
+   * 
+   */
+  public EntryType.Assembly.Range createEntryTypeAssemblyRange()
+  {
+    return new EntryType.Assembly.Range();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Feature.Qualifier }
+   * 
+   */
+  public EntryType.Feature.Qualifier createEntryTypeFeatureQualifier()
+  {
+    return new EntryType.Feature.Qualifier();
+  }
+
+  /**
+   * Create an instance of {@link EntryType.Feature.FeatureTaxon.Lineage.Taxon }
+   * 
+   */
+  public EntryType.Feature.FeatureTaxon.Lineage.Taxon createEntryTypeFeatureFeatureTaxonLineageTaxon()
+  {
+    return new EntryType.Feature.FeatureTaxon.Lineage.Taxon();
+  }
 
 }
index 958cdbc..b3fad01 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:45 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.embl;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,11 +12,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -35,62 +36,59 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "entrySet",
-    "entry"
-})
+@XmlType(name = "", propOrder = { "entrySet", "entry" })
 @XmlRootElement(name = "ROOT")
-public class ROOT {
+public class ROOT
+{
+
+  protected EntrySetType entrySet;
 
-    protected EntrySetType entrySet;
-    protected EntryType entry;
+  protected EntryType entry;
 
-    /**
-     * Gets the value of the entrySet property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link EntrySetType }
-     *     
-     */
-    public EntrySetType getEntrySet() {
-        return entrySet;
-    }
+  /**
+   * Gets the value of the entrySet property.
+   * 
+   * @return possible object is {@link EntrySetType }
+   * 
+   */
+  public EntrySetType getEntrySet()
+  {
+    return entrySet;
+  }
 
-    /**
-     * Sets the value of the entrySet property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link EntrySetType }
-     *     
-     */
-    public void setEntrySet(EntrySetType value) {
-        this.entrySet = value;
-    }
+  /**
+   * Sets the value of the entrySet property.
+   * 
+   * @param value
+   *          allowed object is {@link EntrySetType }
+   * 
+   */
+  public void setEntrySet(EntrySetType value)
+  {
+    this.entrySet = value;
+  }
 
-    /**
-     * Gets the value of the entry property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link EntryType }
-     *     
-     */
-    public EntryType getEntry() {
-        return entry;
-    }
+  /**
+   * Gets the value of the entry property.
+   * 
+   * @return possible object is {@link EntryType }
+   * 
+   */
+  public EntryType getEntry()
+  {
+    return entry;
+  }
 
-    /**
-     * Sets the value of the entry property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link EntryType }
-     *     
-     */
-    public void setEntry(EntryType value) {
-        this.entry = value;
-    }
+  /**
+   * Sets the value of the entry property.
+   * 
+   * @param value
+   *          allowed object is {@link EntryType }
+   * 
+   */
+  public void setEntry(EntryType value)
+  {
+    this.entry = value;
+  }
 
 }
index 244d0fe..03bbba4 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:45 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.embl;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,13 +12,15 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * Database cross-reference.
  * 
- * <p>Java class for XrefType complex type.
+ * <p>
+ * Java class for XrefType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="XrefType">
@@ -37,85 +38,85 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "XrefType")
-public class XrefType {
+public class XrefType
+{
+
+  @XmlAttribute(name = "db", required = true)
+  protected String db;
+
+  @XmlAttribute(name = "id", required = true)
+  protected String id;
 
-    @XmlAttribute(name = "db", required = true)
-    protected String db;
-    @XmlAttribute(name = "id", required = true)
-    protected String id;
-    @XmlAttribute(name = "secondaryId")
-    protected String secondaryId;
+  @XmlAttribute(name = "secondaryId")
+  protected String secondaryId;
 
-    /**
-     * Gets the value of the db property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDb() {
-        return db;
-    }
+  /**
+   * Gets the value of the db property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDb()
+  {
+    return db;
+  }
 
-    /**
-     * Sets the value of the db property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDb(String value) {
-        this.db = value;
-    }
+  /**
+   * Sets the value of the db property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDb(String value)
+  {
+    this.db = value;
+  }
 
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
-    }
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
 
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
-    }
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
 
-    /**
-     * Gets the value of the secondaryId property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getSecondaryId() {
-        return secondaryId;
-    }
+  /**
+   * Gets the value of the secondaryId property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getSecondaryId()
+  {
+    return secondaryId;
+  }
 
-    /**
-     * Sets the value of the secondaryId property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setSecondaryId(String value) {
-        this.secondaryId = value;
-    }
+  /**
+   * Sets the value of the secondaryId property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setSecondaryId(String value)
+  {
+    this.secondaryId = value;
+  }
 
 }
index 2a40e11..6b98b6a 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.math.BigInteger;
@@ -18,11 +17,13 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -61,266 +62,275 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "alcodon",
-    "alcodMap"
-})
+@XmlType(name = "", propOrder = { "alcodon", "alcodMap" })
 @XmlRootElement(name = "AlcodonFrame")
-public class AlcodonFrame {
+public class AlcodonFrame
+{
+
+  protected List<AlcodonFrame.Alcodon> alcodon;
+
+  protected List<AlcodonFrame.AlcodMap> alcodMap;
 
-    protected List<AlcodonFrame.Alcodon> alcodon;
-    protected List<AlcodonFrame.AlcodMap> alcodMap;
+  /**
+   * Gets the value of the alcodon property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the alcodon property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getAlcodon().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link AlcodonFrame.Alcodon }
+   * 
+   * 
+   */
+  public List<AlcodonFrame.Alcodon> getAlcodon()
+  {
+    if (alcodon == null)
+    {
+      alcodon = new ArrayList<AlcodonFrame.Alcodon>();
+    }
+    return this.alcodon;
+  }
+
+  /**
+   * Gets the value of the alcodMap property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the alcodMap property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getAlcodMap().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link AlcodonFrame.AlcodMap }
+   * 
+   * 
+   */
+  public List<AlcodonFrame.AlcodMap> getAlcodMap()
+  {
+    if (alcodMap == null)
+    {
+      alcodMap = new ArrayList<AlcodonFrame.AlcodMap>();
+    }
+    return this.alcodMap;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element ref="{www.vamsas.ac.uk/jalview/version2}Mapping"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="dnasq" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "mapping" })
+  public static class AlcodMap
+  {
+
+    @XmlElement(name = "Mapping", required = true)
+    protected Mapping mapping;
+
+    @XmlAttribute(name = "dnasq", required = true)
+    protected String dnasq;
 
     /**
-     * Gets the value of the alcodon property.
      * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the alcodon property.
+     * a Mapping entry and an associated protein sequence
      * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getAlcodon().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link AlcodonFrame.Alcodon }
      * 
+     * @return possible object is {@link Mapping }
      * 
      */
-    public List<AlcodonFrame.Alcodon> getAlcodon() {
-        if (alcodon == null) {
-            alcodon = new ArrayList<AlcodonFrame.Alcodon>();
-        }
-        return this.alcodon;
+    public Mapping getMapping()
+    {
+      return mapping;
     }
 
     /**
-     * Gets the value of the alcodMap property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the alcodMap property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getAlcodMap().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link AlcodonFrame.AlcodMap }
+     * Sets the value of the mapping property.
      * 
+     * @param value
+     *          allowed object is {@link Mapping }
      * 
      */
-    public List<AlcodonFrame.AlcodMap> getAlcodMap() {
-        if (alcodMap == null) {
-            alcodMap = new ArrayList<AlcodonFrame.AlcodMap>();
-        }
-        return this.alcodMap;
+    public void setMapping(Mapping value)
+    {
+      this.mapping = value;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the dnasq property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @return possible object is {@link String }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element ref="{www.vamsas.ac.uk/jalview/version2}Mapping"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="dnasq" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public String getDnasq()
+    {
+      return dnasq;
+    }
+
+    /**
+     * Sets the value of the dnasq property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "mapping"
-    })
-    public static class AlcodMap {
+    public void setDnasq(String value)
+    {
+      this.dnasq = value;
+    }
 
-        @XmlElement(name = "Mapping", required = true)
-        protected Mapping mapping;
-        @XmlAttribute(name = "dnasq", required = true)
-        protected String dnasq;
+  }
 
-        /**
-         * 
-         *                                                                             a Mapping entry and an associated protein sequence
-         *                                                                     
-         * 
-         * @return
-         *     possible object is
-         *     {@link Mapping }
-         *     
-         */
-        public Mapping getMapping() {
-            return mapping;
-        }
+  /**
+   * 
+   * specifies a series of aligned codons from an associated DNA sequence
+   * alignment that when translated correspond to columns of a peptide
+   * alignment. Element may have either all pos1,2,3 attributes specified, or
+   * none at all (indicating a gapped column with no translated peptide).
+   * 
+   * 
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="pos1" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *       &lt;attribute name="pos2" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *       &lt;attribute name="pos3" type="{http://www.w3.org/2001/XMLSchema}integer" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class Alcodon
+  {
 
-        /**
-         * Sets the value of the mapping property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Mapping }
-         *     
-         */
-        public void setMapping(Mapping value) {
-            this.mapping = value;
-        }
+    @XmlAttribute(name = "pos1")
+    protected BigInteger pos1;
 
-        /**
-         * Gets the value of the dnasq property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getDnasq() {
-            return dnasq;
-        }
+    @XmlAttribute(name = "pos2")
+    protected BigInteger pos2;
 
-        /**
-         * Sets the value of the dnasq property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setDnasq(String value) {
-            this.dnasq = value;
-        }
+    @XmlAttribute(name = "pos3")
+    protected BigInteger pos3;
 
+    /**
+     * Gets the value of the pos1 property.
+     * 
+     * @return possible object is {@link BigInteger }
+     * 
+     */
+    public BigInteger getPos1()
+    {
+      return pos1;
     }
 
-
     /**
+     * Sets the value of the pos1 property.
      * 
-     *                                                                 specifies a series of aligned codons from an associated DNA sequence alignment that when translated correspond to columns of a peptide alignment.
-     *                                                                 Element may have either all pos1,2,3 attributes specified, or none at all (indicating a gapped column with no translated peptide).
-     *                                                         
+     * @param value
+     *          allowed object is {@link BigInteger }
      * 
-     * <p>Java class for anonymous complex type.
+     */
+    public void setPos1(BigInteger value)
+    {
+      this.pos1 = value;
+    }
+
+    /**
+     * Gets the value of the pos2 property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @return possible object is {@link BigInteger }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="pos1" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *       &lt;attribute name="pos2" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *       &lt;attribute name="pos3" type="{http://www.w3.org/2001/XMLSchema}integer" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public BigInteger getPos2()
+    {
+      return pos2;
+    }
+
+    /**
+     * Sets the value of the pos2 property.
      * 
+     * @param value
+     *          allowed object is {@link BigInteger }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class Alcodon {
-
-        @XmlAttribute(name = "pos1")
-        protected BigInteger pos1;
-        @XmlAttribute(name = "pos2")
-        protected BigInteger pos2;
-        @XmlAttribute(name = "pos3")
-        protected BigInteger pos3;
-
-        /**
-         * Gets the value of the pos1 property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link BigInteger }
-         *     
-         */
-        public BigInteger getPos1() {
-            return pos1;
-        }
-
-        /**
-         * Sets the value of the pos1 property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link BigInteger }
-         *     
-         */
-        public void setPos1(BigInteger value) {
-            this.pos1 = value;
-        }
-
-        /**
-         * Gets the value of the pos2 property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link BigInteger }
-         *     
-         */
-        public BigInteger getPos2() {
-            return pos2;
-        }
-
-        /**
-         * Sets the value of the pos2 property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link BigInteger }
-         *     
-         */
-        public void setPos2(BigInteger value) {
-            this.pos2 = value;
-        }
-
-        /**
-         * Gets the value of the pos3 property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link BigInteger }
-         *     
-         */
-        public BigInteger getPos3() {
-            return pos3;
-        }
+    public void setPos2(BigInteger value)
+    {
+      this.pos2 = value;
+    }
 
-        /**
-         * Sets the value of the pos3 property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link BigInteger }
-         *     
-         */
-        public void setPos3(BigInteger value) {
-            this.pos3 = value;
-        }
+    /**
+     * Gets the value of the pos3 property.
+     * 
+     * @return possible object is {@link BigInteger }
+     * 
+     */
+    public BigInteger getPos3()
+    {
+      return pos3;
+    }
 
+    /**
+     * Sets the value of the pos3 property.
+     * 
+     * @param value
+     *          allowed object is {@link BigInteger }
+     * 
+     */
+    public void setPos3(BigInteger value)
+    {
+      this.pos3 = value;
     }
 
+  }
+
 }
index 8d99141..2feda64 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -17,11 +16,13 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -70,733 +71,755 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "annotationElement",
-    "label",
-    "description",
-    "thresholdLine",
-    "contactmatrix",
-    "property"
-})
+@XmlType(
+  name = "",
+  propOrder =
+  { "annotationElement", "label", "description", "thresholdLine",
+      "contactmatrix", "property" })
 @XmlRootElement(name = "Annotation")
-public class Annotation {
-
-    protected List<AnnotationElement> annotationElement;
-    @XmlElement(required = true)
-    protected String label;
-    protected String description;
-    protected Annotation.ThresholdLine thresholdLine;
-    protected List<MatrixType> contactmatrix;
-    protected List<Property> property;
-    @XmlAttribute(name = "graph", required = true)
-    protected boolean graph;
-    @XmlAttribute(name = "graphType")
-    protected Integer graphType;
-    @XmlAttribute(name = "sequenceRef")
-    protected String sequenceRef;
-    @XmlAttribute(name = "groupRef")
-    protected String groupRef;
-    @XmlAttribute(name = "graphColour")
-    protected Integer graphColour;
-    @XmlAttribute(name = "graphGroup")
-    protected Integer graphGroup;
-    @XmlAttribute(name = "graphHeight")
-    protected Integer graphHeight;
-    @XmlAttribute(name = "id")
-    protected String id;
-    @XmlAttribute(name = "scoreOnly")
-    protected Boolean scoreOnly;
-    @XmlAttribute(name = "score")
-    protected Double score;
-    @XmlAttribute(name = "visible")
-    protected Boolean visible;
-    @XmlAttribute(name = "centreColLabels")
-    protected Boolean centreColLabels;
-    @XmlAttribute(name = "scaleColLabels")
-    protected Boolean scaleColLabels;
-    @XmlAttribute(name = "showAllColLabels")
-    protected Boolean showAllColLabels;
-    @XmlAttribute(name = "autoCalculated")
-    protected Boolean autoCalculated;
-    @XmlAttribute(name = "belowAlignment")
-    protected Boolean belowAlignment;
-    @XmlAttribute(name = "calcId")
-    protected String calcId;
-
-    /**
-     * Gets the value of the annotationElement property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the annotationElement property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getAnnotationElement().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link AnnotationElement }
-     * 
-     * 
-     */
-    public List<AnnotationElement> getAnnotationElement() {
-        if (annotationElement == null) {
-            annotationElement = new ArrayList<AnnotationElement>();
-        }
-        return this.annotationElement;
-    }
-
-    /**
-     * Gets the value of the label property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getLabel() {
-        return label;
-    }
-
-    /**
-     * Sets the value of the label property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setLabel(String value) {
-        this.label = value;
-    }
-
-    /**
-     * Gets the value of the description property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDescription() {
-        return description;
-    }
-
-    /**
-     * Sets the value of the description property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDescription(String value) {
-        this.description = value;
-    }
-
-    /**
-     * Gets the value of the thresholdLine property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Annotation.ThresholdLine }
-     *     
-     */
-    public Annotation.ThresholdLine getThresholdLine() {
-        return thresholdLine;
-    }
-
-    /**
-     * Sets the value of the thresholdLine property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Annotation.ThresholdLine }
-     *     
-     */
-    public void setThresholdLine(Annotation.ThresholdLine value) {
-        this.thresholdLine = value;
-    }
-
-    /**
-     * Gets the value of the contactmatrix property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the contactmatrix property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getContactmatrix().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link MatrixType }
-     * 
-     * 
-     */
-    public List<MatrixType> getContactmatrix() {
-        if (contactmatrix == null) {
-            contactmatrix = new ArrayList<MatrixType>();
-        }
-        return this.contactmatrix;
-    }
-
-    /**
-     * Gets the value of the property property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the property property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getProperty().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Property }
-     * 
-     * 
-     */
-    public List<Property> getProperty() {
-        if (property == null) {
-            property = new ArrayList<Property>();
-        }
-        return this.property;
-    }
-
-    /**
-     * Gets the value of the graph property.
-     * 
-     */
-    public boolean isGraph() {
-        return graph;
-    }
-
-    /**
-     * Sets the value of the graph property.
-     * 
-     */
-    public void setGraph(boolean value) {
-        this.graph = value;
-    }
-
-    /**
-     * Gets the value of the graphType property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getGraphType() {
-        return graphType;
-    }
+public class Annotation
+{
 
-    /**
-     * Sets the value of the graphType property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setGraphType(Integer value) {
-        this.graphType = value;
-    }
-
-    /**
-     * Gets the value of the sequenceRef property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getSequenceRef() {
-        return sequenceRef;
-    }
-
-    /**
-     * Sets the value of the sequenceRef property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setSequenceRef(String value) {
-        this.sequenceRef = value;
-    }
-
-    /**
-     * Gets the value of the groupRef property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getGroupRef() {
-        return groupRef;
-    }
+  protected List<AnnotationElement> annotationElement;
 
-    /**
-     * Sets the value of the groupRef property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setGroupRef(String value) {
-        this.groupRef = value;
-    }
+  @XmlElement(required = true)
+  protected String label;
+
+  protected String description;
 
-    /**
-     * Gets the value of the graphColour property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getGraphColour() {
-        return graphColour;
-    }
-
-    /**
-     * Sets the value of the graphColour property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setGraphColour(Integer value) {
-        this.graphColour = value;
-    }
-
-    /**
-     * Gets the value of the graphGroup property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getGraphGroup() {
-        return graphGroup;
-    }
-
-    /**
-     * Sets the value of the graphGroup property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setGraphGroup(Integer value) {
-        this.graphGroup = value;
-    }
-
-    /**
-     * Gets the value of the graphHeight property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getGraphHeight() {
-        return graphHeight;
-    }
-
-    /**
-     * Sets the value of the graphHeight property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setGraphHeight(Integer value) {
-        this.graphHeight = value;
-    }
-
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
-    }
-
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
-    }
-
-    /**
-     * Gets the value of the scoreOnly property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
-     */
-    public boolean isScoreOnly() {
-        if (scoreOnly == null) {
-            return false;
-        } else {
-            return scoreOnly;
-        }
-    }
-
-    /**
-     * Sets the value of the scoreOnly property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setScoreOnly(Boolean value) {
-        this.scoreOnly = value;
-    }
-
-    /**
-     * Gets the value of the score property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Double }
-     *     
-     */
-    public Double getScore() {
-        return score;
-    }
+  protected Annotation.ThresholdLine thresholdLine;
+
+  protected List<MatrixType> contactmatrix;
+
+  protected List<Property> property;
+
+  @XmlAttribute(name = "graph", required = true)
+  protected boolean graph;
+
+  @XmlAttribute(name = "graphType")
+  protected Integer graphType;
+
+  @XmlAttribute(name = "sequenceRef")
+  protected String sequenceRef;
+
+  @XmlAttribute(name = "groupRef")
+  protected String groupRef;
+
+  @XmlAttribute(name = "graphColour")
+  protected Integer graphColour;
+
+  @XmlAttribute(name = "graphGroup")
+  protected Integer graphGroup;
+
+  @XmlAttribute(name = "graphHeight")
+  protected Integer graphHeight;
+
+  @XmlAttribute(name = "id")
+  protected String id;
+
+  @XmlAttribute(name = "scoreOnly")
+  protected Boolean scoreOnly;
+
+  @XmlAttribute(name = "score")
+  protected Double score;
+
+  @XmlAttribute(name = "visible")
+  protected Boolean visible;
+
+  @XmlAttribute(name = "centreColLabels")
+  protected Boolean centreColLabels;
+
+  @XmlAttribute(name = "scaleColLabels")
+  protected Boolean scaleColLabels;
+
+  @XmlAttribute(name = "showAllColLabels")
+  protected Boolean showAllColLabels;
+
+  @XmlAttribute(name = "autoCalculated")
+  protected Boolean autoCalculated;
+
+  @XmlAttribute(name = "belowAlignment")
+  protected Boolean belowAlignment;
+
+  @XmlAttribute(name = "calcId")
+  protected String calcId;
+
+  /**
+   * Gets the value of the annotationElement property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the annotationElement property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getAnnotationElement().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link AnnotationElement }
+   * 
+   * 
+   */
+  public List<AnnotationElement> getAnnotationElement()
+  {
+    if (annotationElement == null)
+    {
+      annotationElement = new ArrayList<AnnotationElement>();
+    }
+    return this.annotationElement;
+  }
+
+  /**
+   * Gets the value of the label property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getLabel()
+  {
+    return label;
+  }
+
+  /**
+   * Sets the value of the label property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setLabel(String value)
+  {
+    this.label = value;
+  }
+
+  /**
+   * Gets the value of the description property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /**
+   * Sets the value of the description property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDescription(String value)
+  {
+    this.description = value;
+  }
+
+  /**
+   * Gets the value of the thresholdLine property.
+   * 
+   * @return possible object is {@link Annotation.ThresholdLine }
+   * 
+   */
+  public Annotation.ThresholdLine getThresholdLine()
+  {
+    return thresholdLine;
+  }
+
+  /**
+   * Sets the value of the thresholdLine property.
+   * 
+   * @param value
+   *          allowed object is {@link Annotation.ThresholdLine }
+   * 
+   */
+  public void setThresholdLine(Annotation.ThresholdLine value)
+  {
+    this.thresholdLine = value;
+  }
+
+  /**
+   * Gets the value of the contactmatrix property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the contactmatrix property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getContactmatrix().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link MatrixType
+   * }
+   * 
+   * 
+   */
+  public List<MatrixType> getContactmatrix()
+  {
+    if (contactmatrix == null)
+    {
+      contactmatrix = new ArrayList<MatrixType>();
+    }
+    return this.contactmatrix;
+  }
+
+  /**
+   * Gets the value of the property property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the property property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getProperty().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Property }
+   * 
+   * 
+   */
+  public List<Property> getProperty()
+  {
+    if (property == null)
+    {
+      property = new ArrayList<Property>();
+    }
+    return this.property;
+  }
+
+  /**
+   * Gets the value of the graph property.
+   * 
+   */
+  public boolean isGraph()
+  {
+    return graph;
+  }
+
+  /**
+   * Sets the value of the graph property.
+   * 
+   */
+  public void setGraph(boolean value)
+  {
+    this.graph = value;
+  }
+
+  /**
+   * Gets the value of the graphType property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getGraphType()
+  {
+    return graphType;
+  }
+
+  /**
+   * Sets the value of the graphType property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setGraphType(Integer value)
+  {
+    this.graphType = value;
+  }
+
+  /**
+   * Gets the value of the sequenceRef property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getSequenceRef()
+  {
+    return sequenceRef;
+  }
+
+  /**
+   * Sets the value of the sequenceRef property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setSequenceRef(String value)
+  {
+    this.sequenceRef = value;
+  }
+
+  /**
+   * Gets the value of the groupRef property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getGroupRef()
+  {
+    return groupRef;
+  }
+
+  /**
+   * Sets the value of the groupRef property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setGroupRef(String value)
+  {
+    this.groupRef = value;
+  }
+
+  /**
+   * Gets the value of the graphColour property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getGraphColour()
+  {
+    return graphColour;
+  }
+
+  /**
+   * Sets the value of the graphColour property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setGraphColour(Integer value)
+  {
+    this.graphColour = value;
+  }
+
+  /**
+   * Gets the value of the graphGroup property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getGraphGroup()
+  {
+    return graphGroup;
+  }
+
+  /**
+   * Sets the value of the graphGroup property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setGraphGroup(Integer value)
+  {
+    this.graphGroup = value;
+  }
+
+  /**
+   * Gets the value of the graphHeight property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getGraphHeight()
+  {
+    return graphHeight;
+  }
+
+  /**
+   * Sets the value of the graphHeight property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setGraphHeight(Integer value)
+  {
+    this.graphHeight = value;
+  }
+
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
+
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
+
+  /**
+   * Gets the value of the scoreOnly property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public boolean isScoreOnly()
+  {
+    if (scoreOnly == null)
+    {
+      return false;
+    }
+    else
+    {
+      return scoreOnly;
+    }
+  }
+
+  /**
+   * Sets the value of the scoreOnly property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setScoreOnly(Boolean value)
+  {
+    this.scoreOnly = value;
+  }
+
+  /**
+   * Gets the value of the score property.
+   * 
+   * @return possible object is {@link Double }
+   * 
+   */
+  public Double getScore()
+  {
+    return score;
+  }
+
+  /**
+   * Sets the value of the score property.
+   * 
+   * @param value
+   *          allowed object is {@link Double }
+   * 
+   */
+  public void setScore(Double value)
+  {
+    this.score = value;
+  }
+
+  /**
+   * Gets the value of the visible property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public Boolean isVisible()
+  {
+    return visible;
+  }
+
+  /**
+   * Sets the value of the visible property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setVisible(Boolean value)
+  {
+    this.visible = value;
+  }
+
+  /**
+   * Gets the value of the centreColLabels property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public Boolean isCentreColLabels()
+  {
+    return centreColLabels;
+  }
+
+  /**
+   * Sets the value of the centreColLabels property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setCentreColLabels(Boolean value)
+  {
+    this.centreColLabels = value;
+  }
+
+  /**
+   * Gets the value of the scaleColLabels property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public Boolean isScaleColLabels()
+  {
+    return scaleColLabels;
+  }
+
+  /**
+   * Sets the value of the scaleColLabels property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setScaleColLabels(Boolean value)
+  {
+    this.scaleColLabels = value;
+  }
+
+  /**
+   * Gets the value of the showAllColLabels property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public Boolean isShowAllColLabels()
+  {
+    return showAllColLabels;
+  }
+
+  /**
+   * Sets the value of the showAllColLabels property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setShowAllColLabels(Boolean value)
+  {
+    this.showAllColLabels = value;
+  }
+
+  /**
+   * Gets the value of the autoCalculated property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public boolean isAutoCalculated()
+  {
+    if (autoCalculated == null)
+    {
+      return false;
+    }
+    else
+    {
+      return autoCalculated;
+    }
+  }
+
+  /**
+   * Sets the value of the autoCalculated property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setAutoCalculated(Boolean value)
+  {
+    this.autoCalculated = value;
+  }
+
+  /**
+   * Gets the value of the belowAlignment property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public boolean isBelowAlignment()
+  {
+    if (belowAlignment == null)
+    {
+      return true;
+    }
+    else
+    {
+      return belowAlignment;
+    }
+  }
+
+  /**
+   * Sets the value of the belowAlignment property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setBelowAlignment(Boolean value)
+  {
+    this.belowAlignment = value;
+  }
+
+  /**
+   * Gets the value of the calcId property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getCalcId()
+  {
+    return calcId;
+  }
+
+  /**
+   * Sets the value of the calcId property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setCalcId(String value)
+  {
+    this.calcId = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="label" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="value" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *       &lt;attribute name="colour" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class ThresholdLine
+  {
+
+    @XmlAttribute(name = "label")
+    protected String label;
 
-    /**
-     * Sets the value of the score property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Double }
-     *     
-     */
-    public void setScore(Double value) {
-        this.score = value;
-    }
+    @XmlAttribute(name = "value")
+    protected Float value;
 
-    /**
-     * Gets the value of the visible property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
-     */
-    public Boolean isVisible() {
-        return visible;
-    }
+    @XmlAttribute(name = "colour")
+    protected Integer colour;
 
     /**
-     * Sets the value of the visible property.
+     * Gets the value of the label property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setVisible(Boolean value) {
-        this.visible = value;
-    }
-
-    /**
-     * Gets the value of the centreColLabels property.
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
      */
-    public Boolean isCentreColLabels() {
-        return centreColLabels;
+    public String getLabel()
+    {
+      return label;
     }
 
     /**
-     * Sets the value of the centreColLabels property.
+     * Sets the value of the label property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setCentreColLabels(Boolean value) {
-        this.centreColLabels = value;
-    }
-
-    /**
-     * Gets the value of the scaleColLabels property.
+     *          allowed object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
      */
-    public Boolean isScaleColLabels() {
-        return scaleColLabels;
+    public void setLabel(String value)
+    {
+      this.label = value;
     }
 
     /**
-     * Sets the value of the scaleColLabels property.
+     * Gets the value of the value property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setScaleColLabels(Boolean value) {
-        this.scaleColLabels = value;
-    }
-
-    /**
-     * Gets the value of the showAllColLabels property.
+     * @return possible object is {@link Float }
      * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
      */
-    public Boolean isShowAllColLabels() {
-        return showAllColLabels;
+    public Float getValue()
+    {
+      return value;
     }
 
     /**
-     * Sets the value of the showAllColLabels property.
+     * Sets the value of the value property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setShowAllColLabels(Boolean value) {
-        this.showAllColLabels = value;
-    }
-
-    /**
-     * Gets the value of the autoCalculated property.
+     *          allowed object is {@link Float }
      * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
      */
-    public boolean isAutoCalculated() {
-        if (autoCalculated == null) {
-            return false;
-        } else {
-            return autoCalculated;
-        }
+    public void setValue(Float value)
+    {
+      this.value = value;
     }
 
     /**
-     * Sets the value of the autoCalculated property.
+     * Gets the value of the colour property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setAutoCalculated(Boolean value) {
-        this.autoCalculated = value;
-    }
-
-    /**
-     * Gets the value of the belowAlignment property.
+     * @return possible object is {@link Integer }
      * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
      */
-    public boolean isBelowAlignment() {
-        if (belowAlignment == null) {
-            return true;
-        } else {
-            return belowAlignment;
-        }
+    public Integer getColour()
+    {
+      return colour;
     }
 
     /**
-     * Sets the value of the belowAlignment property.
+     * Sets the value of the colour property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setBelowAlignment(Boolean value) {
-        this.belowAlignment = value;
-    }
-
-    /**
-     * Gets the value of the calcId property.
+     *          allowed object is {@link Integer }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getCalcId() {
-        return calcId;
+    public void setColour(Integer value)
+    {
+      this.colour = value;
     }
 
-    /**
-     * Sets the value of the calcId property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setCalcId(String value) {
-        this.calcId = value;
-    }
-
-
-    /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="label" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="value" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *       &lt;attribute name="colour" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
-     * 
-     * 
-     */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class ThresholdLine {
-
-        @XmlAttribute(name = "label")
-        protected String label;
-        @XmlAttribute(name = "value")
-        protected Float value;
-        @XmlAttribute(name = "colour")
-        protected Integer colour;
-
-        /**
-         * Gets the value of the label property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getLabel() {
-            return label;
-        }
-
-        /**
-         * Sets the value of the label property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setLabel(String value) {
-            this.label = value;
-        }
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Float }
-         *     
-         */
-        public Float getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Float }
-         *     
-         */
-        public void setValue(Float value) {
-            this.value = value;
-        }
-
-        /**
-         * Gets the value of the colour property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getColour() {
-            return colour;
-        }
-
-        /**
-         * Sets the value of the colour property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setColour(Integer value) {
-            this.colour = value;
-        }
-
-    }
+  }
 
 }
index 27e0cc6..c820076 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,11 +12,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for AnnotationColourScheme complex type.
+ * <p>
+ * Java class for AnnotationColourScheme complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="AnnotationColourScheme">
@@ -40,215 +41,215 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "AnnotationColourScheme", namespace = "www.jalview.org")
-public class AnnotationColourScheme {
-
-    @XmlAttribute(name = "aboveThreshold")
-    protected Integer aboveThreshold;
-    @XmlAttribute(name = "annotation")
-    protected String annotation;
-    @XmlAttribute(name = "minColour")
-    protected Integer minColour;
-    @XmlAttribute(name = "maxColour")
-    protected Integer maxColour;
-    @XmlAttribute(name = "colourScheme")
-    protected String colourScheme;
-    @XmlAttribute(name = "threshold")
-    protected Float threshold;
-    @XmlAttribute(name = "perSequence")
-    protected Boolean perSequence;
-    @XmlAttribute(name = "predefinedColours")
-    protected Boolean predefinedColours;
-
-    /**
-     * Gets the value of the aboveThreshold property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getAboveThreshold() {
-        return aboveThreshold;
-    }
-
-    /**
-     * Sets the value of the aboveThreshold property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setAboveThreshold(Integer value) {
-        this.aboveThreshold = value;
-    }
-
-    /**
-     * Gets the value of the annotation property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getAnnotation() {
-        return annotation;
-    }
-
-    /**
-     * Sets the value of the annotation property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setAnnotation(String value) {
-        this.annotation = value;
-    }
-
-    /**
-     * Gets the value of the minColour property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getMinColour() {
-        return minColour;
-    }
-
-    /**
-     * Sets the value of the minColour property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setMinColour(Integer value) {
-        this.minColour = value;
-    }
-
-    /**
-     * Gets the value of the maxColour property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getMaxColour() {
-        return maxColour;
-    }
-
-    /**
-     * Sets the value of the maxColour property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setMaxColour(Integer value) {
-        this.maxColour = value;
-    }
-
-    /**
-     * Gets the value of the colourScheme property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getColourScheme() {
-        return colourScheme;
-    }
-
-    /**
-     * Sets the value of the colourScheme property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setColourScheme(String value) {
-        this.colourScheme = value;
-    }
-
-    /**
-     * Gets the value of the threshold property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Float }
-     *     
-     */
-    public Float getThreshold() {
-        return threshold;
-    }
-
-    /**
-     * Sets the value of the threshold property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Float }
-     *     
-     */
-    public void setThreshold(Float value) {
-        this.threshold = value;
-    }
-
-    /**
-     * Gets the value of the perSequence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
-     */
-    public Boolean isPerSequence() {
-        return perSequence;
-    }
-
-    /**
-     * Sets the value of the perSequence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setPerSequence(Boolean value) {
-        this.perSequence = value;
-    }
-
-    /**
-     * Gets the value of the predefinedColours property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
-     */
-    public Boolean isPredefinedColours() {
-        return predefinedColours;
-    }
-
-    /**
-     * Sets the value of the predefinedColours property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setPredefinedColours(Boolean value) {
-        this.predefinedColours = value;
-    }
+public class AnnotationColourScheme
+{
+
+  @XmlAttribute(name = "aboveThreshold")
+  protected Integer aboveThreshold;
+
+  @XmlAttribute(name = "annotation")
+  protected String annotation;
+
+  @XmlAttribute(name = "minColour")
+  protected Integer minColour;
+
+  @XmlAttribute(name = "maxColour")
+  protected Integer maxColour;
+
+  @XmlAttribute(name = "colourScheme")
+  protected String colourScheme;
+
+  @XmlAttribute(name = "threshold")
+  protected Float threshold;
+
+  @XmlAttribute(name = "perSequence")
+  protected Boolean perSequence;
+
+  @XmlAttribute(name = "predefinedColours")
+  protected Boolean predefinedColours;
+
+  /**
+   * Gets the value of the aboveThreshold property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getAboveThreshold()
+  {
+    return aboveThreshold;
+  }
+
+  /**
+   * Sets the value of the aboveThreshold property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setAboveThreshold(Integer value)
+  {
+    this.aboveThreshold = value;
+  }
+
+  /**
+   * Gets the value of the annotation property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getAnnotation()
+  {
+    return annotation;
+  }
+
+  /**
+   * Sets the value of the annotation property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setAnnotation(String value)
+  {
+    this.annotation = value;
+  }
+
+  /**
+   * Gets the value of the minColour property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getMinColour()
+  {
+    return minColour;
+  }
+
+  /**
+   * Sets the value of the minColour property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setMinColour(Integer value)
+  {
+    this.minColour = value;
+  }
+
+  /**
+   * Gets the value of the maxColour property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getMaxColour()
+  {
+    return maxColour;
+  }
+
+  /**
+   * Sets the value of the maxColour property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setMaxColour(Integer value)
+  {
+    this.maxColour = value;
+  }
+
+  /**
+   * Gets the value of the colourScheme property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getColourScheme()
+  {
+    return colourScheme;
+  }
+
+  /**
+   * Sets the value of the colourScheme property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setColourScheme(String value)
+  {
+    this.colourScheme = value;
+  }
+
+  /**
+   * Gets the value of the threshold property.
+   * 
+   * @return possible object is {@link Float }
+   * 
+   */
+  public Float getThreshold()
+  {
+    return threshold;
+  }
+
+  /**
+   * Sets the value of the threshold property.
+   * 
+   * @param value
+   *          allowed object is {@link Float }
+   * 
+   */
+  public void setThreshold(Float value)
+  {
+    this.threshold = value;
+  }
+
+  /**
+   * Gets the value of the perSequence property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public Boolean isPerSequence()
+  {
+    return perSequence;
+  }
+
+  /**
+   * Sets the value of the perSequence property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setPerSequence(Boolean value)
+  {
+    this.perSequence = value;
+  }
+
+  /**
+   * Gets the value of the predefinedColours property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public Boolean isPredefinedColours()
+  {
+    return predefinedColours;
+  }
+
+  /**
+   * Sets the value of the predefinedColours property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setPredefinedColours(Boolean value)
+  {
+    this.predefinedColours = value;
+  }
 
 }
index c5f75e0..087667a 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -14,11 +13,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -46,158 +47,159 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "displayCharacter",
-    "description",
-    "secondaryStructure",
-    "value"
-})
+@XmlType(
+  name = "",
+  propOrder =
+  { "displayCharacter", "description", "secondaryStructure", "value" })
 @XmlRootElement(name = "annotationElement")
-public class AnnotationElement {
-
-    protected String displayCharacter;
-    protected String description;
-    protected String secondaryStructure;
-    protected Float value;
-    @XmlAttribute(name = "position", required = true)
-    protected int position;
-    @XmlAttribute(name = "colour")
-    protected Integer colour;
-
-    /**
-     * Gets the value of the displayCharacter property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDisplayCharacter() {
-        return displayCharacter;
-    }
-
-    /**
-     * Sets the value of the displayCharacter property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDisplayCharacter(String value) {
-        this.displayCharacter = value;
-    }
-
-    /**
-     * Gets the value of the description property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDescription() {
-        return description;
-    }
-
-    /**
-     * Sets the value of the description property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDescription(String value) {
-        this.description = value;
-    }
-
-    /**
-     * Gets the value of the secondaryStructure property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getSecondaryStructure() {
-        return secondaryStructure;
-    }
-
-    /**
-     * Sets the value of the secondaryStructure property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setSecondaryStructure(String value) {
-        this.secondaryStructure = value;
-    }
-
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Float }
-     *     
-     */
-    public Float getValue() {
-        return value;
-    }
-
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Float }
-     *     
-     */
-    public void setValue(Float value) {
-        this.value = value;
-    }
-
-    /**
-     * Gets the value of the position property.
-     * 
-     */
-    public int getPosition() {
-        return position;
-    }
-
-    /**
-     * Sets the value of the position property.
-     * 
-     */
-    public void setPosition(int value) {
-        this.position = value;
-    }
-
-    /**
-     * Gets the value of the colour property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getColour() {
-        return colour;
-    }
-
-    /**
-     * Sets the value of the colour property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setColour(Integer value) {
-        this.colour = value;
-    }
+public class AnnotationElement
+{
+
+  protected String displayCharacter;
+
+  protected String description;
+
+  protected String secondaryStructure;
+
+  protected Float value;
+
+  @XmlAttribute(name = "position", required = true)
+  protected int position;
+
+  @XmlAttribute(name = "colour")
+  protected Integer colour;
+
+  /**
+   * Gets the value of the displayCharacter property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDisplayCharacter()
+  {
+    return displayCharacter;
+  }
+
+  /**
+   * Sets the value of the displayCharacter property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDisplayCharacter(String value)
+  {
+    this.displayCharacter = value;
+  }
+
+  /**
+   * Gets the value of the description property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /**
+   * Sets the value of the description property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDescription(String value)
+  {
+    this.description = value;
+  }
+
+  /**
+   * Gets the value of the secondaryStructure property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getSecondaryStructure()
+  {
+    return secondaryStructure;
+  }
+
+  /**
+   * Sets the value of the secondaryStructure property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setSecondaryStructure(String value)
+  {
+    this.secondaryStructure = value;
+  }
+
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link Float }
+   * 
+   */
+  public Float getValue()
+  {
+    return value;
+  }
+
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link Float }
+   * 
+   */
+  public void setValue(Float value)
+  {
+    this.value = value;
+  }
+
+  /**
+   * Gets the value of the position property.
+   * 
+   */
+  public int getPosition()
+  {
+    return position;
+  }
+
+  /**
+   * Sets the value of the position property.
+   * 
+   */
+  public void setPosition(int value)
+  {
+    this.position = value;
+  }
+
+  /**
+   * Gets the value of the colour property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getColour()
+  {
+    return colour;
+  }
+
+  /**
+   * Sets the value of the colour property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setColour(Integer value)
+  {
+    this.colour = value;
+  }
 
 }
index 9be9876..b42a170 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for DoubleMatrix complex type.
+ * <p>
+ * Java class for DoubleMatrix complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="DoubleMatrix">
@@ -41,146 +42,150 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "DoubleMatrix", namespace = "www.jalview.org", propOrder = {
-    "row",
-    "d",
-    "e"
-})
-public class DoubleMatrix {
-
-    protected List<DoubleVector> row;
-    @XmlElement(name = "D")
-    protected DoubleVector d;
-    @XmlElement(name = "E")
-    protected DoubleVector e;
-    @XmlAttribute(name = "rows")
-    protected Integer rows;
-    @XmlAttribute(name = "columns")
-    protected Integer columns;
-
-    /**
-     * Gets the value of the row property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the row property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getRow().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link DoubleVector }
-     * 
-     * 
-     */
-    public List<DoubleVector> getRow() {
-        if (row == null) {
-            row = new ArrayList<DoubleVector>();
-        }
-        return this.row;
-    }
-
-    /**
-     * Gets the value of the d property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DoubleVector }
-     *     
-     */
-    public DoubleVector getD() {
-        return d;
-    }
-
-    /**
-     * Sets the value of the d property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DoubleVector }
-     *     
-     */
-    public void setD(DoubleVector value) {
-        this.d = value;
-    }
-
-    /**
-     * Gets the value of the e property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DoubleVector }
-     *     
-     */
-    public DoubleVector getE() {
-        return e;
-    }
-
-    /**
-     * Sets the value of the e property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DoubleVector }
-     *     
-     */
-    public void setE(DoubleVector value) {
-        this.e = value;
-    }
-
-    /**
-     * Gets the value of the rows property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getRows() {
-        return rows;
-    }
-
-    /**
-     * Sets the value of the rows property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setRows(Integer value) {
-        this.rows = value;
-    }
-
-    /**
-     * Gets the value of the columns property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getColumns() {
-        return columns;
-    }
-
-    /**
-     * Sets the value of the columns property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setColumns(Integer value) {
-        this.columns = value;
+@XmlType(
+  name = "DoubleMatrix",
+  namespace = "www.jalview.org",
+  propOrder =
+  { "row", "d", "e" })
+public class DoubleMatrix
+{
+
+  protected List<DoubleVector> row;
+
+  @XmlElement(name = "D")
+  protected DoubleVector d;
+
+  @XmlElement(name = "E")
+  protected DoubleVector e;
+
+  @XmlAttribute(name = "rows")
+  protected Integer rows;
+
+  @XmlAttribute(name = "columns")
+  protected Integer columns;
+
+  /**
+   * Gets the value of the row property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the row property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getRow().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link DoubleVector }
+   * 
+   * 
+   */
+  public List<DoubleVector> getRow()
+  {
+    if (row == null)
+    {
+      row = new ArrayList<DoubleVector>();
     }
+    return this.row;
+  }
+
+  /**
+   * Gets the value of the d property.
+   * 
+   * @return possible object is {@link DoubleVector }
+   * 
+   */
+  public DoubleVector getD()
+  {
+    return d;
+  }
+
+  /**
+   * Sets the value of the d property.
+   * 
+   * @param value
+   *          allowed object is {@link DoubleVector }
+   * 
+   */
+  public void setD(DoubleVector value)
+  {
+    this.d = value;
+  }
+
+  /**
+   * Gets the value of the e property.
+   * 
+   * @return possible object is {@link DoubleVector }
+   * 
+   */
+  public DoubleVector getE()
+  {
+    return e;
+  }
+
+  /**
+   * Sets the value of the e property.
+   * 
+   * @param value
+   *          allowed object is {@link DoubleVector }
+   * 
+   */
+  public void setE(DoubleVector value)
+  {
+    this.e = value;
+  }
+
+  /**
+   * Gets the value of the rows property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getRows()
+  {
+    return rows;
+  }
+
+  /**
+   * Sets the value of the rows property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setRows(Integer value)
+  {
+    this.rows = value;
+  }
+
+  /**
+   * Gets the value of the columns property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getColumns()
+  {
+    return columns;
+  }
+
+  /**
+   * Sets the value of the columns property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setColumns(Integer value)
+  {
+    this.columns = value;
+  }
 
 }
index 6546be9..3b449fe 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -15,11 +14,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for DoubleVector complex type.
+ * <p>
+ * Java class for DoubleVector complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="DoubleVector">
@@ -36,41 +37,46 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "DoubleVector", namespace = "www.jalview.org", propOrder = {
-    "v"
-})
-public class DoubleVector {
+@XmlType(
+  name = "DoubleVector",
+  namespace = "www.jalview.org",
+  propOrder =
+  { "v" })
+public class DoubleVector
+{
 
-    @XmlElement(type = Double.class)
-    protected List<Double> v;
+  @XmlElement(type = Double.class)
+  protected List<Double> v;
 
-    /**
-     * Gets the value of the v property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the v property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getV().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Double }
-     * 
-     * 
-     */
-    public List<Double> getV() {
-        if (v == null) {
-            v = new ArrayList<Double>();
-        }
-        return this.v;
+  /**
+   * Gets the value of the v property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the v property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getV().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Double }
+   * 
+   * 
+   */
+  public List<Double> getV()
+  {
+    if (v == null)
+    {
+      v = new ArrayList<Double>();
     }
+    return this.v;
+  }
 
 }
index a124e62..afedb4c 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -15,11 +14,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for feature complex type.
+ * <p>
+ * Java class for feature complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="feature">
@@ -53,311 +54,325 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "feature", namespace = "www.jalview.org", propOrder = {
-    "otherData"
-})
-public class Feature {
-
-    protected List<Feature.OtherData> otherData;
-    @XmlAttribute(name = "begin", required = true)
-    protected int begin;
-    @XmlAttribute(name = "end", required = true)
-    protected int end;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "description")
-    protected String description;
-    @XmlAttribute(name = "status")
-    protected String status;
-    @XmlAttribute(name = "featureGroup")
-    protected String featureGroup;
-    @XmlAttribute(name = "score")
-    protected Float score;
-
-    /**
-     * Gets the value of the otherData property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the otherData property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getOtherData().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Feature.OtherData }
-     * 
-     * 
-     */
-    public List<Feature.OtherData> getOtherData() {
-        if (otherData == null) {
-            otherData = new ArrayList<Feature.OtherData>();
-        }
-        return this.otherData;
+@XmlType(
+  name = "feature",
+  namespace = "www.jalview.org",
+  propOrder =
+  { "otherData" })
+public class Feature
+{
+
+  protected List<Feature.OtherData> otherData;
+
+  @XmlAttribute(name = "begin", required = true)
+  protected int begin;
+
+  @XmlAttribute(name = "end", required = true)
+  protected int end;
+
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
+
+  @XmlAttribute(name = "description")
+  protected String description;
+
+  @XmlAttribute(name = "status")
+  protected String status;
+
+  @XmlAttribute(name = "featureGroup")
+  protected String featureGroup;
+
+  @XmlAttribute(name = "score")
+  protected Float score;
+
+  /**
+   * Gets the value of the otherData property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the otherData property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getOtherData().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link Feature.OtherData }
+   * 
+   * 
+   */
+  public List<Feature.OtherData> getOtherData()
+  {
+    if (otherData == null)
+    {
+      otherData = new ArrayList<Feature.OtherData>();
     }
+    return this.otherData;
+  }
+
+  /**
+   * Gets the value of the begin property.
+   * 
+   */
+  public int getBegin()
+  {
+    return begin;
+  }
+
+  /**
+   * Sets the value of the begin property.
+   * 
+   */
+  public void setBegin(int value)
+  {
+    this.begin = value;
+  }
+
+  /**
+   * Gets the value of the end property.
+   * 
+   */
+  public int getEnd()
+  {
+    return end;
+  }
+
+  /**
+   * Sets the value of the end property.
+   * 
+   */
+  public void setEnd(int value)
+  {
+    this.end = value;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
+
+  /**
+   * Gets the value of the description property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /**
+   * Sets the value of the description property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDescription(String value)
+  {
+    this.description = value;
+  }
+
+  /**
+   * Gets the value of the status property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getStatus()
+  {
+    return status;
+  }
+
+  /**
+   * Sets the value of the status property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setStatus(String value)
+  {
+    this.status = value;
+  }
+
+  /**
+   * Gets the value of the featureGroup property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getFeatureGroup()
+  {
+    return featureGroup;
+  }
+
+  /**
+   * Sets the value of the featureGroup property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setFeatureGroup(String value)
+  {
+    this.featureGroup = value;
+  }
+
+  /**
+   * Gets the value of the score property.
+   * 
+   * @return possible object is {@link Float }
+   * 
+   */
+  public Float getScore()
+  {
+    return score;
+  }
+
+  /**
+   * Sets the value of the score property.
+   * 
+   * @param value
+   *          allowed object is {@link Float }
+   * 
+   */
+  public void setScore(Float value)
+  {
+    this.score = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="key" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="key2" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class OtherData
+  {
+
+    @XmlAttribute(name = "key", required = true)
+    protected String key;
+
+    @XmlAttribute(name = "key2")
+    protected String key2;
+
+    @XmlAttribute(name = "value", required = true)
+    protected String value;
 
     /**
-     * Gets the value of the begin property.
+     * Gets the value of the key property.
      * 
-     */
-    public int getBegin() {
-        return begin;
-    }
-
-    /**
-     * Sets the value of the begin property.
-     * 
-     */
-    public void setBegin(int value) {
-        this.begin = value;
-    }
-
-    /**
-     * Gets the value of the end property.
-     * 
-     */
-    public int getEnd() {
-        return end;
-    }
-
-    /**
-     * Sets the value of the end property.
-     * 
-     */
-    public void setEnd(int value) {
-        this.end = value;
-    }
-
-    /**
-     * Gets the value of the type property.
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getType() {
-        return type;
+    public String getKey()
+    {
+      return key;
     }
 
     /**
-     * Sets the value of the type property.
+     * Sets the value of the key property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
-
-    /**
-     * Gets the value of the description property.
+     *          allowed object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getDescription() {
-        return description;
+    public void setKey(String value)
+    {
+      this.key = value;
     }
 
     /**
-     * Sets the value of the description property.
+     * Gets the value of the key2 property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDescription(String value) {
-        this.description = value;
-    }
-
-    /**
-     * Gets the value of the status property.
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getStatus() {
-        return status;
+    public String getKey2()
+    {
+      return key2;
     }
 
     /**
-     * Sets the value of the status property.
+     * Sets the value of the key2 property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setStatus(String value) {
-        this.status = value;
-    }
-
-    /**
-     * Gets the value of the featureGroup property.
+     *          allowed object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getFeatureGroup() {
-        return featureGroup;
+    public void setKey2(String value)
+    {
+      this.key2 = value;
     }
 
     /**
-     * Sets the value of the featureGroup property.
+     * Gets the value of the value property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setFeatureGroup(String value) {
-        this.featureGroup = value;
-    }
-
-    /**
-     * Gets the value of the score property.
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link Float }
-     *     
      */
-    public Float getScore() {
-        return score;
+    public String getValue()
+    {
+      return value;
     }
 
     /**
-     * Sets the value of the score property.
+     * Sets the value of the value property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link Float }
-     *     
-     */
-    public void setScore(Float value) {
-        this.score = value;
-    }
-
-
-    /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="key" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="key2" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
-     * 
+     *          allowed object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class OtherData {
-
-        @XmlAttribute(name = "key", required = true)
-        protected String key;
-        @XmlAttribute(name = "key2")
-        protected String key2;
-        @XmlAttribute(name = "value", required = true)
-        protected String value;
-
-        /**
-         * Gets the value of the key property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getKey() {
-            return key;
-        }
-
-        /**
-         * Sets the value of the key property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setKey(String value) {
-            this.key = value;
-        }
-
-        /**
-         * Gets the value of the key2 property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getKey2() {
-            return key2;
-        }
-
-        /**
-         * Sets the value of the key2 property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setKey2(String value) {
-            this.key2 = value;
-        }
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-
+    public void setValue(String value)
+    {
+      this.value = value;
     }
 
+  }
+
 }
index 61e66ce..fa80569 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for FeatureMatcher complex type.
+ * <p>
+ * Java class for FeatureMatcher complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="FeatureMatcher">
@@ -40,121 +41,124 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "FeatureMatcher", namespace = "www.jalview.org/colours", propOrder = {
-    "attributeName",
-    "condition",
-    "value"
-})
-public class FeatureMatcher {
+@XmlType(
+  name = "FeatureMatcher",
+  namespace = "www.jalview.org/colours",
+  propOrder =
+  { "attributeName", "condition", "value" })
+public class FeatureMatcher
+{
 
-    @XmlElement(namespace = "")
-    protected List<String> attributeName;
-    @XmlElement(namespace = "", required = true)
-    protected String condition;
-    @XmlElement(namespace = "", required = true)
-    protected String value;
-    @XmlAttribute(name = "by")
-    protected FilterBy by;
+  @XmlElement(namespace = "")
+  protected List<String> attributeName;
 
-    /**
-     * Gets the value of the attributeName property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the attributeName property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getAttributeName().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getAttributeName() {
-        if (attributeName == null) {
-            attributeName = new ArrayList<String>();
-        }
-        return this.attributeName;
-    }
+  @XmlElement(namespace = "", required = true)
+  protected String condition;
 
-    /**
-     * Gets the value of the condition property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getCondition() {
-        return condition;
-    }
+  @XmlElement(namespace = "", required = true)
+  protected String value;
 
-    /**
-     * Sets the value of the condition property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setCondition(String value) {
-        this.condition = value;
-    }
+  @XmlAttribute(name = "by")
+  protected FilterBy by;
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
+  /**
+   * Gets the value of the attributeName property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the attributeName property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getAttributeName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getAttributeName()
+  {
+    if (attributeName == null)
+    {
+      attributeName = new ArrayList<String>();
     }
+    return this.attributeName;
+  }
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  /**
+   * Gets the value of the condition property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getCondition()
+  {
+    return condition;
+  }
 
-    /**
-     * Gets the value of the by property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link FilterBy }
-     *     
-     */
-    public FilterBy getBy() {
-        return by;
-    }
+  /**
+   * Sets the value of the condition property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setCondition(String value)
+  {
+    this.condition = value;
+  }
 
-    /**
-     * Sets the value of the by property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link FilterBy }
-     *     
-     */
-    public void setBy(FilterBy value) {
-        this.by = value;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
+
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
+
+  /**
+   * Gets the value of the by property.
+   * 
+   * @return possible object is {@link FilterBy }
+   * 
+   */
+  public FilterBy getBy()
+  {
+    return by;
+  }
+
+  /**
+   * Sets the value of the by property.
+   * 
+   * @param value
+   *          allowed object is {@link FilterBy }
+   * 
+   */
+  public void setBy(FilterBy value)
+  {
+    this.by = value;
+  }
 
 }
index 24190b8..45077af 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -16,13 +15,15 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * A feature match condition, which may be simple or compound
  * 
- * <p>Java class for FeatureMatcherSet complex type.
+ * <p>
+ * Java class for FeatureMatcherSet complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="FeatureMatcherSet">
@@ -51,142 +52,150 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "FeatureMatcherSet", namespace = "www.jalview.org/colours", propOrder = {
-    "matchCondition",
-    "compoundMatcher"
-})
-public class FeatureMatcherSet {
-
-    @XmlElement(namespace = "")
-    protected FeatureMatcher matchCondition;
-    @XmlElement(namespace = "")
-    protected FeatureMatcherSet.CompoundMatcher compoundMatcher;
+@XmlType(
+  name = "FeatureMatcherSet",
+  namespace = "www.jalview.org/colours",
+  propOrder =
+  { "matchCondition", "compoundMatcher" })
+public class FeatureMatcherSet
+{
+
+  @XmlElement(namespace = "")
+  protected FeatureMatcher matchCondition;
+
+  @XmlElement(namespace = "")
+  protected FeatureMatcherSet.CompoundMatcher compoundMatcher;
+
+  /**
+   * Gets the value of the matchCondition property.
+   * 
+   * @return possible object is {@link FeatureMatcher }
+   * 
+   */
+  public FeatureMatcher getMatchCondition()
+  {
+    return matchCondition;
+  }
+
+  /**
+   * Sets the value of the matchCondition property.
+   * 
+   * @param value
+   *          allowed object is {@link FeatureMatcher }
+   * 
+   */
+  public void setMatchCondition(FeatureMatcher value)
+  {
+    this.matchCondition = value;
+  }
+
+  /**
+   * Gets the value of the compoundMatcher property.
+   * 
+   * @return possible object is {@link FeatureMatcherSet.CompoundMatcher }
+   * 
+   */
+  public FeatureMatcherSet.CompoundMatcher getCompoundMatcher()
+  {
+    return compoundMatcher;
+  }
+
+  /**
+   * Sets the value of the compoundMatcher property.
+   * 
+   * @param value
+   *          allowed object is {@link FeatureMatcherSet.CompoundMatcher }
+   * 
+   */
+  public void setCompoundMatcher(FeatureMatcherSet.CompoundMatcher value)
+  {
+    this.compoundMatcher = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="matcherSet" type="{www.jalview.org/colours}FeatureMatcherSet" maxOccurs="2" minOccurs="2"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="and" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "matcherSet" })
+  public static class CompoundMatcher
+  {
+
+    @XmlElement(namespace = "", required = true)
+    protected List<FeatureMatcherSet> matcherSet;
+
+    @XmlAttribute(name = "and", required = true)
+    protected boolean and;
 
     /**
-     * Gets the value of the matchCondition property.
+     * Gets the value of the matcherSet property.
      * 
-     * @return
-     *     possible object is
-     *     {@link FeatureMatcher }
-     *     
-     */
-    public FeatureMatcher getMatchCondition() {
-        return matchCondition;
-    }
-
-    /**
-     * Sets the value of the matchCondition property.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the matcherSet property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getMatcherSet().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link FeatureMatcherSet }
      * 
-     * @param value
-     *     allowed object is
-     *     {@link FeatureMatcher }
-     *     
-     */
-    public void setMatchCondition(FeatureMatcher value) {
-        this.matchCondition = value;
-    }
-
-    /**
-     * Gets the value of the compoundMatcher property.
      * 
-     * @return
-     *     possible object is
-     *     {@link FeatureMatcherSet.CompoundMatcher }
-     *     
      */
-    public FeatureMatcherSet.CompoundMatcher getCompoundMatcher() {
-        return compoundMatcher;
+    public List<FeatureMatcherSet> getMatcherSet()
+    {
+      if (matcherSet == null)
+      {
+        matcherSet = new ArrayList<FeatureMatcherSet>();
+      }
+      return this.matcherSet;
     }
 
     /**
-     * Sets the value of the compoundMatcher property.
+     * Gets the value of the and property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link FeatureMatcherSet.CompoundMatcher }
-     *     
      */
-    public void setCompoundMatcher(FeatureMatcherSet.CompoundMatcher value) {
-        this.compoundMatcher = value;
+    public boolean isAnd()
+    {
+      return and;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="matcherSet" type="{www.jalview.org/colours}FeatureMatcherSet" maxOccurs="2" minOccurs="2"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="and" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
-     * 
+     * Sets the value of the and property.
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "matcherSet"
-    })
-    public static class CompoundMatcher {
-
-        @XmlElement(namespace = "", required = true)
-        protected List<FeatureMatcherSet> matcherSet;
-        @XmlAttribute(name = "and", required = true)
-        protected boolean and;
-
-        /**
-         * Gets the value of the matcherSet property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the matcherSet property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getMatcherSet().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link FeatureMatcherSet }
-         * 
-         * 
-         */
-        public List<FeatureMatcherSet> getMatcherSet() {
-            if (matcherSet == null) {
-                matcherSet = new ArrayList<FeatureMatcherSet>();
-            }
-            return this.matcherSet;
-        }
-
-        /**
-         * Gets the value of the and property.
-         * 
-         */
-        public boolean isAnd() {
-            return and;
-        }
-
-        /**
-         * Sets the value of the and property.
-         * 
-         */
-        public void setAnd(boolean value) {
-            this.and = value;
-        }
-
+    public void setAnd(boolean value)
+    {
+      this.and = value;
     }
 
+  }
+
 }
index 3a9428c..76fc6cd 100644 (file)
@@ -2,22 +2,24 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlEnum;
 import javax.xml.bind.annotation.XmlEnumValue;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for FilterBy.
+ * <p>
+ * Java class for FilterBy.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
  * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
+ * <p>
+ * 
  * <pre>
  * &lt;simpleType name="FilterBy">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -31,31 +33,36 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlType(name = "FilterBy", namespace = "www.jalview.org/colours")
 @XmlEnum
-public enum FilterBy {
-
-    @XmlEnumValue("byLabel")
-    BY_LABEL("byLabel"),
-    @XmlEnumValue("byScore")
-    BY_SCORE("byScore"),
-    @XmlEnumValue("byAttribute")
-    BY_ATTRIBUTE("byAttribute");
-    private final String value;
-
-    FilterBy(String v) {
-        value = v;
-    }
+public enum FilterBy
+{
 
-    public String value() {
-        return value;
-    }
+  @XmlEnumValue("byLabel")
+  BY_LABEL("byLabel"), @XmlEnumValue("byScore")
+  BY_SCORE("byScore"), @XmlEnumValue("byAttribute")
+  BY_ATTRIBUTE("byAttribute");
+
+  private final String value;
+
+  FilterBy(String v)
+  {
+    value = v;
+  }
+
+  public String value()
+  {
+    return value;
+  }
 
-    public static FilterBy fromValue(String v) {
-        for (FilterBy c: FilterBy.values()) {
-            if (c.value.equals(v)) {
-                return c;
-            }
-        }
-        throw new IllegalArgumentException(v);
+  public static FilterBy fromValue(String v)
+  {
+    for (FilterBy c : FilterBy.values())
+    {
+      if (c.value.equals(v))
+      {
+        return c;
+      }
     }
+    throw new IllegalArgumentException(v);
+  }
 
 }
index 22b2533..94f9373 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -22,11 +21,13 @@ import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import javax.xml.datatype.XMLGregorianCalendar;
 
-
 /**
- * <p>Java class for JalviewModel complex type.
+ * <p>
+ * Java class for JalviewModel complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="JalviewModel">
@@ -381,2762 +382,3475 @@ import javax.xml.datatype.XMLGregorianCalendar;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "JalviewModel", namespace = "www.jalview.org", propOrder = {
-    "creationDate",
-    "version",
-    "vamsasModel",
-    "jSeq",
-    "jGroup",
-    "viewport",
-    "userColours",
-    "tree",
-    "pcaViewer",
-    "featureSettings"
-})
-public class JalviewModel {
-
-    @XmlElement(required = true)
-    @XmlSchemaType(name = "dateTime")
-    protected XMLGregorianCalendar creationDate;
-    @XmlElement(required = true)
-    protected String version;
-    @XmlElement(required = true)
-    protected VAMSAS vamsasModel;
-    @XmlElement(name = "JSeq")
-    protected List<JalviewModel.JSeq> jSeq;
-    @XmlElement(name = "JGroup")
-    protected List<JalviewModel.JGroup> jGroup;
-    @XmlElement(name = "Viewport")
-    protected List<JalviewModel.Viewport> viewport;
-    @XmlElement(name = "UserColours")
-    protected List<JalviewModel.UserColours> userColours;
-    protected List<JalviewModel.Tree> tree;
-    @XmlElement(name = "PcaViewer")
-    protected List<JalviewModel.PcaViewer> pcaViewer;
-    @XmlElement(name = "FeatureSettings")
-    protected JalviewModel.FeatureSettings featureSettings;
-
-    /**
-     * Gets the value of the creationDate property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public XMLGregorianCalendar getCreationDate() {
-        return creationDate;
-    }
-
-    /**
-     * Sets the value of the creationDate property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public void setCreationDate(XMLGregorianCalendar value) {
-        this.creationDate = value;
+@XmlType(
+  name = "JalviewModel",
+  namespace = "www.jalview.org",
+  propOrder =
+  { "creationDate", "version", "vamsasModel", "jSeq", "jGroup", "viewport",
+      "userColours", "tree", "pcaViewer", "featureSettings" })
+public class JalviewModel
+{
+
+  @XmlElement(required = true)
+  @XmlSchemaType(name = "dateTime")
+  protected XMLGregorianCalendar creationDate;
+
+  @XmlElement(required = true)
+  protected String version;
+
+  @XmlElement(required = true)
+  protected VAMSAS vamsasModel;
+
+  @XmlElement(name = "JSeq")
+  protected List<JalviewModel.JSeq> jSeq;
+
+  @XmlElement(name = "JGroup")
+  protected List<JalviewModel.JGroup> jGroup;
+
+  @XmlElement(name = "Viewport")
+  protected List<JalviewModel.Viewport> viewport;
+
+  @XmlElement(name = "UserColours")
+  protected List<JalviewModel.UserColours> userColours;
+
+  protected List<JalviewModel.Tree> tree;
+
+  @XmlElement(name = "PcaViewer")
+  protected List<JalviewModel.PcaViewer> pcaViewer;
+
+  @XmlElement(name = "FeatureSettings")
+  protected JalviewModel.FeatureSettings featureSettings;
+
+  /**
+   * Gets the value of the creationDate property.
+   * 
+   * @return possible object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public XMLGregorianCalendar getCreationDate()
+  {
+    return creationDate;
+  }
+
+  /**
+   * Sets the value of the creationDate property.
+   * 
+   * @param value
+   *          allowed object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public void setCreationDate(XMLGregorianCalendar value)
+  {
+    this.creationDate = value;
+  }
+
+  /**
+   * Gets the value of the version property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getVersion()
+  {
+    return version;
+  }
+
+  /**
+   * Sets the value of the version property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setVersion(String value)
+  {
+    this.version = value;
+  }
+
+  /**
+   * Gets the value of the vamsasModel property.
+   * 
+   * @return possible object is {@link VAMSAS }
+   * 
+   */
+  public VAMSAS getVamsasModel()
+  {
+    return vamsasModel;
+  }
+
+  /**
+   * Sets the value of the vamsasModel property.
+   * 
+   * @param value
+   *          allowed object is {@link VAMSAS }
+   * 
+   */
+  public void setVamsasModel(VAMSAS value)
+  {
+    this.vamsasModel = value;
+  }
+
+  /**
+   * Gets the value of the jSeq property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the jSeq property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getJSeq().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link JalviewModel.JSeq }
+   * 
+   * 
+   */
+  public List<JalviewModel.JSeq> getJSeq()
+  {
+    if (jSeq == null)
+    {
+      jSeq = new ArrayList<JalviewModel.JSeq>();
     }
-
-    /**
-     * Gets the value of the version property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getVersion() {
-        return version;
+    return this.jSeq;
+  }
+
+  /**
+   * Gets the value of the jGroup property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the jGroup property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getJGroup().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link JalviewModel.JGroup }
+   * 
+   * 
+   */
+  public List<JalviewModel.JGroup> getJGroup()
+  {
+    if (jGroup == null)
+    {
+      jGroup = new ArrayList<JalviewModel.JGroup>();
     }
-
-    /**
-     * Sets the value of the version property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setVersion(String value) {
-        this.version = value;
+    return this.jGroup;
+  }
+
+  /**
+   * Gets the value of the viewport property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the viewport property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getViewport().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link JalviewModel.Viewport }
+   * 
+   * 
+   */
+  public List<JalviewModel.Viewport> getViewport()
+  {
+    if (viewport == null)
+    {
+      viewport = new ArrayList<JalviewModel.Viewport>();
     }
-
-    /**
-     * Gets the value of the vamsasModel property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link VAMSAS }
-     *     
-     */
-    public VAMSAS getVamsasModel() {
-        return vamsasModel;
+    return this.viewport;
+  }
+
+  /**
+   * Gets the value of the userColours property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the userColours property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getUserColours().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link JalviewModel.UserColours }
+   * 
+   * 
+   */
+  public List<JalviewModel.UserColours> getUserColours()
+  {
+    if (userColours == null)
+    {
+      userColours = new ArrayList<JalviewModel.UserColours>();
     }
-
-    /**
-     * Sets the value of the vamsasModel property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link VAMSAS }
-     *     
-     */
-    public void setVamsasModel(VAMSAS value) {
-        this.vamsasModel = value;
+    return this.userColours;
+  }
+
+  /**
+   * Gets the value of the tree property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the tree property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getTree().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link JalviewModel.Tree }
+   * 
+   * 
+   */
+  public List<JalviewModel.Tree> getTree()
+  {
+    if (tree == null)
+    {
+      tree = new ArrayList<JalviewModel.Tree>();
+    }
+    return this.tree;
+  }
+
+  /**
+   * Gets the value of the pcaViewer property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the pcaViewer property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getPcaViewer().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link JalviewModel.PcaViewer }
+   * 
+   * 
+   */
+  public List<JalviewModel.PcaViewer> getPcaViewer()
+  {
+    if (pcaViewer == null)
+    {
+      pcaViewer = new ArrayList<JalviewModel.PcaViewer>();
     }
+    return this.pcaViewer;
+  }
+
+  /**
+   * Gets the value of the featureSettings property.
+   * 
+   * @return possible object is {@link JalviewModel.FeatureSettings }
+   * 
+   */
+  public JalviewModel.FeatureSettings getFeatureSettings()
+  {
+    return featureSettings;
+  }
+
+  /**
+   * Sets the value of the featureSettings property.
+   * 
+   * @param value
+   *          allowed object is {@link JalviewModel.FeatureSettings }
+   * 
+   */
+  public void setFeatureSettings(JalviewModel.FeatureSettings value)
+  {
+    this.featureSettings = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="setting" maxOccurs="unbounded" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;sequence>
+   *                   &lt;element name="attributeName" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="2" minOccurs="0"/>
+   *                   &lt;element name="matcherSet" type="{www.jalview.org/colours}FeatureMatcherSet" minOccurs="0"/>
+   *                 &lt;/sequence>
+   *                 &lt;attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="colour" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *                 &lt;attribute name="display" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *                 &lt;attribute name="order" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *                 &lt;attribute name="mincolour" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *                 &lt;attribute name="noValueColour" type="{www.jalview.org/colours}NoValueColour" default="Min" />
+   *                 &lt;attribute name="threshold" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *                 &lt;attribute name="threshstate" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *                 &lt;attribute name="max" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *                 &lt;attribute name="min" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *                 &lt;attribute name="colourByLabel" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *                 &lt;attribute name="autoScale" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="group" maxOccurs="unbounded" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="display" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "setting", "group" })
+  public static class FeatureSettings
+  {
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected List<JalviewModel.FeatureSettings.Setting> setting;
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected List<JalviewModel.FeatureSettings.Group> group;
 
     /**
-     * Gets the value of the jSeq property.
+     * Gets the value of the setting property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the jSeq property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the setting property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getJSeq().add(newItem);
+     * getSetting().add(newItem);
      * </pre>
      * 
      * 
      * <p>
      * Objects of the following type(s) are allowed in the list
-     * {@link JalviewModel.JSeq }
+     * {@link JalviewModel.FeatureSettings.Setting }
      * 
      * 
      */
-    public List<JalviewModel.JSeq> getJSeq() {
-        if (jSeq == null) {
-            jSeq = new ArrayList<JalviewModel.JSeq>();
-        }
-        return this.jSeq;
+    public List<JalviewModel.FeatureSettings.Setting> getSetting()
+    {
+      if (setting == null)
+      {
+        setting = new ArrayList<JalviewModel.FeatureSettings.Setting>();
+      }
+      return this.setting;
     }
 
     /**
-     * Gets the value of the jGroup property.
+     * Gets the value of the group property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the jGroup property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the group property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getJGroup().add(newItem);
+     * getGroup().add(newItem);
      * </pre>
      * 
      * 
      * <p>
      * Objects of the following type(s) are allowed in the list
-     * {@link JalviewModel.JGroup }
+     * {@link JalviewModel.FeatureSettings.Group }
      * 
      * 
      */
-    public List<JalviewModel.JGroup> getJGroup() {
-        if (jGroup == null) {
-            jGroup = new ArrayList<JalviewModel.JGroup>();
-        }
-        return this.jGroup;
+    public List<JalviewModel.FeatureSettings.Group> getGroup()
+    {
+      if (group == null)
+      {
+        group = new ArrayList<JalviewModel.FeatureSettings.Group>();
+      }
+      return this.group;
     }
 
     /**
-     * Gets the value of the viewport property.
-     * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the viewport property.
+     * Java class for anonymous complex type.
      * 
      * <p>
-     * For example, to add a new item, do as follows:
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
      * <pre>
-     *    getViewport().add(newItem);
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="display" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
      * </pre>
      * 
      * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Group
+    {
+
+      @XmlAttribute(name = "name", required = true)
+      protected String name;
+
+      @XmlAttribute(name = "display", required = true)
+      protected boolean display;
+
+      /**
+       * Gets the value of the name property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getName()
+      {
+        return name;
+      }
+
+      /**
+       * Sets the value of the name property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setName(String value)
+      {
+        this.name = value;
+      }
+
+      /**
+       * Gets the value of the display property.
+       * 
+       */
+      public boolean isDisplay()
+      {
+        return display;
+      }
+
+      /**
+       * Sets the value of the display property.
+       * 
+       */
+      public void setDisplay(boolean value)
+      {
+        this.display = value;
+      }
+
+    }
+
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
      * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link JalviewModel.Viewport }
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;element name="attributeName" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="2" minOccurs="0"/>
+     *         &lt;element name="matcherSet" type="{www.jalview.org/colours}FeatureMatcherSet" minOccurs="0"/>
+     *       &lt;/sequence>
+     *       &lt;attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="colour" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *       &lt;attribute name="display" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *       &lt;attribute name="order" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *       &lt;attribute name="mincolour" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *       &lt;attribute name="noValueColour" type="{www.jalview.org/colours}NoValueColour" default="Min" />
+     *       &lt;attribute name="threshold" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *       &lt;attribute name="threshstate" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *       &lt;attribute name="max" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *       &lt;attribute name="min" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *       &lt;attribute name="colourByLabel" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *       &lt;attribute name="autoScale" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
      * 
      * 
      */
-    public List<JalviewModel.Viewport> getViewport() {
-        if (viewport == null) {
-            viewport = new ArrayList<JalviewModel.Viewport>();
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = { "attributeName", "matcherSet" })
+    public static class Setting
+    {
+
+      @XmlElement(namespace = "www.jalview.org")
+      protected List<String> attributeName;
+
+      @XmlElement(namespace = "www.jalview.org")
+      protected FeatureMatcherSet matcherSet;
+
+      @XmlAttribute(name = "type", required = true)
+      protected String type;
+
+      @XmlAttribute(name = "colour", required = true)
+      protected int colour;
+
+      @XmlAttribute(name = "display", required = true)
+      protected boolean display;
+
+      @XmlAttribute(name = "order")
+      protected Float order;
+
+      @XmlAttribute(name = "mincolour")
+      protected Integer mincolour;
+
+      @XmlAttribute(name = "noValueColour")
+      protected NoValueColour noValueColour;
+
+      @XmlAttribute(name = "threshold")
+      protected Float threshold;
+
+      @XmlAttribute(name = "threshstate")
+      protected Integer threshstate;
+
+      @XmlAttribute(name = "max")
+      protected Float max;
+
+      @XmlAttribute(name = "min")
+      protected Float min;
+
+      @XmlAttribute(name = "colourByLabel")
+      protected Boolean colourByLabel;
+
+      @XmlAttribute(name = "autoScale")
+      protected Boolean autoScale;
+
+      /**
+       * Gets the value of the attributeName property.
+       * 
+       * <p>
+       * This accessor method returns a reference to the live list, not a
+       * snapshot. Therefore any modification you make to the returned list will
+       * be present inside the JAXB object. This is why there is not a
+       * <CODE>set</CODE> method for the attributeName property.
+       * 
+       * <p>
+       * For example, to add a new item, do as follows:
+       * 
+       * <pre>
+       * getAttributeName().add(newItem);
+       * </pre>
+       * 
+       * 
+       * <p>
+       * Objects of the following type(s) are allowed in the list {@link String
+       * }
+       * 
+       * 
+       */
+      public List<String> getAttributeName()
+      {
+        if (attributeName == null)
+        {
+          attributeName = new ArrayList<String>();
+        }
+        return this.attributeName;
+      }
+
+      /**
+       * Gets the value of the matcherSet property.
+       * 
+       * @return possible object is {@link FeatureMatcherSet }
+       * 
+       */
+      public FeatureMatcherSet getMatcherSet()
+      {
+        return matcherSet;
+      }
+
+      /**
+       * Sets the value of the matcherSet property.
+       * 
+       * @param value
+       *          allowed object is {@link FeatureMatcherSet }
+       * 
+       */
+      public void setMatcherSet(FeatureMatcherSet value)
+      {
+        this.matcherSet = value;
+      }
+
+      /**
+       * Gets the value of the type property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getType()
+      {
+        return type;
+      }
+
+      /**
+       * Sets the value of the type property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setType(String value)
+      {
+        this.type = value;
+      }
+
+      /**
+       * Gets the value of the colour property.
+       * 
+       */
+      public int getColour()
+      {
+        return colour;
+      }
+
+      /**
+       * Sets the value of the colour property.
+       * 
+       */
+      public void setColour(int value)
+      {
+        this.colour = value;
+      }
+
+      /**
+       * Gets the value of the display property.
+       * 
+       */
+      public boolean isDisplay()
+      {
+        return display;
+      }
+
+      /**
+       * Sets the value of the display property.
+       * 
+       */
+      public void setDisplay(boolean value)
+      {
+        this.display = value;
+      }
+
+      /**
+       * Gets the value of the order property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getOrder()
+      {
+        return order;
+      }
+
+      /**
+       * Sets the value of the order property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setOrder(Float value)
+      {
+        this.order = value;
+      }
+
+      /**
+       * Gets the value of the mincolour property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getMincolour()
+      {
+        return mincolour;
+      }
+
+      /**
+       * Sets the value of the mincolour property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setMincolour(Integer value)
+      {
+        this.mincolour = value;
+      }
+
+      /**
+       * Gets the value of the noValueColour property.
+       * 
+       * @return possible object is {@link NoValueColour }
+       * 
+       */
+      public NoValueColour getNoValueColour()
+      {
+        if (noValueColour == null)
+        {
+          return NoValueColour.MIN;
         }
-        return this.viewport;
+        else
+        {
+          return noValueColour;
+        }
+      }
+
+      /**
+       * Sets the value of the noValueColour property.
+       * 
+       * @param value
+       *          allowed object is {@link NoValueColour }
+       * 
+       */
+      public void setNoValueColour(NoValueColour value)
+      {
+        this.noValueColour = value;
+      }
+
+      /**
+       * Gets the value of the threshold property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getThreshold()
+      {
+        return threshold;
+      }
+
+      /**
+       * Sets the value of the threshold property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setThreshold(Float value)
+      {
+        this.threshold = value;
+      }
+
+      /**
+       * Gets the value of the threshstate property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getThreshstate()
+      {
+        return threshstate;
+      }
+
+      /**
+       * Sets the value of the threshstate property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setThreshstate(Integer value)
+      {
+        this.threshstate = value;
+      }
+
+      /**
+       * Gets the value of the max property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getMax()
+      {
+        return max;
+      }
+
+      /**
+       * Sets the value of the max property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setMax(Float value)
+      {
+        this.max = value;
+      }
+
+      /**
+       * Gets the value of the min property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getMin()
+      {
+        return min;
+      }
+
+      /**
+       * Sets the value of the min property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setMin(Float value)
+      {
+        this.min = value;
+      }
+
+      /**
+       * Gets the value of the colourByLabel property.
+       * 
+       * @return possible object is {@link Boolean }
+       * 
+       */
+      public Boolean isColourByLabel()
+      {
+        return colourByLabel;
+      }
+
+      /**
+       * Sets the value of the colourByLabel property.
+       * 
+       * @param value
+       *          allowed object is {@link Boolean }
+       * 
+       */
+      public void setColourByLabel(Boolean value)
+      {
+        this.colourByLabel = value;
+      }
+
+      /**
+       * Gets the value of the autoScale property.
+       * 
+       * @return possible object is {@link Boolean }
+       * 
+       */
+      public Boolean isAutoScale()
+      {
+        return autoScale;
+      }
+
+      /**
+       * Sets the value of the autoScale property.
+       * 
+       * @param value
+       *          allowed object is {@link Boolean }
+       * 
+       */
+      public void setAutoScale(Boolean value)
+      {
+        this.autoScale = value;
+      }
+
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="seq" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
+   *         &lt;element name="annotationColours" type="{www.jalview.org}AnnotationColourScheme" minOccurs="0"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="start" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="end" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="colour" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="consThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="pidThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="outlineColour" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="displayBoxes" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="displayText" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="colourText" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="textCol1" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="textCol2" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="textColThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="showUnconserved" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="ignoreGapsinConsensus" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *       &lt;attribute name="showConsensusHistogram" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *       &lt;attribute name="showSequenceLogo" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="normaliseSequenceLogo" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "seq", "annotationColours" })
+  public static class JGroup
+  {
+
+    @XmlElement(namespace = "www.jalview.org", required = true)
+    protected List<String> seq;
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected AnnotationColourScheme annotationColours;
+
+    @XmlAttribute(name = "start")
+    protected Integer start;
+
+    @XmlAttribute(name = "end")
+    protected Integer end;
+
+    @XmlAttribute(name = "name")
+    protected String name;
+
+    @XmlAttribute(name = "colour")
+    protected String colour;
+
+    @XmlAttribute(name = "consThreshold")
+    protected Integer consThreshold;
+
+    @XmlAttribute(name = "pidThreshold")
+    protected Integer pidThreshold;
+
+    @XmlAttribute(name = "outlineColour")
+    protected Integer outlineColour;
+
+    @XmlAttribute(name = "displayBoxes")
+    protected Boolean displayBoxes;
+
+    @XmlAttribute(name = "displayText")
+    protected Boolean displayText;
+
+    @XmlAttribute(name = "colourText")
+    protected Boolean colourText;
+
+    @XmlAttribute(name = "textCol1")
+    protected Integer textCol1;
+
+    @XmlAttribute(name = "textCol2")
+    protected Integer textCol2;
+
+    @XmlAttribute(name = "textColThreshold")
+    protected Integer textColThreshold;
+
+    @XmlAttribute(name = "showUnconserved")
+    protected Boolean showUnconserved;
+
+    @XmlAttribute(name = "ignoreGapsinConsensus")
+    protected Boolean ignoreGapsinConsensus;
+
+    @XmlAttribute(name = "showConsensusHistogram")
+    protected Boolean showConsensusHistogram;
+
+    @XmlAttribute(name = "showSequenceLogo")
+    protected Boolean showSequenceLogo;
+
+    @XmlAttribute(name = "normaliseSequenceLogo")
+    protected Boolean normaliseSequenceLogo;
+
+    @XmlAttribute(name = "id")
+    protected String id;
+
     /**
-     * Gets the value of the userColours property.
+     * Gets the value of the seq property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the userColours property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the seq property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getUserColours().add(newItem);
+     * getSeq().add(newItem);
      * </pre>
      * 
      * 
      * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link JalviewModel.UserColours }
+     * Objects of the following type(s) are allowed in the list {@link String }
      * 
      * 
      */
-    public List<JalviewModel.UserColours> getUserColours() {
-        if (userColours == null) {
-            userColours = new ArrayList<JalviewModel.UserColours>();
-        }
-        return this.userColours;
+    public List<String> getSeq()
+    {
+      if (seq == null)
+      {
+        seq = new ArrayList<String>();
+      }
+      return this.seq;
     }
 
     /**
-     * Gets the value of the tree property.
+     * Gets the value of the annotationColours property.
      * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the tree property.
+     * @return possible object is {@link AnnotationColourScheme }
      * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getTree().add(newItem);
-     * </pre>
+     */
+    public AnnotationColourScheme getAnnotationColours()
+    {
+      return annotationColours;
+    }
+
+    /**
+     * Sets the value of the annotationColours property.
      * 
+     * @param value
+     *          allowed object is {@link AnnotationColourScheme }
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link JalviewModel.Tree }
+     */
+    public void setAnnotationColours(AnnotationColourScheme value)
+    {
+      this.annotationColours = value;
+    }
+
+    /**
+     * Gets the value of the start property.
      * 
+     * @return possible object is {@link Integer }
      * 
      */
-    public List<JalviewModel.Tree> getTree() {
-        if (tree == null) {
-            tree = new ArrayList<JalviewModel.Tree>();
-        }
-        return this.tree;
+    public Integer getStart()
+    {
+      return start;
     }
 
     /**
-     * Gets the value of the pcaViewer property.
+     * Sets the value of the start property.
      * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the pcaViewer property.
+     * @param value
+     *          allowed object is {@link Integer }
      * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getPcaViewer().add(newItem);
-     * </pre>
+     */
+    public void setStart(Integer value)
+    {
+      this.start = value;
+    }
+
+    /**
+     * Gets the value of the end property.
      * 
+     * @return possible object is {@link Integer }
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link JalviewModel.PcaViewer }
+     */
+    public Integer getEnd()
+    {
+      return end;
+    }
+
+    /**
+     * Sets the value of the end property.
      * 
+     * @param value
+     *          allowed object is {@link Integer }
      * 
      */
-    public List<JalviewModel.PcaViewer> getPcaViewer() {
-        if (pcaViewer == null) {
-            pcaViewer = new ArrayList<JalviewModel.PcaViewer>();
-        }
-        return this.pcaViewer;
+    public void setEnd(Integer value)
+    {
+      this.end = value;
     }
 
     /**
-     * Gets the value of the featureSettings property.
+     * Gets the value of the name property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link JalviewModel.FeatureSettings }
-     *     
      */
-    public JalviewModel.FeatureSettings getFeatureSettings() {
-        return featureSettings;
+    public String getName()
+    {
+      return name;
     }
 
     /**
-     * Sets the value of the featureSettings property.
+     * Sets the value of the name property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link JalviewModel.FeatureSettings }
-     *     
+     *          allowed object is {@link String }
+     * 
      */
-    public void setFeatureSettings(JalviewModel.FeatureSettings value) {
-        this.featureSettings = value;
+    public void setName(String value)
+    {
+      this.name = value;
     }
 
+    /**
+     * Gets the value of the colour property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getColour()
+    {
+      return colour;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Sets the value of the colour property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @param value
+     *          allowed object is {@link String }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="setting" maxOccurs="unbounded" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;sequence>
-     *                   &lt;element name="attributeName" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="2" minOccurs="0"/>
-     *                   &lt;element name="matcherSet" type="{www.jalview.org/colours}FeatureMatcherSet" minOccurs="0"/>
-     *                 &lt;/sequence>
-     *                 &lt;attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="colour" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *                 &lt;attribute name="display" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *                 &lt;attribute name="order" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *                 &lt;attribute name="mincolour" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *                 &lt;attribute name="noValueColour" type="{www.jalview.org/colours}NoValueColour" default="Min" />
-     *                 &lt;attribute name="threshold" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *                 &lt;attribute name="threshstate" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *                 &lt;attribute name="max" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *                 &lt;attribute name="min" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *                 &lt;attribute name="colourByLabel" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *                 &lt;attribute name="autoScale" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="group" maxOccurs="unbounded" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="display" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public void setColour(String value)
+    {
+      this.colour = value;
+    }
+
+    /**
+     * Gets the value of the consThreshold property.
      * 
+     * @return possible object is {@link Integer }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "setting",
-        "group"
-    })
-    public static class FeatureSettings {
+    public Integer getConsThreshold()
+    {
+      return consThreshold;
+    }
 
-        @XmlElement(namespace = "www.jalview.org")
-        protected List<JalviewModel.FeatureSettings.Setting> setting;
-        @XmlElement(namespace = "www.jalview.org")
-        protected List<JalviewModel.FeatureSettings.Group> group;
+    /**
+     * Sets the value of the consThreshold property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setConsThreshold(Integer value)
+    {
+      this.consThreshold = value;
+    }
 
-        /**
-         * Gets the value of the setting property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the setting property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getSetting().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link JalviewModel.FeatureSettings.Setting }
-         * 
-         * 
-         */
-        public List<JalviewModel.FeatureSettings.Setting> getSetting() {
-            if (setting == null) {
-                setting = new ArrayList<JalviewModel.FeatureSettings.Setting>();
-            }
-            return this.setting;
-        }
+    /**
+     * Gets the value of the pidThreshold property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getPidThreshold()
+    {
+      return pidThreshold;
+    }
 
-        /**
-         * Gets the value of the group property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the group property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getGroup().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link JalviewModel.FeatureSettings.Group }
-         * 
-         * 
-         */
-        public List<JalviewModel.FeatureSettings.Group> getGroup() {
-            if (group == null) {
-                group = new ArrayList<JalviewModel.FeatureSettings.Group>();
-            }
-            return this.group;
-        }
+    /**
+     * Sets the value of the pidThreshold property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setPidThreshold(Integer value)
+    {
+      this.pidThreshold = value;
+    }
 
+    /**
+     * Gets the value of the outlineColour property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getOutlineColour()
+    {
+      return outlineColour;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="display" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class Group {
-
-            @XmlAttribute(name = "name", required = true)
-            protected String name;
-            @XmlAttribute(name = "display", required = true)
-            protected boolean display;
-
-            /**
-             * Gets the value of the name property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getName() {
-                return name;
-            }
-
-            /**
-             * Sets the value of the name property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setName(String value) {
-                this.name = value;
-            }
-
-            /**
-             * Gets the value of the display property.
-             * 
-             */
-            public boolean isDisplay() {
-                return display;
-            }
-
-            /**
-             * Sets the value of the display property.
-             * 
-             */
-            public void setDisplay(boolean value) {
-                this.display = value;
-            }
+    /**
+     * Sets the value of the outlineColour property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setOutlineColour(Integer value)
+    {
+      this.outlineColour = value;
+    }
 
-        }
+    /**
+     * Gets the value of the displayBoxes property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isDisplayBoxes()
+    {
+      return displayBoxes;
+    }
 
+    /**
+     * Sets the value of the displayBoxes property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setDisplayBoxes(Boolean value)
+    {
+      this.displayBoxes = value;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;sequence>
-         *         &lt;element name="attributeName" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="2" minOccurs="0"/>
-         *         &lt;element name="matcherSet" type="{www.jalview.org/colours}FeatureMatcherSet" minOccurs="0"/>
-         *       &lt;/sequence>
-         *       &lt;attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="colour" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *       &lt;attribute name="display" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-         *       &lt;attribute name="order" type="{http://www.w3.org/2001/XMLSchema}float" />
-         *       &lt;attribute name="mincolour" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *       &lt;attribute name="noValueColour" type="{www.jalview.org/colours}NoValueColour" default="Min" />
-         *       &lt;attribute name="threshold" type="{http://www.w3.org/2001/XMLSchema}float" />
-         *       &lt;attribute name="threshstate" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *       &lt;attribute name="max" type="{http://www.w3.org/2001/XMLSchema}float" />
-         *       &lt;attribute name="min" type="{http://www.w3.org/2001/XMLSchema}float" />
-         *       &lt;attribute name="colourByLabel" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-         *       &lt;attribute name="autoScale" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "", propOrder = {
-            "attributeName",
-            "matcherSet"
-        })
-        public static class Setting {
-
-            @XmlElement(namespace = "www.jalview.org")
-            protected List<String> attributeName;
-            @XmlElement(namespace = "www.jalview.org")
-            protected FeatureMatcherSet matcherSet;
-            @XmlAttribute(name = "type", required = true)
-            protected String type;
-            @XmlAttribute(name = "colour", required = true)
-            protected int colour;
-            @XmlAttribute(name = "display", required = true)
-            protected boolean display;
-            @XmlAttribute(name = "order")
-            protected Float order;
-            @XmlAttribute(name = "mincolour")
-            protected Integer mincolour;
-            @XmlAttribute(name = "noValueColour")
-            protected NoValueColour noValueColour;
-            @XmlAttribute(name = "threshold")
-            protected Float threshold;
-            @XmlAttribute(name = "threshstate")
-            protected Integer threshstate;
-            @XmlAttribute(name = "max")
-            protected Float max;
-            @XmlAttribute(name = "min")
-            protected Float min;
-            @XmlAttribute(name = "colourByLabel")
-            protected Boolean colourByLabel;
-            @XmlAttribute(name = "autoScale")
-            protected Boolean autoScale;
-
-            /**
-             * Gets the value of the attributeName property.
-             * 
-             * <p>
-             * This accessor method returns a reference to the live list,
-             * not a snapshot. Therefore any modification you make to the
-             * returned list will be present inside the JAXB object.
-             * This is why there is not a <CODE>set</CODE> method for the attributeName property.
-             * 
-             * <p>
-             * For example, to add a new item, do as follows:
-             * <pre>
-             *    getAttributeName().add(newItem);
-             * </pre>
-             * 
-             * 
-             * <p>
-             * Objects of the following type(s) are allowed in the list
-             * {@link String }
-             * 
-             * 
-             */
-            public List<String> getAttributeName() {
-                if (attributeName == null) {
-                    attributeName = new ArrayList<String>();
-                }
-                return this.attributeName;
-            }
-
-            /**
-             * Gets the value of the matcherSet property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link FeatureMatcherSet }
-             *     
-             */
-            public FeatureMatcherSet getMatcherSet() {
-                return matcherSet;
-            }
-
-            /**
-             * Sets the value of the matcherSet property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link FeatureMatcherSet }
-             *     
-             */
-            public void setMatcherSet(FeatureMatcherSet value) {
-                this.matcherSet = value;
-            }
-
-            /**
-             * Gets the value of the type property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getType() {
-                return type;
-            }
-
-            /**
-             * Sets the value of the type property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setType(String value) {
-                this.type = value;
-            }
-
-            /**
-             * Gets the value of the colour property.
-             * 
-             */
-            public int getColour() {
-                return colour;
-            }
-
-            /**
-             * Sets the value of the colour property.
-             * 
-             */
-            public void setColour(int value) {
-                this.colour = value;
-            }
-
-            /**
-             * Gets the value of the display property.
-             * 
-             */
-            public boolean isDisplay() {
-                return display;
-            }
-
-            /**
-             * Sets the value of the display property.
-             * 
-             */
-            public void setDisplay(boolean value) {
-                this.display = value;
-            }
-
-            /**
-             * Gets the value of the order property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getOrder() {
-                return order;
-            }
-
-            /**
-             * Sets the value of the order property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setOrder(Float value) {
-                this.order = value;
-            }
-
-            /**
-             * Gets the value of the mincolour property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getMincolour() {
-                return mincolour;
-            }
-
-            /**
-             * Sets the value of the mincolour property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setMincolour(Integer value) {
-                this.mincolour = value;
-            }
-
-            /**
-             * Gets the value of the noValueColour property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link NoValueColour }
-             *     
-             */
-            public NoValueColour getNoValueColour() {
-                if (noValueColour == null) {
-                    return NoValueColour.MIN;
-                } else {
-                    return noValueColour;
-                }
-            }
-
-            /**
-             * Sets the value of the noValueColour property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link NoValueColour }
-             *     
-             */
-            public void setNoValueColour(NoValueColour value) {
-                this.noValueColour = value;
-            }
-
-            /**
-             * Gets the value of the threshold property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getThreshold() {
-                return threshold;
-            }
-
-            /**
-             * Sets the value of the threshold property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setThreshold(Float value) {
-                this.threshold = value;
-            }
-
-            /**
-             * Gets the value of the threshstate property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getThreshstate() {
-                return threshstate;
-            }
-
-            /**
-             * Sets the value of the threshstate property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setThreshstate(Integer value) {
-                this.threshstate = value;
-            }
-
-            /**
-             * Gets the value of the max property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getMax() {
-                return max;
-            }
-
-            /**
-             * Sets the value of the max property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setMax(Float value) {
-                this.max = value;
-            }
-
-            /**
-             * Gets the value of the min property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getMin() {
-                return min;
-            }
-
-            /**
-             * Sets the value of the min property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setMin(Float value) {
-                this.min = value;
-            }
-
-            /**
-             * Gets the value of the colourByLabel property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Boolean }
-             *     
-             */
-            public Boolean isColourByLabel() {
-                return colourByLabel;
-            }
-
-            /**
-             * Sets the value of the colourByLabel property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Boolean }
-             *     
-             */
-            public void setColourByLabel(Boolean value) {
-                this.colourByLabel = value;
-            }
-
-            /**
-             * Gets the value of the autoScale property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Boolean }
-             *     
-             */
-            public Boolean isAutoScale() {
-                return autoScale;
-            }
-
-            /**
-             * Sets the value of the autoScale property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Boolean }
-             *     
-             */
-            public void setAutoScale(Boolean value) {
-                this.autoScale = value;
-            }
+    /**
+     * Gets the value of the displayText property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isDisplayText()
+    {
+      return displayText;
+    }
 
-        }
+    /**
+     * Sets the value of the displayText property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setDisplayText(Boolean value)
+    {
+      this.displayText = value;
+    }
 
+    /**
+     * Gets the value of the colourText property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isColourText()
+    {
+      return colourText;
     }
 
+    /**
+     * Sets the value of the colourText property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setColourText(Boolean value)
+    {
+      this.colourText = value;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the textCol1 property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @return possible object is {@link Integer }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="seq" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
-     *         &lt;element name="annotationColours" type="{www.jalview.org}AnnotationColourScheme" minOccurs="0"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="start" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="end" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="colour" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="consThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="pidThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="outlineColour" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="displayBoxes" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="displayText" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="colourText" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="textCol1" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="textCol2" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="textColThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="showUnconserved" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="ignoreGapsinConsensus" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *       &lt;attribute name="showConsensusHistogram" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *       &lt;attribute name="showSequenceLogo" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="normaliseSequenceLogo" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public Integer getTextCol1()
+    {
+      return textCol1;
+    }
+
+    /**
+     * Sets the value of the textCol1 property.
      * 
+     * @param value
+     *          allowed object is {@link Integer }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "seq",
-        "annotationColours"
-    })
-    public static class JGroup {
-
-        @XmlElement(namespace = "www.jalview.org", required = true)
-        protected List<String> seq;
-        @XmlElement(namespace = "www.jalview.org")
-        protected AnnotationColourScheme annotationColours;
-        @XmlAttribute(name = "start")
-        protected Integer start;
-        @XmlAttribute(name = "end")
-        protected Integer end;
-        @XmlAttribute(name = "name")
-        protected String name;
-        @XmlAttribute(name = "colour")
-        protected String colour;
-        @XmlAttribute(name = "consThreshold")
-        protected Integer consThreshold;
-        @XmlAttribute(name = "pidThreshold")
-        protected Integer pidThreshold;
-        @XmlAttribute(name = "outlineColour")
-        protected Integer outlineColour;
-        @XmlAttribute(name = "displayBoxes")
-        protected Boolean displayBoxes;
-        @XmlAttribute(name = "displayText")
-        protected Boolean displayText;
-        @XmlAttribute(name = "colourText")
-        protected Boolean colourText;
-        @XmlAttribute(name = "textCol1")
-        protected Integer textCol1;
-        @XmlAttribute(name = "textCol2")
-        protected Integer textCol2;
-        @XmlAttribute(name = "textColThreshold")
-        protected Integer textColThreshold;
-        @XmlAttribute(name = "showUnconserved")
-        protected Boolean showUnconserved;
-        @XmlAttribute(name = "ignoreGapsinConsensus")
-        protected Boolean ignoreGapsinConsensus;
-        @XmlAttribute(name = "showConsensusHistogram")
-        protected Boolean showConsensusHistogram;
-        @XmlAttribute(name = "showSequenceLogo")
-        protected Boolean showSequenceLogo;
-        @XmlAttribute(name = "normaliseSequenceLogo")
-        protected Boolean normaliseSequenceLogo;
-        @XmlAttribute(name = "id")
-        protected String id;
+    public void setTextCol1(Integer value)
+    {
+      this.textCol1 = value;
+    }
 
-        /**
-         * Gets the value of the seq property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the seq property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getSeq().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link String }
-         * 
-         * 
-         */
-        public List<String> getSeq() {
-            if (seq == null) {
-                seq = new ArrayList<String>();
-            }
-            return this.seq;
-        }
+    /**
+     * Gets the value of the textCol2 property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getTextCol2()
+    {
+      return textCol2;
+    }
+
+    /**
+     * Sets the value of the textCol2 property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setTextCol2(Integer value)
+    {
+      this.textCol2 = value;
+    }
+
+    /**
+     * Gets the value of the textColThreshold property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getTextColThreshold()
+    {
+      return textColThreshold;
+    }
+
+    /**
+     * Sets the value of the textColThreshold property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setTextColThreshold(Integer value)
+    {
+      this.textColThreshold = value;
+    }
+
+    /**
+     * Gets the value of the showUnconserved property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowUnconserved()
+    {
+      return showUnconserved;
+    }
+
+    /**
+     * Sets the value of the showUnconserved property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowUnconserved(Boolean value)
+    {
+      this.showUnconserved = value;
+    }
+
+    /**
+     * Gets the value of the ignoreGapsinConsensus property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isIgnoreGapsinConsensus()
+    {
+      if (ignoreGapsinConsensus == null)
+      {
+        return true;
+      }
+      else
+      {
+        return ignoreGapsinConsensus;
+      }
+    }
+
+    /**
+     * Sets the value of the ignoreGapsinConsensus property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setIgnoreGapsinConsensus(Boolean value)
+    {
+      this.ignoreGapsinConsensus = value;
+    }
+
+    /**
+     * Gets the value of the showConsensusHistogram property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowConsensusHistogram()
+    {
+      if (showConsensusHistogram == null)
+      {
+        return true;
+      }
+      else
+      {
+        return showConsensusHistogram;
+      }
+    }
+
+    /**
+     * Sets the value of the showConsensusHistogram property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowConsensusHistogram(Boolean value)
+    {
+      this.showConsensusHistogram = value;
+    }
+
+    /**
+     * Gets the value of the showSequenceLogo property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowSequenceLogo()
+    {
+      if (showSequenceLogo == null)
+      {
+        return false;
+      }
+      else
+      {
+        return showSequenceLogo;
+      }
+    }
+
+    /**
+     * Sets the value of the showSequenceLogo property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowSequenceLogo(Boolean value)
+    {
+      this.showSequenceLogo = value;
+    }
+
+    /**
+     * Gets the value of the normaliseSequenceLogo property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isNormaliseSequenceLogo()
+    {
+      if (normaliseSequenceLogo == null)
+      {
+        return false;
+      }
+      else
+      {
+        return normaliseSequenceLogo;
+      }
+    }
+
+    /**
+     * Sets the value of the normaliseSequenceLogo property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setNormaliseSequenceLogo(Boolean value)
+    {
+      this.normaliseSequenceLogo = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getId()
+    {
+      return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setId(String value)
+    {
+      this.id = value;
+    }
+
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="features" type="{www.jalview.org}feature" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="pdbids" maxOccurs="unbounded" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;extension base="{www.jalview.org}pdbentry">
+   *                 &lt;sequence>
+   *                   &lt;element name="structureState" maxOccurs="unbounded" minOccurs="0">
+   *                     &lt;complexType>
+   *                       &lt;simpleContent>
+   *                         &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+   *                           &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+   *                           &lt;attribute name="visible" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *                           &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                           &lt;attribute name="alignwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *                           &lt;attribute name="colourwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *                           &lt;attribute name="colourByJmol" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *                           &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                         &lt;/extension>
+   *                       &lt;/simpleContent>
+   *                     &lt;/complexType>
+   *                   &lt;/element>
+   *                 &lt;/sequence>
+   *               &lt;/extension>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="hiddenSequences" type="{http://www.w3.org/2001/XMLSchema}int" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="rnaViewer" maxOccurs="unbounded" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;sequence>
+   *                   &lt;element name="secondaryStructure" maxOccurs="unbounded">
+   *                     &lt;complexType>
+   *                       &lt;complexContent>
+   *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                           &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                           &lt;attribute name="annotationId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                           &lt;attribute name="gapped" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *                           &lt;attribute name="viewerState" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                         &lt;/restriction>
+   *                       &lt;/complexContent>
+   *                     &lt;/complexType>
+   *                   &lt;/element>
+   *                 &lt;/sequence>
+   *                 &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+   *                 &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="dividerLocation" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *                 &lt;attribute name="selectedRna" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *       &lt;/sequence>
+   *       &lt;attribute name="colour" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="start" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="hidden" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="viewreference" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(
+    name = "",
+    propOrder =
+    { "features", "pdbids", "hiddenSequences", "rnaViewer" })
+  public static class JSeq
+  {
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected List<Feature> features;
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected List<JalviewModel.JSeq.Pdbids> pdbids;
+
+    @XmlElement(namespace = "www.jalview.org", type = Integer.class)
+    protected List<Integer> hiddenSequences;
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected List<JalviewModel.JSeq.RnaViewer> rnaViewer;
+
+    @XmlAttribute(name = "colour")
+    protected Integer colour;
+
+    @XmlAttribute(name = "start", required = true)
+    protected int start;
+
+    @XmlAttribute(name = "end", required = true)
+    protected int end;
+
+    @XmlAttribute(name = "id", required = true)
+    protected String id;
+
+    @XmlAttribute(name = "hidden")
+    protected Boolean hidden;
+
+    @XmlAttribute(name = "viewreference")
+    protected Boolean viewreference;
+
+    /**
+     * Gets the value of the features property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the features property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getFeatures().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link Feature }
+     * 
+     * 
+     */
+    public List<Feature> getFeatures()
+    {
+      if (features == null)
+      {
+        features = new ArrayList<Feature>();
+      }
+      return this.features;
+    }
+
+    /**
+     * Gets the value of the pdbids property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the pdbids property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getPdbids().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link JalviewModel.JSeq.Pdbids }
+     * 
+     * 
+     */
+    public List<JalviewModel.JSeq.Pdbids> getPdbids()
+    {
+      if (pdbids == null)
+      {
+        pdbids = new ArrayList<JalviewModel.JSeq.Pdbids>();
+      }
+      return this.pdbids;
+    }
+
+    /**
+     * Gets the value of the hiddenSequences property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the hiddenSequences property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getHiddenSequences().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link Integer }
+     * 
+     * 
+     */
+    public List<Integer> getHiddenSequences()
+    {
+      if (hiddenSequences == null)
+      {
+        hiddenSequences = new ArrayList<Integer>();
+      }
+      return this.hiddenSequences;
+    }
+
+    /**
+     * Gets the value of the rnaViewer property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the rnaViewer property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getRnaViewer().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link JalviewModel.JSeq.RnaViewer }
+     * 
+     * 
+     */
+    public List<JalviewModel.JSeq.RnaViewer> getRnaViewer()
+    {
+      if (rnaViewer == null)
+      {
+        rnaViewer = new ArrayList<JalviewModel.JSeq.RnaViewer>();
+      }
+      return this.rnaViewer;
+    }
+
+    /**
+     * Gets the value of the colour property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getColour()
+    {
+      return colour;
+    }
+
+    /**
+     * Sets the value of the colour property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setColour(Integer value)
+    {
+      this.colour = value;
+    }
+
+    /**
+     * Gets the value of the start property.
+     * 
+     */
+    public int getStart()
+    {
+      return start;
+    }
+
+    /**
+     * Sets the value of the start property.
+     * 
+     */
+    public void setStart(int value)
+    {
+      this.start = value;
+    }
+
+    /**
+     * Gets the value of the end property.
+     * 
+     */
+    public int getEnd()
+    {
+      return end;
+    }
+
+    /**
+     * Sets the value of the end property.
+     * 
+     */
+    public void setEnd(int value)
+    {
+      this.end = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getId()
+    {
+      return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setId(String value)
+    {
+      this.id = value;
+    }
+
+    /**
+     * Gets the value of the hidden property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isHidden()
+    {
+      return hidden;
+    }
+
+    /**
+     * Sets the value of the hidden property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setHidden(Boolean value)
+    {
+      this.hidden = value;
+    }
+
+    /**
+     * Gets the value of the viewreference property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isViewreference()
+    {
+      return viewreference;
+    }
+
+    /**
+     * Sets the value of the viewreference property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setViewreference(Boolean value)
+    {
+      this.viewreference = value;
+    }
+
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;extension base="{www.jalview.org}pdbentry">
+     *       &lt;sequence>
+     *         &lt;element name="structureState" maxOccurs="unbounded" minOccurs="0">
+     *           &lt;complexType>
+     *             &lt;simpleContent>
+     *               &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+     *                 &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+     *                 &lt;attribute name="visible" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *                 &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *                 &lt;attribute name="alignwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+     *                 &lt;attribute name="colourwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+     *                 &lt;attribute name="colourByJmol" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+     *                 &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *               &lt;/extension>
+     *             &lt;/simpleContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *       &lt;/sequence>
+     *     &lt;/extension>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = { "structureState" })
+    public static class Pdbids extends Pdbentry
+    {
+
+      @XmlElement(namespace = "www.jalview.org")
+      protected List<JalviewModel.JSeq.Pdbids.StructureState> structureState;
+
+      /**
+       * Gets the value of the structureState property.
+       * 
+       * <p>
+       * This accessor method returns a reference to the live list, not a
+       * snapshot. Therefore any modification you make to the returned list will
+       * be present inside the JAXB object. This is why there is not a
+       * <CODE>set</CODE> method for the structureState property.
+       * 
+       * <p>
+       * For example, to add a new item, do as follows:
+       * 
+       * <pre>
+       * getStructureState().add(newItem);
+       * </pre>
+       * 
+       * 
+       * <p>
+       * Objects of the following type(s) are allowed in the list
+       * {@link JalviewModel.JSeq.Pdbids.StructureState }
+       * 
+       * 
+       */
+      public List<JalviewModel.JSeq.Pdbids.StructureState> getStructureState()
+      {
+        if (structureState == null)
+        {
+          structureState = new ArrayList<JalviewModel.JSeq.Pdbids.StructureState>();
+        }
+        return this.structureState;
+      }
+
+      /**
+       * <p>
+       * Java class for anonymous complex type.
+       * 
+       * <p>
+       * The following schema fragment specifies the expected content contained
+       * within this class.
+       * 
+       * <pre>
+       * &lt;complexType>
+       *   &lt;simpleContent>
+       *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+       *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+       *       &lt;attribute name="visible" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+       *       &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
+       *       &lt;attribute name="alignwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+       *       &lt;attribute name="colourwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+       *       &lt;attribute name="colourByJmol" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+       *       &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+       *     &lt;/extension>
+       *   &lt;/simpleContent>
+       * &lt;/complexType>
+       * </pre>
+       * 
+       * 
+       */
+      @XmlAccessorType(XmlAccessType.FIELD)
+      @XmlType(name = "", propOrder = { "value" })
+      public static class StructureState
+      {
+
+        @XmlValue
+        protected String value;
+
+        @XmlAttribute(name = "visible")
+        protected Boolean visible;
+
+        @XmlAttribute(name = "viewId")
+        protected String viewId;
+
+        @XmlAttribute(name = "alignwithAlignPanel")
+        protected Boolean alignwithAlignPanel;
+
+        @XmlAttribute(name = "colourwithAlignPanel")
+        protected Boolean colourwithAlignPanel;
+
+        @XmlAttribute(name = "colourByJmol")
+        protected Boolean colourByJmol;
+
+        @XmlAttribute(name = "type")
+        protected String type;
+
+        @XmlAttribute(name = "width")
+        protected Integer width;
+
+        @XmlAttribute(name = "height")
+        protected Integer height;
+
+        @XmlAttribute(name = "xpos")
+        protected Integer xpos;
 
-        /**
-         * Gets the value of the annotationColours property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link AnnotationColourScheme }
-         *     
-         */
-        public AnnotationColourScheme getAnnotationColours() {
-            return annotationColours;
-        }
+        @XmlAttribute(name = "ypos")
+        protected Integer ypos;
 
         /**
-         * Sets the value of the annotationColours property.
+         * Gets the value of the value property.
          * 
-         * @param value
-         *     allowed object is
-         *     {@link AnnotationColourScheme }
-         *     
-         */
-        public void setAnnotationColours(AnnotationColourScheme value) {
-            this.annotationColours = value;
-        }
-
-        /**
-         * Gets the value of the start property.
+         * @return possible object is {@link String }
          * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
          */
-        public Integer getStart() {
-            return start;
+        public String getValue()
+        {
+          return value;
         }
 
         /**
-         * Sets the value of the start property.
+         * Sets the value of the value property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setStart(Integer value) {
-            this.start = value;
-        }
-
-        /**
-         * Gets the value of the end property.
+         *          allowed object is {@link String }
          * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
          */
-        public Integer getEnd() {
-            return end;
+        public void setValue(String value)
+        {
+          this.value = value;
         }
 
         /**
-         * Sets the value of the end property.
+         * Gets the value of the visible property.
          * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setEnd(Integer value) {
-            this.end = value;
-        }
-
-        /**
-         * Gets the value of the name property.
+         * @return possible object is {@link Boolean }
          * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
          */
-        public String getName() {
-            return name;
+        public Boolean isVisible()
+        {
+          return visible;
         }
 
         /**
-         * Sets the value of the name property.
+         * Sets the value of the visible property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setName(String value) {
-            this.name = value;
-        }
-
-        /**
-         * Gets the value of the colour property.
+         *          allowed object is {@link Boolean }
          * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
          */
-        public String getColour() {
-            return colour;
+        public void setVisible(Boolean value)
+        {
+          this.visible = value;
         }
 
         /**
-         * Sets the value of the colour property.
+         * Gets the value of the viewId property.
          * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setColour(String value) {
-            this.colour = value;
-        }
-
-        /**
-         * Gets the value of the consThreshold property.
+         * @return possible object is {@link String }
          * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
          */
-        public Integer getConsThreshold() {
-            return consThreshold;
+        public String getViewId()
+        {
+          return viewId;
         }
 
         /**
-         * Sets the value of the consThreshold property.
+         * Sets the value of the viewId property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setConsThreshold(Integer value) {
-            this.consThreshold = value;
-        }
-
-        /**
-         * Gets the value of the pidThreshold property.
+         *          allowed object is {@link String }
          * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
          */
-        public Integer getPidThreshold() {
-            return pidThreshold;
+        public void setViewId(String value)
+        {
+          this.viewId = value;
         }
 
         /**
-         * Sets the value of the pidThreshold property.
+         * Gets the value of the alignwithAlignPanel property.
          * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setPidThreshold(Integer value) {
-            this.pidThreshold = value;
-        }
-
-        /**
-         * Gets the value of the outlineColour property.
+         * @return possible object is {@link Boolean }
          * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
          */
-        public Integer getOutlineColour() {
-            return outlineColour;
+        public boolean isAlignwithAlignPanel()
+        {
+          if (alignwithAlignPanel == null)
+          {
+            return true;
+          }
+          else
+          {
+            return alignwithAlignPanel;
+          }
         }
 
         /**
-         * Sets the value of the outlineColour property.
+         * Sets the value of the alignwithAlignPanel property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setOutlineColour(Integer value) {
-            this.outlineColour = value;
-        }
-
-        /**
-         * Gets the value of the displayBoxes property.
+         *          allowed object is {@link Boolean }
          * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
          */
-        public Boolean isDisplayBoxes() {
-            return displayBoxes;
+        public void setAlignwithAlignPanel(Boolean value)
+        {
+          this.alignwithAlignPanel = value;
         }
 
         /**
-         * Sets the value of the displayBoxes property.
+         * Gets the value of the colourwithAlignPanel property.
          * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setDisplayBoxes(Boolean value) {
-            this.displayBoxes = value;
-        }
-
-        /**
-         * Gets the value of the displayText property.
+         * @return possible object is {@link Boolean }
          * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
          */
-        public Boolean isDisplayText() {
-            return displayText;
+        public boolean isColourwithAlignPanel()
+        {
+          if (colourwithAlignPanel == null)
+          {
+            return false;
+          }
+          else
+          {
+            return colourwithAlignPanel;
+          }
         }
 
         /**
-         * Sets the value of the displayText property.
+         * Sets the value of the colourwithAlignPanel property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
+         *          allowed object is {@link Boolean }
+         * 
          */
-        public void setDisplayText(Boolean value) {
-            this.displayText = value;
+        public void setColourwithAlignPanel(Boolean value)
+        {
+          this.colourwithAlignPanel = value;
         }
 
         /**
-         * Gets the value of the colourText property.
+         * Gets the value of the colourByJmol property.
+         * 
+         * @return possible object is {@link Boolean }
          * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
          */
-        public Boolean isColourText() {
-            return colourText;
+        public boolean isColourByJmol()
+        {
+          if (colourByJmol == null)
+          {
+            return true;
+          }
+          else
+          {
+            return colourByJmol;
+          }
         }
 
         /**
-         * Sets the value of the colourText property.
+         * Sets the value of the colourByJmol property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
+         *          allowed object is {@link Boolean }
+         * 
          */
-        public void setColourText(Boolean value) {
-            this.colourText = value;
+        public void setColourByJmol(Boolean value)
+        {
+          this.colourByJmol = value;
         }
 
         /**
-         * Gets the value of the textCol1 property.
+         * Gets the value of the type property.
+         * 
+         * @return possible object is {@link String }
          * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
          */
-        public Integer getTextCol1() {
-            return textCol1;
+        public String getType()
+        {
+          return type;
         }
 
         /**
-         * Sets the value of the textCol1 property.
+         * Sets the value of the type property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
+         *          allowed object is {@link String }
+         * 
          */
-        public void setTextCol1(Integer value) {
-            this.textCol1 = value;
+        public void setType(String value)
+        {
+          this.type = value;
         }
 
         /**
-         * Gets the value of the textCol2 property.
+         * Gets the value of the width property.
+         * 
+         * @return possible object is {@link Integer }
          * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
          */
-        public Integer getTextCol2() {
-            return textCol2;
+        public Integer getWidth()
+        {
+          return width;
         }
 
         /**
-         * Sets the value of the textCol2 property.
+         * Sets the value of the width property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
+         *          allowed object is {@link Integer }
+         * 
          */
-        public void setTextCol2(Integer value) {
-            this.textCol2 = value;
+        public void setWidth(Integer value)
+        {
+          this.width = value;
         }
 
         /**
-         * Gets the value of the textColThreshold property.
+         * Gets the value of the height property.
+         * 
+         * @return possible object is {@link Integer }
          * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
          */
-        public Integer getTextColThreshold() {
-            return textColThreshold;
+        public Integer getHeight()
+        {
+          return height;
         }
 
         /**
-         * Sets the value of the textColThreshold property.
+         * Sets the value of the height property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
+         *          allowed object is {@link Integer }
+         * 
          */
-        public void setTextColThreshold(Integer value) {
-            this.textColThreshold = value;
+        public void setHeight(Integer value)
+        {
+          this.height = value;
         }
 
         /**
-         * Gets the value of the showUnconserved property.
+         * Gets the value of the xpos property.
+         * 
+         * @return possible object is {@link Integer }
          * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
          */
-        public Boolean isShowUnconserved() {
-            return showUnconserved;
+        public Integer getXpos()
+        {
+          return xpos;
         }
 
         /**
-         * Sets the value of the showUnconserved property.
+         * Sets the value of the xpos property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
+         *          allowed object is {@link Integer }
+         * 
          */
-        public void setShowUnconserved(Boolean value) {
-            this.showUnconserved = value;
+        public void setXpos(Integer value)
+        {
+          this.xpos = value;
         }
 
         /**
-         * Gets the value of the ignoreGapsinConsensus property.
+         * Gets the value of the ypos property.
+         * 
+         * @return possible object is {@link Integer }
          * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
          */
-        public boolean isIgnoreGapsinConsensus() {
-            if (ignoreGapsinConsensus == null) {
-                return true;
-            } else {
-                return ignoreGapsinConsensus;
-            }
+        public Integer getYpos()
+        {
+          return ypos;
         }
 
         /**
-         * Sets the value of the ignoreGapsinConsensus property.
+         * Sets the value of the ypos property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
+         *          allowed object is {@link Integer }
+         * 
          */
-        public void setIgnoreGapsinConsensus(Boolean value) {
-            this.ignoreGapsinConsensus = value;
+        public void setYpos(Integer value)
+        {
+          this.ypos = value;
         }
 
+      }
+
+    }
+
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;element name="secondaryStructure" maxOccurs="unbounded">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *                 &lt;attribute name="annotationId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *                 &lt;attribute name="gapped" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *                 &lt;attribute name="viewerState" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *       &lt;/sequence>
+     *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+     *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="dividerLocation" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *       &lt;attribute name="selectedRna" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = { "secondaryStructure" })
+    public static class RnaViewer
+    {
+
+      @XmlElement(namespace = "www.jalview.org", required = true)
+      protected List<JalviewModel.JSeq.RnaViewer.SecondaryStructure> secondaryStructure;
+
+      @XmlAttribute(name = "title")
+      protected String title;
+
+      @XmlAttribute(name = "viewId")
+      protected String viewId;
+
+      @XmlAttribute(name = "dividerLocation")
+      protected Integer dividerLocation;
+
+      @XmlAttribute(name = "selectedRna")
+      protected Integer selectedRna;
+
+      @XmlAttribute(name = "width")
+      protected Integer width;
+
+      @XmlAttribute(name = "height")
+      protected Integer height;
+
+      @XmlAttribute(name = "xpos")
+      protected Integer xpos;
+
+      @XmlAttribute(name = "ypos")
+      protected Integer ypos;
+
+      /**
+       * Gets the value of the secondaryStructure property.
+       * 
+       * <p>
+       * This accessor method returns a reference to the live list, not a
+       * snapshot. Therefore any modification you make to the returned list will
+       * be present inside the JAXB object. This is why there is not a
+       * <CODE>set</CODE> method for the secondaryStructure property.
+       * 
+       * <p>
+       * For example, to add a new item, do as follows:
+       * 
+       * <pre>
+       * getSecondaryStructure().add(newItem);
+       * </pre>
+       * 
+       * 
+       * <p>
+       * Objects of the following type(s) are allowed in the list
+       * {@link JalviewModel.JSeq.RnaViewer.SecondaryStructure }
+       * 
+       * 
+       */
+      public List<JalviewModel.JSeq.RnaViewer.SecondaryStructure> getSecondaryStructure()
+      {
+        if (secondaryStructure == null)
+        {
+          secondaryStructure = new ArrayList<JalviewModel.JSeq.RnaViewer.SecondaryStructure>();
+        }
+        return this.secondaryStructure;
+      }
+
+      /**
+       * Gets the value of the title property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getTitle()
+      {
+        return title;
+      }
+
+      /**
+       * Sets the value of the title property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setTitle(String value)
+      {
+        this.title = value;
+      }
+
+      /**
+       * Gets the value of the viewId property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getViewId()
+      {
+        return viewId;
+      }
+
+      /**
+       * Sets the value of the viewId property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setViewId(String value)
+      {
+        this.viewId = value;
+      }
+
+      /**
+       * Gets the value of the dividerLocation property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getDividerLocation()
+      {
+        return dividerLocation;
+      }
+
+      /**
+       * Sets the value of the dividerLocation property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setDividerLocation(Integer value)
+      {
+        this.dividerLocation = value;
+      }
+
+      /**
+       * Gets the value of the selectedRna property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getSelectedRna()
+      {
+        return selectedRna;
+      }
+
+      /**
+       * Sets the value of the selectedRna property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setSelectedRna(Integer value)
+      {
+        this.selectedRna = value;
+      }
+
+      /**
+       * Gets the value of the width property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getWidth()
+      {
+        return width;
+      }
+
+      /**
+       * Sets the value of the width property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setWidth(Integer value)
+      {
+        this.width = value;
+      }
+
+      /**
+       * Gets the value of the height property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getHeight()
+      {
+        return height;
+      }
+
+      /**
+       * Sets the value of the height property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setHeight(Integer value)
+      {
+        this.height = value;
+      }
+
+      /**
+       * Gets the value of the xpos property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getXpos()
+      {
+        return xpos;
+      }
+
+      /**
+       * Sets the value of the xpos property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setXpos(Integer value)
+      {
+        this.xpos = value;
+      }
+
+      /**
+       * Gets the value of the ypos property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getYpos()
+      {
+        return ypos;
+      }
+
+      /**
+       * Sets the value of the ypos property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setYpos(Integer value)
+      {
+        this.ypos = value;
+      }
+
+      /**
+       * <p>
+       * Java class for anonymous complex type.
+       * 
+       * <p>
+       * The following schema fragment specifies the expected content contained
+       * within this class.
+       * 
+       * <pre>
+       * &lt;complexType>
+       *   &lt;complexContent>
+       *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+       *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+       *       &lt;attribute name="annotationId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+       *       &lt;attribute name="gapped" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+       *       &lt;attribute name="viewerState" type="{http://www.w3.org/2001/XMLSchema}string" />
+       *     &lt;/restriction>
+       *   &lt;/complexContent>
+       * &lt;/complexType>
+       * </pre>
+       * 
+       * 
+       */
+      @XmlAccessorType(XmlAccessType.FIELD)
+      @XmlType(name = "")
+      public static class SecondaryStructure
+      {
+
+        @XmlAttribute(name = "title")
+        protected String title;
+
+        @XmlAttribute(name = "annotationId", required = true)
+        protected String annotationId;
+
+        @XmlAttribute(name = "gapped")
+        protected Boolean gapped;
+
+        @XmlAttribute(name = "viewerState")
+        protected String viewerState;
+
         /**
-         * Gets the value of the showConsensusHistogram property.
+         * Gets the value of the title property.
+         * 
+         * @return possible object is {@link String }
          * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
          */
-        public boolean isShowConsensusHistogram() {
-            if (showConsensusHistogram == null) {
-                return true;
-            } else {
-                return showConsensusHistogram;
-            }
+        public String getTitle()
+        {
+          return title;
         }
 
         /**
-         * Sets the value of the showConsensusHistogram property.
+         * Sets the value of the title property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
+         *          allowed object is {@link String }
+         * 
          */
-        public void setShowConsensusHistogram(Boolean value) {
-            this.showConsensusHistogram = value;
+        public void setTitle(String value)
+        {
+          this.title = value;
         }
 
         /**
-         * Gets the value of the showSequenceLogo property.
+         * Gets the value of the annotationId property.
+         * 
+         * @return possible object is {@link String }
          * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
          */
-        public boolean isShowSequenceLogo() {
-            if (showSequenceLogo == null) {
-                return false;
-            } else {
-                return showSequenceLogo;
-            }
+        public String getAnnotationId()
+        {
+          return annotationId;
         }
 
         /**
-         * Sets the value of the showSequenceLogo property.
+         * Sets the value of the annotationId property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
+         *          allowed object is {@link String }
+         * 
          */
-        public void setShowSequenceLogo(Boolean value) {
-            this.showSequenceLogo = value;
+        public void setAnnotationId(String value)
+        {
+          this.annotationId = value;
         }
 
         /**
-         * Gets the value of the normaliseSequenceLogo property.
+         * Gets the value of the gapped property.
+         * 
+         * @return possible object is {@link Boolean }
          * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
          */
-        public boolean isNormaliseSequenceLogo() {
-            if (normaliseSequenceLogo == null) {
-                return false;
-            } else {
-                return normaliseSequenceLogo;
-            }
+        public Boolean isGapped()
+        {
+          return gapped;
         }
 
         /**
-         * Sets the value of the normaliseSequenceLogo property.
+         * Sets the value of the gapped property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
+         *          allowed object is {@link Boolean }
+         * 
          */
-        public void setNormaliseSequenceLogo(Boolean value) {
-            this.normaliseSequenceLogo = value;
+        public void setGapped(Boolean value)
+        {
+          this.gapped = value;
         }
 
         /**
-         * Gets the value of the id property.
+         * Gets the value of the viewerState property.
+         * 
+         * @return possible object is {@link String }
          * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
          */
-        public String getId() {
-            return id;
+        public String getViewerState()
+        {
+          return viewerState;
         }
 
         /**
-         * Sets the value of the id property.
+         * Sets the value of the viewerState property.
          * 
          * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
+         *          allowed object is {@link String }
+         * 
          */
-        public void setId(String value) {
-            this.id = value;
+        public void setViewerState(String value)
+        {
+          this.viewerState = value;
         }
 
+      }
+
+    }
+
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="sequencePoint" maxOccurs="unbounded">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attGroup ref="{www.jalview.org}position"/>
+   *                 &lt;attribute name="sequenceRef" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="axis" maxOccurs="3" minOccurs="3">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attGroup ref="{www.jalview.org}position"/>
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="seqPointMin">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attGroup ref="{www.jalview.org}position"/>
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="seqPointMax">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attGroup ref="{www.jalview.org}position"/>
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="pcaData" type="{www.jalview.org}PcaDataType"/>
+   *       &lt;/sequence>
+   *       &lt;attGroup ref="{www.jalview.org}SimilarityParams"/>
+   *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+   *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="scoreModelName" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="xDim" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="yDim" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="zDim" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="bgColour" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="scaleFactor" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *       &lt;attribute name="showLabels" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="linkToAllViews" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(
+    name = "",
+    propOrder =
+    { "sequencePoint", "axis", "seqPointMin", "seqPointMax", "pcaData" })
+  public static class PcaViewer
+  {
+
+    @XmlElement(namespace = "www.jalview.org", required = true)
+    protected List<JalviewModel.PcaViewer.SequencePoint> sequencePoint;
+
+    @XmlElement(namespace = "www.jalview.org", required = true)
+    protected List<JalviewModel.PcaViewer.Axis> axis;
+
+    @XmlElement(namespace = "www.jalview.org", required = true)
+    protected JalviewModel.PcaViewer.SeqPointMin seqPointMin;
+
+    @XmlElement(namespace = "www.jalview.org", required = true)
+    protected JalviewModel.PcaViewer.SeqPointMax seqPointMax;
+
+    @XmlElement(namespace = "www.jalview.org", required = true)
+    protected PcaDataType pcaData;
+
+    @XmlAttribute(name = "title")
+    protected String title;
+
+    @XmlAttribute(name = "scoreModelName")
+    protected String scoreModelName;
+
+    @XmlAttribute(name = "xDim")
+    protected Integer xDim;
+
+    @XmlAttribute(name = "yDim")
+    protected Integer yDim;
+
+    @XmlAttribute(name = "zDim")
+    protected Integer zDim;
+
+    @XmlAttribute(name = "bgColour")
+    protected Integer bgColour;
+
+    @XmlAttribute(name = "scaleFactor")
+    protected Float scaleFactor;
+
+    @XmlAttribute(name = "showLabels")
+    protected Boolean showLabels;
+
+    @XmlAttribute(name = "linkToAllViews")
+    protected Boolean linkToAllViews;
+
+    @XmlAttribute(name = "includeGaps")
+    protected Boolean includeGaps;
+
+    @XmlAttribute(name = "matchGaps")
+    protected Boolean matchGaps;
+
+    @XmlAttribute(name = "includeGappedColumns")
+    protected Boolean includeGappedColumns;
+
+    @XmlAttribute(name = "denominateByShortestLength")
+    protected Boolean denominateByShortestLength;
+
+    @XmlAttribute(name = "width")
+    protected Integer width;
+
+    @XmlAttribute(name = "height")
+    protected Integer height;
+
+    @XmlAttribute(name = "xpos")
+    protected Integer xpos;
+
+    @XmlAttribute(name = "ypos")
+    protected Integer ypos;
+
+    /**
+     * Gets the value of the sequencePoint property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the sequencePoint property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getSequencePoint().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link JalviewModel.PcaViewer.SequencePoint }
+     * 
+     * 
+     */
+    public List<JalviewModel.PcaViewer.SequencePoint> getSequencePoint()
+    {
+      if (sequencePoint == null)
+      {
+        sequencePoint = new ArrayList<JalviewModel.PcaViewer.SequencePoint>();
+      }
+      return this.sequencePoint;
+    }
+
+    /**
+     * Gets the value of the axis property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the axis property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getAxis().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link JalviewModel.PcaViewer.Axis }
+     * 
+     * 
+     */
+    public List<JalviewModel.PcaViewer.Axis> getAxis()
+    {
+      if (axis == null)
+      {
+        axis = new ArrayList<JalviewModel.PcaViewer.Axis>();
+      }
+      return this.axis;
+    }
+
+    /**
+     * Gets the value of the seqPointMin property.
+     * 
+     * @return possible object is {@link JalviewModel.PcaViewer.SeqPointMin }
+     * 
+     */
+    public JalviewModel.PcaViewer.SeqPointMin getSeqPointMin()
+    {
+      return seqPointMin;
+    }
+
+    /**
+     * Sets the value of the seqPointMin property.
+     * 
+     * @param value
+     *          allowed object is {@link JalviewModel.PcaViewer.SeqPointMin }
+     * 
+     */
+    public void setSeqPointMin(JalviewModel.PcaViewer.SeqPointMin value)
+    {
+      this.seqPointMin = value;
+    }
+
+    /**
+     * Gets the value of the seqPointMax property.
+     * 
+     * @return possible object is {@link JalviewModel.PcaViewer.SeqPointMax }
+     * 
+     */
+    public JalviewModel.PcaViewer.SeqPointMax getSeqPointMax()
+    {
+      return seqPointMax;
+    }
+
+    /**
+     * Sets the value of the seqPointMax property.
+     * 
+     * @param value
+     *          allowed object is {@link JalviewModel.PcaViewer.SeqPointMax }
+     * 
+     */
+    public void setSeqPointMax(JalviewModel.PcaViewer.SeqPointMax value)
+    {
+      this.seqPointMax = value;
+    }
+
+    /**
+     * Gets the value of the pcaData property.
+     * 
+     * @return possible object is {@link PcaDataType }
+     * 
+     */
+    public PcaDataType getPcaData()
+    {
+      return pcaData;
+    }
+
+    /**
+     * Sets the value of the pcaData property.
+     * 
+     * @param value
+     *          allowed object is {@link PcaDataType }
+     * 
+     */
+    public void setPcaData(PcaDataType value)
+    {
+      this.pcaData = value;
+    }
+
+    /**
+     * Gets the value of the title property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getTitle()
+    {
+      return title;
+    }
+
+    /**
+     * Sets the value of the title property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setTitle(String value)
+    {
+      this.title = value;
+    }
+
+    /**
+     * Gets the value of the scoreModelName property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getScoreModelName()
+    {
+      return scoreModelName;
+    }
+
+    /**
+     * Sets the value of the scoreModelName property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setScoreModelName(String value)
+    {
+      this.scoreModelName = value;
+    }
+
+    /**
+     * Gets the value of the xDim property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getXDim()
+    {
+      return xDim;
+    }
+
+    /**
+     * Sets the value of the xDim property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setXDim(Integer value)
+    {
+      this.xDim = value;
     }
 
+    /**
+     * Gets the value of the yDim property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getYDim()
+    {
+      return yDim;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Sets the value of the yDim property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @param value
+     *          allowed object is {@link Integer }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="features" type="{www.jalview.org}feature" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="pdbids" maxOccurs="unbounded" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;extension base="{www.jalview.org}pdbentry">
-     *                 &lt;sequence>
-     *                   &lt;element name="structureState" maxOccurs="unbounded" minOccurs="0">
-     *                     &lt;complexType>
-     *                       &lt;simpleContent>
-     *                         &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
-     *                           &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-     *                           &lt;attribute name="visible" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *                           &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                           &lt;attribute name="alignwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *                           &lt;attribute name="colourwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *                           &lt;attribute name="colourByJmol" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *                           &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                         &lt;/extension>
-     *                       &lt;/simpleContent>
-     *                     &lt;/complexType>
-     *                   &lt;/element>
-     *                 &lt;/sequence>
-     *               &lt;/extension>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="hiddenSequences" type="{http://www.w3.org/2001/XMLSchema}int" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="rnaViewer" maxOccurs="unbounded" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;sequence>
-     *                   &lt;element name="secondaryStructure" maxOccurs="unbounded">
-     *                     &lt;complexType>
-     *                       &lt;complexContent>
-     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                           &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                           &lt;attribute name="annotationId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                           &lt;attribute name="gapped" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *                           &lt;attribute name="viewerState" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                         &lt;/restriction>
-     *                       &lt;/complexContent>
-     *                     &lt;/complexType>
-     *                   &lt;/element>
-     *                 &lt;/sequence>
-     *                 &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-     *                 &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="dividerLocation" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *                 &lt;attribute name="selectedRna" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *       &lt;/sequence>
-     *       &lt;attribute name="colour" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="start" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="hidden" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="viewreference" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public void setYDim(Integer value)
+    {
+      this.yDim = value;
+    }
+
+    /**
+     * Gets the value of the zDim property.
      * 
+     * @return possible object is {@link Integer }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "features",
-        "pdbids",
-        "hiddenSequences",
-        "rnaViewer"
-    })
-    public static class JSeq {
-
-        @XmlElement(namespace = "www.jalview.org")
-        protected List<Feature> features;
-        @XmlElement(namespace = "www.jalview.org")
-        protected List<JalviewModel.JSeq.Pdbids> pdbids;
-        @XmlElement(namespace = "www.jalview.org", type = Integer.class)
-        protected List<Integer> hiddenSequences;
-        @XmlElement(namespace = "www.jalview.org")
-        protected List<JalviewModel.JSeq.RnaViewer> rnaViewer;
-        @XmlAttribute(name = "colour")
-        protected Integer colour;
-        @XmlAttribute(name = "start", required = true)
-        protected int start;
-        @XmlAttribute(name = "end", required = true)
-        protected int end;
-        @XmlAttribute(name = "id", required = true)
-        protected String id;
-        @XmlAttribute(name = "hidden")
-        protected Boolean hidden;
-        @XmlAttribute(name = "viewreference")
-        protected Boolean viewreference;
+    public Integer getZDim()
+    {
+      return zDim;
+    }
 
-        /**
-         * Gets the value of the features property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the features property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getFeatures().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link Feature }
-         * 
-         * 
-         */
-        public List<Feature> getFeatures() {
-            if (features == null) {
-                features = new ArrayList<Feature>();
-            }
-            return this.features;
-        }
+    /**
+     * Sets the value of the zDim property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setZDim(Integer value)
+    {
+      this.zDim = value;
+    }
 
-        /**
-         * Gets the value of the pdbids property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the pdbids property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getPdbids().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link JalviewModel.JSeq.Pdbids }
-         * 
-         * 
-         */
-        public List<JalviewModel.JSeq.Pdbids> getPdbids() {
-            if (pdbids == null) {
-                pdbids = new ArrayList<JalviewModel.JSeq.Pdbids>();
-            }
-            return this.pdbids;
-        }
+    /**
+     * Gets the value of the bgColour property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getBgColour()
+    {
+      return bgColour;
+    }
 
-        /**
-         * Gets the value of the hiddenSequences property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the hiddenSequences property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getHiddenSequences().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link Integer }
-         * 
-         * 
-         */
-        public List<Integer> getHiddenSequences() {
-            if (hiddenSequences == null) {
-                hiddenSequences = new ArrayList<Integer>();
-            }
-            return this.hiddenSequences;
-        }
+    /**
+     * Sets the value of the bgColour property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setBgColour(Integer value)
+    {
+      this.bgColour = value;
+    }
 
-        /**
-         * Gets the value of the rnaViewer property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the rnaViewer property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getRnaViewer().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link JalviewModel.JSeq.RnaViewer }
-         * 
-         * 
-         */
-        public List<JalviewModel.JSeq.RnaViewer> getRnaViewer() {
-            if (rnaViewer == null) {
-                rnaViewer = new ArrayList<JalviewModel.JSeq.RnaViewer>();
-            }
-            return this.rnaViewer;
-        }
+    /**
+     * Gets the value of the scaleFactor property.
+     * 
+     * @return possible object is {@link Float }
+     * 
+     */
+    public Float getScaleFactor()
+    {
+      return scaleFactor;
+    }
 
-        /**
-         * Gets the value of the colour property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getColour() {
-            return colour;
-        }
+    /**
+     * Sets the value of the scaleFactor property.
+     * 
+     * @param value
+     *          allowed object is {@link Float }
+     * 
+     */
+    public void setScaleFactor(Float value)
+    {
+      this.scaleFactor = value;
+    }
 
-        /**
-         * Sets the value of the colour property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setColour(Integer value) {
-            this.colour = value;
-        }
+    /**
+     * Gets the value of the showLabels property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowLabels()
+    {
+      return showLabels;
+    }
 
-        /**
-         * Gets the value of the start property.
-         * 
-         */
-        public int getStart() {
-            return start;
-        }
+    /**
+     * Sets the value of the showLabels property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowLabels(Boolean value)
+    {
+      this.showLabels = value;
+    }
 
-        /**
-         * Sets the value of the start property.
-         * 
-         */
-        public void setStart(int value) {
-            this.start = value;
-        }
+    /**
+     * Gets the value of the linkToAllViews property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isLinkToAllViews()
+    {
+      return linkToAllViews;
+    }
 
-        /**
-         * Gets the value of the end property.
-         * 
-         */
-        public int getEnd() {
-            return end;
-        }
+    /**
+     * Sets the value of the linkToAllViews property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setLinkToAllViews(Boolean value)
+    {
+      this.linkToAllViews = value;
+    }
 
-        /**
-         * Sets the value of the end property.
-         * 
-         */
-        public void setEnd(int value) {
-            this.end = value;
-        }
+    /**
+     * Gets the value of the includeGaps property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isIncludeGaps()
+    {
+      return includeGaps;
+    }
 
-        /**
-         * Gets the value of the id property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getId() {
-            return id;
-        }
+    /**
+     * Sets the value of the includeGaps property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setIncludeGaps(Boolean value)
+    {
+      this.includeGaps = value;
+    }
 
-        /**
-         * Sets the value of the id property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setId(String value) {
-            this.id = value;
-        }
+    /**
+     * Gets the value of the matchGaps property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isMatchGaps()
+    {
+      return matchGaps;
+    }
 
-        /**
-         * Gets the value of the hidden property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isHidden() {
-            return hidden;
-        }
+    /**
+     * Sets the value of the matchGaps property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setMatchGaps(Boolean value)
+    {
+      this.matchGaps = value;
+    }
 
-        /**
-         * Sets the value of the hidden property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setHidden(Boolean value) {
-            this.hidden = value;
-        }
+    /**
+     * Gets the value of the includeGappedColumns property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isIncludeGappedColumns()
+    {
+      return includeGappedColumns;
+    }
 
-        /**
-         * Gets the value of the viewreference property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isViewreference() {
-            return viewreference;
-        }
+    /**
+     * Sets the value of the includeGappedColumns property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setIncludeGappedColumns(Boolean value)
+    {
+      this.includeGappedColumns = value;
+    }
 
-        /**
-         * Sets the value of the viewreference property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setViewreference(Boolean value) {
-            this.viewreference = value;
-        }
+    /**
+     * Gets the value of the denominateByShortestLength property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isDenominateByShortestLength()
+    {
+      return denominateByShortestLength;
+    }
 
+    /**
+     * Sets the value of the denominateByShortestLength property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setDenominateByShortestLength(Boolean value)
+    {
+      this.denominateByShortestLength = value;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;extension base="{www.jalview.org}pdbentry">
-         *       &lt;sequence>
-         *         &lt;element name="structureState" maxOccurs="unbounded" minOccurs="0">
-         *           &lt;complexType>
-         *             &lt;simpleContent>
-         *               &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
-         *                 &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-         *                 &lt;attribute name="visible" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-         *                 &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *                 &lt;attribute name="alignwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-         *                 &lt;attribute name="colourwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-         *                 &lt;attribute name="colourByJmol" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-         *                 &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *               &lt;/extension>
-         *             &lt;/simpleContent>
-         *           &lt;/complexType>
-         *         &lt;/element>
-         *       &lt;/sequence>
-         *     &lt;/extension>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "", propOrder = {
-            "structureState"
-        })
-        public static class Pdbids
-            extends Pdbentry
-        {
+    /**
+     * Gets the value of the width property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getWidth()
+    {
+      return width;
+    }
 
-            @XmlElement(namespace = "www.jalview.org")
-            protected List<JalviewModel.JSeq.Pdbids.StructureState> structureState;
-
-            /**
-             * Gets the value of the structureState property.
-             * 
-             * <p>
-             * This accessor method returns a reference to the live list,
-             * not a snapshot. Therefore any modification you make to the
-             * returned list will be present inside the JAXB object.
-             * This is why there is not a <CODE>set</CODE> method for the structureState property.
-             * 
-             * <p>
-             * For example, to add a new item, do as follows:
-             * <pre>
-             *    getStructureState().add(newItem);
-             * </pre>
-             * 
-             * 
-             * <p>
-             * Objects of the following type(s) are allowed in the list
-             * {@link JalviewModel.JSeq.Pdbids.StructureState }
-             * 
-             * 
-             */
-            public List<JalviewModel.JSeq.Pdbids.StructureState> getStructureState() {
-                if (structureState == null) {
-                    structureState = new ArrayList<JalviewModel.JSeq.Pdbids.StructureState>();
-                }
-                return this.structureState;
-            }
-
-
-            /**
-             * <p>Java class for anonymous complex type.
-             * 
-             * <p>The following schema fragment specifies the expected content contained within this class.
-             * 
-             * <pre>
-             * &lt;complexType>
-             *   &lt;simpleContent>
-             *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
-             *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-             *       &lt;attribute name="visible" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-             *       &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *       &lt;attribute name="alignwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-             *       &lt;attribute name="colourwithAlignPanel" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-             *       &lt;attribute name="colourByJmol" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-             *       &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *     &lt;/extension>
-             *   &lt;/simpleContent>
-             * &lt;/complexType>
-             * </pre>
-             * 
-             * 
-             */
-            @XmlAccessorType(XmlAccessType.FIELD)
-            @XmlType(name = "", propOrder = {
-                "value"
-            })
-            public static class StructureState {
-
-                @XmlValue
-                protected String value;
-                @XmlAttribute(name = "visible")
-                protected Boolean visible;
-                @XmlAttribute(name = "viewId")
-                protected String viewId;
-                @XmlAttribute(name = "alignwithAlignPanel")
-                protected Boolean alignwithAlignPanel;
-                @XmlAttribute(name = "colourwithAlignPanel")
-                protected Boolean colourwithAlignPanel;
-                @XmlAttribute(name = "colourByJmol")
-                protected Boolean colourByJmol;
-                @XmlAttribute(name = "type")
-                protected String type;
-                @XmlAttribute(name = "width")
-                protected Integer width;
-                @XmlAttribute(name = "height")
-                protected Integer height;
-                @XmlAttribute(name = "xpos")
-                protected Integer xpos;
-                @XmlAttribute(name = "ypos")
-                protected Integer ypos;
-
-                /**
-                 * Gets the value of the value property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link String }
-                 *     
-                 */
-                public String getValue() {
-                    return value;
-                }
-
-                /**
-                 * Sets the value of the value property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link String }
-                 *     
-                 */
-                public void setValue(String value) {
-                    this.value = value;
-                }
-
-                /**
-                 * Gets the value of the visible property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public Boolean isVisible() {
-                    return visible;
-                }
-
-                /**
-                 * Sets the value of the visible property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public void setVisible(Boolean value) {
-                    this.visible = value;
-                }
-
-                /**
-                 * Gets the value of the viewId property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link String }
-                 *     
-                 */
-                public String getViewId() {
-                    return viewId;
-                }
-
-                /**
-                 * Sets the value of the viewId property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link String }
-                 *     
-                 */
-                public void setViewId(String value) {
-                    this.viewId = value;
-                }
-
-                /**
-                 * Gets the value of the alignwithAlignPanel property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public boolean isAlignwithAlignPanel() {
-                    if (alignwithAlignPanel == null) {
-                        return true;
-                    } else {
-                        return alignwithAlignPanel;
-                    }
-                }
-
-                /**
-                 * Sets the value of the alignwithAlignPanel property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public void setAlignwithAlignPanel(Boolean value) {
-                    this.alignwithAlignPanel = value;
-                }
-
-                /**
-                 * Gets the value of the colourwithAlignPanel property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public boolean isColourwithAlignPanel() {
-                    if (colourwithAlignPanel == null) {
-                        return false;
-                    } else {
-                        return colourwithAlignPanel;
-                    }
-                }
-
-                /**
-                 * Sets the value of the colourwithAlignPanel property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public void setColourwithAlignPanel(Boolean value) {
-                    this.colourwithAlignPanel = value;
-                }
-
-                /**
-                 * Gets the value of the colourByJmol property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public boolean isColourByJmol() {
-                    if (colourByJmol == null) {
-                        return true;
-                    } else {
-                        return colourByJmol;
-                    }
-                }
-
-                /**
-                 * Sets the value of the colourByJmol property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public void setColourByJmol(Boolean value) {
-                    this.colourByJmol = value;
-                }
-
-                /**
-                 * Gets the value of the type property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link String }
-                 *     
-                 */
-                public String getType() {
-                    return type;
-                }
-
-                /**
-                 * Sets the value of the type property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link String }
-                 *     
-                 */
-                public void setType(String value) {
-                    this.type = value;
-                }
-
-                /**
-                 * Gets the value of the width property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Integer }
-                 *     
-                 */
-                public Integer getWidth() {
-                    return width;
-                }
-
-                /**
-                 * Sets the value of the width property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Integer }
-                 *     
-                 */
-                public void setWidth(Integer value) {
-                    this.width = value;
-                }
-
-                /**
-                 * Gets the value of the height property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Integer }
-                 *     
-                 */
-                public Integer getHeight() {
-                    return height;
-                }
-
-                /**
-                 * Sets the value of the height property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Integer }
-                 *     
-                 */
-                public void setHeight(Integer value) {
-                    this.height = value;
-                }
-
-                /**
-                 * Gets the value of the xpos property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Integer }
-                 *     
-                 */
-                public Integer getXpos() {
-                    return xpos;
-                }
-
-                /**
-                 * Sets the value of the xpos property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Integer }
-                 *     
-                 */
-                public void setXpos(Integer value) {
-                    this.xpos = value;
-                }
-
-                /**
-                 * Gets the value of the ypos property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Integer }
-                 *     
-                 */
-                public Integer getYpos() {
-                    return ypos;
-                }
-
-                /**
-                 * Sets the value of the ypos property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Integer }
-                 *     
-                 */
-                public void setYpos(Integer value) {
-                    this.ypos = value;
-                }
-
-            }
+    /**
+     * Sets the value of the width property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setWidth(Integer value)
+    {
+      this.width = value;
+    }
 
-        }
+    /**
+     * Gets the value of the height property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getHeight()
+    {
+      return height;
+    }
 
+    /**
+     * Sets the value of the height property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setHeight(Integer value)
+    {
+      this.height = value;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;sequence>
-         *         &lt;element name="secondaryStructure" maxOccurs="unbounded">
-         *           &lt;complexType>
-         *             &lt;complexContent>
-         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *                 &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *                 &lt;attribute name="annotationId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *                 &lt;attribute name="gapped" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-         *                 &lt;attribute name="viewerState" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *               &lt;/restriction>
-         *             &lt;/complexContent>
-         *           &lt;/complexType>
-         *         &lt;/element>
-         *       &lt;/sequence>
-         *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-         *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="viewId" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="dividerLocation" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *       &lt;attribute name="selectedRna" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "", propOrder = {
-            "secondaryStructure"
-        })
-        public static class RnaViewer {
-
-            @XmlElement(namespace = "www.jalview.org", required = true)
-            protected List<JalviewModel.JSeq.RnaViewer.SecondaryStructure> secondaryStructure;
-            @XmlAttribute(name = "title")
-            protected String title;
-            @XmlAttribute(name = "viewId")
-            protected String viewId;
-            @XmlAttribute(name = "dividerLocation")
-            protected Integer dividerLocation;
-            @XmlAttribute(name = "selectedRna")
-            protected Integer selectedRna;
-            @XmlAttribute(name = "width")
-            protected Integer width;
-            @XmlAttribute(name = "height")
-            protected Integer height;
-            @XmlAttribute(name = "xpos")
-            protected Integer xpos;
-            @XmlAttribute(name = "ypos")
-            protected Integer ypos;
-
-            /**
-             * Gets the value of the secondaryStructure property.
-             * 
-             * <p>
-             * This accessor method returns a reference to the live list,
-             * not a snapshot. Therefore any modification you make to the
-             * returned list will be present inside the JAXB object.
-             * This is why there is not a <CODE>set</CODE> method for the secondaryStructure property.
-             * 
-             * <p>
-             * For example, to add a new item, do as follows:
-             * <pre>
-             *    getSecondaryStructure().add(newItem);
-             * </pre>
-             * 
-             * 
-             * <p>
-             * Objects of the following type(s) are allowed in the list
-             * {@link JalviewModel.JSeq.RnaViewer.SecondaryStructure }
-             * 
-             * 
-             */
-            public List<JalviewModel.JSeq.RnaViewer.SecondaryStructure> getSecondaryStructure() {
-                if (secondaryStructure == null) {
-                    secondaryStructure = new ArrayList<JalviewModel.JSeq.RnaViewer.SecondaryStructure>();
-                }
-                return this.secondaryStructure;
-            }
-
-            /**
-             * Gets the value of the title property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getTitle() {
-                return title;
-            }
-
-            /**
-             * Sets the value of the title property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setTitle(String value) {
-                this.title = value;
-            }
-
-            /**
-             * Gets the value of the viewId property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getViewId() {
-                return viewId;
-            }
-
-            /**
-             * Sets the value of the viewId property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setViewId(String value) {
-                this.viewId = value;
-            }
-
-            /**
-             * Gets the value of the dividerLocation property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getDividerLocation() {
-                return dividerLocation;
-            }
-
-            /**
-             * Sets the value of the dividerLocation property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setDividerLocation(Integer value) {
-                this.dividerLocation = value;
-            }
-
-            /**
-             * Gets the value of the selectedRna property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getSelectedRna() {
-                return selectedRna;
-            }
-
-            /**
-             * Sets the value of the selectedRna property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setSelectedRna(Integer value) {
-                this.selectedRna = value;
-            }
-
-            /**
-             * Gets the value of the width property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getWidth() {
-                return width;
-            }
-
-            /**
-             * Sets the value of the width property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setWidth(Integer value) {
-                this.width = value;
-            }
-
-            /**
-             * Gets the value of the height property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getHeight() {
-                return height;
-            }
-
-            /**
-             * Sets the value of the height property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setHeight(Integer value) {
-                this.height = value;
-            }
-
-            /**
-             * Gets the value of the xpos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getXpos() {
-                return xpos;
-            }
-
-            /**
-             * Sets the value of the xpos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setXpos(Integer value) {
-                this.xpos = value;
-            }
-
-            /**
-             * Gets the value of the ypos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getYpos() {
-                return ypos;
-            }
-
-            /**
-             * Sets the value of the ypos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setYpos(Integer value) {
-                this.ypos = value;
-            }
-
-
-            /**
-             * <p>Java class for anonymous complex type.
-             * 
-             * <p>The following schema fragment specifies the expected content contained within this class.
-             * 
-             * <pre>
-             * &lt;complexType>
-             *   &lt;complexContent>
-             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-             *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *       &lt;attribute name="annotationId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *       &lt;attribute name="gapped" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-             *       &lt;attribute name="viewerState" type="{http://www.w3.org/2001/XMLSchema}string" />
-             *     &lt;/restriction>
-             *   &lt;/complexContent>
-             * &lt;/complexType>
-             * </pre>
-             * 
-             * 
-             */
-            @XmlAccessorType(XmlAccessType.FIELD)
-            @XmlType(name = "")
-            public static class SecondaryStructure {
-
-                @XmlAttribute(name = "title")
-                protected String title;
-                @XmlAttribute(name = "annotationId", required = true)
-                protected String annotationId;
-                @XmlAttribute(name = "gapped")
-                protected Boolean gapped;
-                @XmlAttribute(name = "viewerState")
-                protected String viewerState;
-
-                /**
-                 * Gets the value of the title property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link String }
-                 *     
-                 */
-                public String getTitle() {
-                    return title;
-                }
-
-                /**
-                 * Sets the value of the title property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link String }
-                 *     
-                 */
-                public void setTitle(String value) {
-                    this.title = value;
-                }
-
-                /**
-                 * Gets the value of the annotationId property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link String }
-                 *     
-                 */
-                public String getAnnotationId() {
-                    return annotationId;
-                }
-
-                /**
-                 * Sets the value of the annotationId property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link String }
-                 *     
-                 */
-                public void setAnnotationId(String value) {
-                    this.annotationId = value;
-                }
-
-                /**
-                 * Gets the value of the gapped property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public Boolean isGapped() {
-                    return gapped;
-                }
-
-                /**
-                 * Sets the value of the gapped property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link Boolean }
-                 *     
-                 */
-                public void setGapped(Boolean value) {
-                    this.gapped = value;
-                }
-
-                /**
-                 * Gets the value of the viewerState property.
-                 * 
-                 * @return
-                 *     possible object is
-                 *     {@link String }
-                 *     
-                 */
-                public String getViewerState() {
-                    return viewerState;
-                }
-
-                /**
-                 * Sets the value of the viewerState property.
-                 * 
-                 * @param value
-                 *     allowed object is
-                 *     {@link String }
-                 *     
-                 */
-                public void setViewerState(String value) {
-                    this.viewerState = value;
-                }
-
-            }
+    /**
+     * Gets the value of the xpos property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getXpos()
+    {
+      return xpos;
+    }
 
-        }
+    /**
+     * Sets the value of the xpos property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setXpos(Integer value)
+    {
+      this.xpos = value;
+    }
 
+    /**
+     * Gets the value of the ypos property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getYpos()
+    {
+      return ypos;
     }
 
+    /**
+     * Sets the value of the ypos property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setYpos(Integer value)
+    {
+      this.ypos = value;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * <p>
+     * Java class for anonymous complex type.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
      * 
      * <pre>
      * &lt;complexType>
      *   &lt;complexContent>
      *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="sequencePoint" maxOccurs="unbounded">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attGroup ref="{www.jalview.org}position"/>
-     *                 &lt;attribute name="sequenceRef" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="axis" maxOccurs="3" minOccurs="3">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attGroup ref="{www.jalview.org}position"/>
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="seqPointMin">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attGroup ref="{www.jalview.org}position"/>
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="seqPointMax">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attGroup ref="{www.jalview.org}position"/>
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="pcaData" type="{www.jalview.org}PcaDataType"/>
-     *       &lt;/sequence>
-     *       &lt;attGroup ref="{www.jalview.org}SimilarityParams"/>
-     *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-     *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="scoreModelName" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="xDim" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="yDim" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="zDim" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="bgColour" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="scaleFactor" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *       &lt;attribute name="showLabels" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="linkToAllViews" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *       &lt;attGroup ref="{www.jalview.org}position"/>
      *     &lt;/restriction>
      *   &lt;/complexContent>
      * &lt;/complexType>
@@ -3145,3670 +3859,3130 @@ public class JalviewModel {
      * 
      */
     @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "sequencePoint",
-        "axis",
-        "seqPointMin",
-        "seqPointMax",
-        "pcaData"
-    })
-    public static class PcaViewer {
-
-        @XmlElement(namespace = "www.jalview.org", required = true)
-        protected List<JalviewModel.PcaViewer.SequencePoint> sequencePoint;
-        @XmlElement(namespace = "www.jalview.org", required = true)
-        protected List<JalviewModel.PcaViewer.Axis> axis;
-        @XmlElement(namespace = "www.jalview.org", required = true)
-        protected JalviewModel.PcaViewer.SeqPointMin seqPointMin;
-        @XmlElement(namespace = "www.jalview.org", required = true)
-        protected JalviewModel.PcaViewer.SeqPointMax seqPointMax;
-        @XmlElement(namespace = "www.jalview.org", required = true)
-        protected PcaDataType pcaData;
-        @XmlAttribute(name = "title")
-        protected String title;
-        @XmlAttribute(name = "scoreModelName")
-        protected String scoreModelName;
-        @XmlAttribute(name = "xDim")
-        protected Integer xDim;
-        @XmlAttribute(name = "yDim")
-        protected Integer yDim;
-        @XmlAttribute(name = "zDim")
-        protected Integer zDim;
-        @XmlAttribute(name = "bgColour")
-        protected Integer bgColour;
-        @XmlAttribute(name = "scaleFactor")
-        protected Float scaleFactor;
-        @XmlAttribute(name = "showLabels")
-        protected Boolean showLabels;
-        @XmlAttribute(name = "linkToAllViews")
-        protected Boolean linkToAllViews;
-        @XmlAttribute(name = "includeGaps")
-        protected Boolean includeGaps;
-        @XmlAttribute(name = "matchGaps")
-        protected Boolean matchGaps;
-        @XmlAttribute(name = "includeGappedColumns")
-        protected Boolean includeGappedColumns;
-        @XmlAttribute(name = "denominateByShortestLength")
-        protected Boolean denominateByShortestLength;
-        @XmlAttribute(name = "width")
-        protected Integer width;
-        @XmlAttribute(name = "height")
-        protected Integer height;
-        @XmlAttribute(name = "xpos")
-        protected Integer xpos;
-        @XmlAttribute(name = "ypos")
-        protected Integer ypos;
-
-        /**
-         * Gets the value of the sequencePoint property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the sequencePoint property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getSequencePoint().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link JalviewModel.PcaViewer.SequencePoint }
-         * 
-         * 
-         */
-        public List<JalviewModel.PcaViewer.SequencePoint> getSequencePoint() {
-            if (sequencePoint == null) {
-                sequencePoint = new ArrayList<JalviewModel.PcaViewer.SequencePoint>();
-            }
-            return this.sequencePoint;
-        }
-
-        /**
-         * Gets the value of the axis property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the axis property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getAxis().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link JalviewModel.PcaViewer.Axis }
-         * 
-         * 
-         */
-        public List<JalviewModel.PcaViewer.Axis> getAxis() {
-            if (axis == null) {
-                axis = new ArrayList<JalviewModel.PcaViewer.Axis>();
-            }
-            return this.axis;
-        }
-
-        /**
-         * Gets the value of the seqPointMin property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link JalviewModel.PcaViewer.SeqPointMin }
-         *     
-         */
-        public JalviewModel.PcaViewer.SeqPointMin getSeqPointMin() {
-            return seqPointMin;
-        }
-
-        /**
-         * Sets the value of the seqPointMin property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link JalviewModel.PcaViewer.SeqPointMin }
-         *     
-         */
-        public void setSeqPointMin(JalviewModel.PcaViewer.SeqPointMin value) {
-            this.seqPointMin = value;
-        }
-
-        /**
-         * Gets the value of the seqPointMax property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link JalviewModel.PcaViewer.SeqPointMax }
-         *     
-         */
-        public JalviewModel.PcaViewer.SeqPointMax getSeqPointMax() {
-            return seqPointMax;
-        }
-
-        /**
-         * Sets the value of the seqPointMax property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link JalviewModel.PcaViewer.SeqPointMax }
-         *     
-         */
-        public void setSeqPointMax(JalviewModel.PcaViewer.SeqPointMax value) {
-            this.seqPointMax = value;
-        }
-
-        /**
-         * Gets the value of the pcaData property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link PcaDataType }
-         *     
-         */
-        public PcaDataType getPcaData() {
-            return pcaData;
-        }
-
-        /**
-         * Sets the value of the pcaData property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link PcaDataType }
-         *     
-         */
-        public void setPcaData(PcaDataType value) {
-            this.pcaData = value;
-        }
-
-        /**
-         * Gets the value of the title property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getTitle() {
-            return title;
-        }
-
-        /**
-         * Sets the value of the title property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setTitle(String value) {
-            this.title = value;
-        }
-
-        /**
-         * Gets the value of the scoreModelName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getScoreModelName() {
-            return scoreModelName;
-        }
-
-        /**
-         * Sets the value of the scoreModelName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setScoreModelName(String value) {
-            this.scoreModelName = value;
-        }
-
-        /**
-         * Gets the value of the xDim property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getXDim() {
-            return xDim;
-        }
-
-        /**
-         * Sets the value of the xDim property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setXDim(Integer value) {
-            this.xDim = value;
-        }
-
-        /**
-         * Gets the value of the yDim property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getYDim() {
-            return yDim;
-        }
+    @XmlType(name = "")
+    public static class Axis
+    {
+
+      @XmlAttribute(name = "xPos")
+      protected Float xPos;
+
+      @XmlAttribute(name = "yPos")
+      protected Float yPos;
+
+      @XmlAttribute(name = "zPos")
+      protected Float zPos;
+
+      /**
+       * Gets the value of the xPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getXPos()
+      {
+        return xPos;
+      }
+
+      /**
+       * Sets the value of the xPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setXPos(Float value)
+      {
+        this.xPos = value;
+      }
+
+      /**
+       * Gets the value of the yPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getYPos()
+      {
+        return yPos;
+      }
+
+      /**
+       * Sets the value of the yPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setYPos(Float value)
+      {
+        this.yPos = value;
+      }
+
+      /**
+       * Gets the value of the zPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getZPos()
+      {
+        return zPos;
+      }
+
+      /**
+       * Sets the value of the zPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setZPos(Float value)
+      {
+        this.zPos = value;
+      }
 
-        /**
-         * Sets the value of the yDim property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setYDim(Integer value) {
-            this.yDim = value;
-        }
+    }
 
-        /**
-         * Gets the value of the zDim property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getZDim() {
-            return zDim;
-        }
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attGroup ref="{www.jalview.org}position"/>
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class SeqPointMax
+    {
+
+      @XmlAttribute(name = "xPos")
+      protected Float xPos;
+
+      @XmlAttribute(name = "yPos")
+      protected Float yPos;
+
+      @XmlAttribute(name = "zPos")
+      protected Float zPos;
+
+      /**
+       * Gets the value of the xPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getXPos()
+      {
+        return xPos;
+      }
+
+      /**
+       * Sets the value of the xPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setXPos(Float value)
+      {
+        this.xPos = value;
+      }
+
+      /**
+       * Gets the value of the yPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getYPos()
+      {
+        return yPos;
+      }
+
+      /**
+       * Sets the value of the yPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setYPos(Float value)
+      {
+        this.yPos = value;
+      }
+
+      /**
+       * Gets the value of the zPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getZPos()
+      {
+        return zPos;
+      }
+
+      /**
+       * Sets the value of the zPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setZPos(Float value)
+      {
+        this.zPos = value;
+      }
 
-        /**
-         * Sets the value of the zDim property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setZDim(Integer value) {
-            this.zDim = value;
-        }
+    }
 
-        /**
-         * Gets the value of the bgColour property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getBgColour() {
-            return bgColour;
-        }
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attGroup ref="{www.jalview.org}position"/>
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class SeqPointMin
+    {
+
+      @XmlAttribute(name = "xPos")
+      protected Float xPos;
+
+      @XmlAttribute(name = "yPos")
+      protected Float yPos;
+
+      @XmlAttribute(name = "zPos")
+      protected Float zPos;
+
+      /**
+       * Gets the value of the xPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getXPos()
+      {
+        return xPos;
+      }
+
+      /**
+       * Sets the value of the xPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setXPos(Float value)
+      {
+        this.xPos = value;
+      }
+
+      /**
+       * Gets the value of the yPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getYPos()
+      {
+        return yPos;
+      }
+
+      /**
+       * Sets the value of the yPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setYPos(Float value)
+      {
+        this.yPos = value;
+      }
+
+      /**
+       * Gets the value of the zPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getZPos()
+      {
+        return zPos;
+      }
+
+      /**
+       * Sets the value of the zPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setZPos(Float value)
+      {
+        this.zPos = value;
+      }
 
-        /**
-         * Sets the value of the bgColour property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setBgColour(Integer value) {
-            this.bgColour = value;
-        }
+    }
 
-        /**
-         * Gets the value of the scaleFactor property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Float }
-         *     
-         */
-        public Float getScaleFactor() {
-            return scaleFactor;
-        }
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attGroup ref="{www.jalview.org}position"/>
+     *       &lt;attribute name="sequenceRef" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class SequencePoint
+    {
+
+      @XmlAttribute(name = "sequenceRef")
+      protected String sequenceRef;
+
+      @XmlAttribute(name = "xPos")
+      protected Float xPos;
+
+      @XmlAttribute(name = "yPos")
+      protected Float yPos;
+
+      @XmlAttribute(name = "zPos")
+      protected Float zPos;
+
+      /**
+       * Gets the value of the sequenceRef property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getSequenceRef()
+      {
+        return sequenceRef;
+      }
+
+      /**
+       * Sets the value of the sequenceRef property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setSequenceRef(String value)
+      {
+        this.sequenceRef = value;
+      }
+
+      /**
+       * Gets the value of the xPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getXPos()
+      {
+        return xPos;
+      }
+
+      /**
+       * Sets the value of the xPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setXPos(Float value)
+      {
+        this.xPos = value;
+      }
+
+      /**
+       * Gets the value of the yPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getYPos()
+      {
+        return yPos;
+      }
+
+      /**
+       * Sets the value of the yPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setYPos(Float value)
+      {
+        this.yPos = value;
+      }
+
+      /**
+       * Gets the value of the zPos property.
+       * 
+       * @return possible object is {@link Float }
+       * 
+       */
+      public Float getZPos()
+      {
+        return zPos;
+      }
+
+      /**
+       * Sets the value of the zPos property.
+       * 
+       * @param value
+       *          allowed object is {@link Float }
+       * 
+       */
+      public void setZPos(Float value)
+      {
+        this.zPos = value;
+      }
 
-        /**
-         * Sets the value of the scaleFactor property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Float }
-         *     
-         */
-        public void setScaleFactor(Float value) {
-            this.scaleFactor = value;
-        }
+    }
 
-        /**
-         * Gets the value of the showLabels property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowLabels() {
-            return showLabels;
-        }
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence minOccurs="0">
+   *         &lt;element name="title" type="{http://www.w3.org/2001/XMLSchema}string"/>
+   *         &lt;element name="newick" type="{http://www.w3.org/2001/XMLSchema}string"/>
+   *       &lt;/sequence>
+   *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+   *       &lt;attribute name="fontName" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="fontSize" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="fontStyle" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="threshold" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *       &lt;attribute name="showBootstrap" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="showDistances" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="markUnlinked" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="fitToWindow" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="currentTree" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="columnWise" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="columnReference" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+   *       &lt;attribute name="linkToAllViews" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "title", "newick" })
+  public static class Tree
+  {
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected String title;
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected String newick;
+
+    @XmlAttribute(name = "fontName")
+    protected String fontName;
+
+    @XmlAttribute(name = "fontSize")
+    protected Integer fontSize;
+
+    @XmlAttribute(name = "fontStyle")
+    protected Integer fontStyle;
+
+    @XmlAttribute(name = "threshold")
+    protected Float threshold;
+
+    @XmlAttribute(name = "showBootstrap")
+    protected Boolean showBootstrap;
+
+    @XmlAttribute(name = "showDistances")
+    protected Boolean showDistances;
+
+    @XmlAttribute(name = "markUnlinked")
+    protected Boolean markUnlinked;
+
+    @XmlAttribute(name = "fitToWindow")
+    protected Boolean fitToWindow;
+
+    @XmlAttribute(name = "currentTree")
+    protected Boolean currentTree;
+
+    @XmlAttribute(name = "columnWise")
+    protected Boolean columnWise;
+
+    @XmlAttribute(name = "columnReference")
+    protected String columnReference;
+
+    @XmlAttribute(name = "id")
+    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+    @XmlID
+    @XmlSchemaType(name = "ID")
+    protected String id;
+
+    @XmlAttribute(name = "linkToAllViews")
+    protected Boolean linkToAllViews;
+
+    @XmlAttribute(name = "width")
+    protected Integer width;
+
+    @XmlAttribute(name = "height")
+    protected Integer height;
+
+    @XmlAttribute(name = "xpos")
+    protected Integer xpos;
+
+    @XmlAttribute(name = "ypos")
+    protected Integer ypos;
 
-        /**
-         * Sets the value of the showLabels property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowLabels(Boolean value) {
-            this.showLabels = value;
-        }
+    /**
+     * Gets the value of the title property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getTitle()
+    {
+      return title;
+    }
 
-        /**
-         * Gets the value of the linkToAllViews property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isLinkToAllViews() {
-            return linkToAllViews;
-        }
+    /**
+     * Sets the value of the title property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setTitle(String value)
+    {
+      this.title = value;
+    }
 
-        /**
-         * Sets the value of the linkToAllViews property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setLinkToAllViews(Boolean value) {
-            this.linkToAllViews = value;
-        }
+    /**
+     * Gets the value of the newick property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getNewick()
+    {
+      return newick;
+    }
 
-        /**
-         * Gets the value of the includeGaps property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isIncludeGaps() {
-            return includeGaps;
-        }
+    /**
+     * Sets the value of the newick property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setNewick(String value)
+    {
+      this.newick = value;
+    }
 
-        /**
-         * Sets the value of the includeGaps property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setIncludeGaps(Boolean value) {
-            this.includeGaps = value;
-        }
+    /**
+     * Gets the value of the fontName property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getFontName()
+    {
+      return fontName;
+    }
 
-        /**
-         * Gets the value of the matchGaps property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isMatchGaps() {
-            return matchGaps;
-        }
+    /**
+     * Sets the value of the fontName property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setFontName(String value)
+    {
+      this.fontName = value;
+    }
 
-        /**
-         * Sets the value of the matchGaps property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setMatchGaps(Boolean value) {
-            this.matchGaps = value;
-        }
+    /**
+     * Gets the value of the fontSize property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getFontSize()
+    {
+      return fontSize;
+    }
 
-        /**
-         * Gets the value of the includeGappedColumns property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isIncludeGappedColumns() {
-            return includeGappedColumns;
-        }
+    /**
+     * Sets the value of the fontSize property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setFontSize(Integer value)
+    {
+      this.fontSize = value;
+    }
 
-        /**
-         * Sets the value of the includeGappedColumns property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setIncludeGappedColumns(Boolean value) {
-            this.includeGappedColumns = value;
-        }
+    /**
+     * Gets the value of the fontStyle property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getFontStyle()
+    {
+      return fontStyle;
+    }
 
-        /**
-         * Gets the value of the denominateByShortestLength property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isDenominateByShortestLength() {
-            return denominateByShortestLength;
-        }
+    /**
+     * Sets the value of the fontStyle property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setFontStyle(Integer value)
+    {
+      this.fontStyle = value;
+    }
 
-        /**
-         * Sets the value of the denominateByShortestLength property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setDenominateByShortestLength(Boolean value) {
-            this.denominateByShortestLength = value;
-        }
+    /**
+     * Gets the value of the threshold property.
+     * 
+     * @return possible object is {@link Float }
+     * 
+     */
+    public Float getThreshold()
+    {
+      return threshold;
+    }
 
-        /**
-         * Gets the value of the width property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getWidth() {
-            return width;
-        }
+    /**
+     * Sets the value of the threshold property.
+     * 
+     * @param value
+     *          allowed object is {@link Float }
+     * 
+     */
+    public void setThreshold(Float value)
+    {
+      this.threshold = value;
+    }
 
-        /**
-         * Sets the value of the width property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setWidth(Integer value) {
-            this.width = value;
-        }
+    /**
+     * Gets the value of the showBootstrap property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowBootstrap()
+    {
+      return showBootstrap;
+    }
 
-        /**
-         * Gets the value of the height property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getHeight() {
-            return height;
-        }
+    /**
+     * Sets the value of the showBootstrap property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowBootstrap(Boolean value)
+    {
+      this.showBootstrap = value;
+    }
 
-        /**
-         * Sets the value of the height property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setHeight(Integer value) {
-            this.height = value;
-        }
+    /**
+     * Gets the value of the showDistances property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowDistances()
+    {
+      return showDistances;
+    }
 
-        /**
-         * Gets the value of the xpos property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getXpos() {
-            return xpos;
-        }
+    /**
+     * Sets the value of the showDistances property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowDistances(Boolean value)
+    {
+      this.showDistances = value;
+    }
 
-        /**
-         * Sets the value of the xpos property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setXpos(Integer value) {
-            this.xpos = value;
-        }
+    /**
+     * Gets the value of the markUnlinked property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isMarkUnlinked()
+    {
+      return markUnlinked;
+    }
 
-        /**
-         * Gets the value of the ypos property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getYpos() {
-            return ypos;
-        }
+    /**
+     * Sets the value of the markUnlinked property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setMarkUnlinked(Boolean value)
+    {
+      this.markUnlinked = value;
+    }
 
-        /**
-         * Sets the value of the ypos property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setYpos(Integer value) {
-            this.ypos = value;
-        }
+    /**
+     * Gets the value of the fitToWindow property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isFitToWindow()
+    {
+      return fitToWindow;
+    }
 
+    /**
+     * Sets the value of the fitToWindow property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setFitToWindow(Boolean value)
+    {
+      this.fitToWindow = value;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attGroup ref="{www.jalview.org}position"/>
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class Axis {
-
-            @XmlAttribute(name = "xPos")
-            protected Float xPos;
-            @XmlAttribute(name = "yPos")
-            protected Float yPos;
-            @XmlAttribute(name = "zPos")
-            protected Float zPos;
-
-            /**
-             * Gets the value of the xPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getXPos() {
-                return xPos;
-            }
-
-            /**
-             * Sets the value of the xPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setXPos(Float value) {
-                this.xPos = value;
-            }
-
-            /**
-             * Gets the value of the yPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getYPos() {
-                return yPos;
-            }
-
-            /**
-             * Sets the value of the yPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setYPos(Float value) {
-                this.yPos = value;
-            }
-
-            /**
-             * Gets the value of the zPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getZPos() {
-                return zPos;
-            }
-
-            /**
-             * Sets the value of the zPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setZPos(Float value) {
-                this.zPos = value;
-            }
+    /**
+     * Gets the value of the currentTree property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isCurrentTree()
+    {
+      return currentTree;
+    }
 
-        }
+    /**
+     * Sets the value of the currentTree property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setCurrentTree(Boolean value)
+    {
+      this.currentTree = value;
+    }
 
+    /**
+     * Gets the value of the columnWise property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isColumnWise()
+    {
+      if (columnWise == null)
+      {
+        return false;
+      }
+      else
+      {
+        return columnWise;
+      }
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attGroup ref="{www.jalview.org}position"/>
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class SeqPointMax {
-
-            @XmlAttribute(name = "xPos")
-            protected Float xPos;
-            @XmlAttribute(name = "yPos")
-            protected Float yPos;
-            @XmlAttribute(name = "zPos")
-            protected Float zPos;
-
-            /**
-             * Gets the value of the xPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getXPos() {
-                return xPos;
-            }
-
-            /**
-             * Sets the value of the xPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setXPos(Float value) {
-                this.xPos = value;
-            }
-
-            /**
-             * Gets the value of the yPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getYPos() {
-                return yPos;
-            }
-
-            /**
-             * Sets the value of the yPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setYPos(Float value) {
-                this.yPos = value;
-            }
-
-            /**
-             * Gets the value of the zPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getZPos() {
-                return zPos;
-            }
-
-            /**
-             * Sets the value of the zPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setZPos(Float value) {
-                this.zPos = value;
-            }
+    /**
+     * Sets the value of the columnWise property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setColumnWise(Boolean value)
+    {
+      this.columnWise = value;
+    }
+
+    /**
+     * Gets the value of the columnReference property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getColumnReference()
+    {
+      return columnReference;
+    }
+
+    /**
+     * Sets the value of the columnReference property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setColumnReference(String value)
+    {
+      this.columnReference = value;
+    }
 
-        }
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getId()
+    {
+      return id;
+    }
 
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setId(String value)
+    {
+      this.id = value;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attGroup ref="{www.jalview.org}position"/>
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class SeqPointMin {
-
-            @XmlAttribute(name = "xPos")
-            protected Float xPos;
-            @XmlAttribute(name = "yPos")
-            protected Float yPos;
-            @XmlAttribute(name = "zPos")
-            protected Float zPos;
-
-            /**
-             * Gets the value of the xPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getXPos() {
-                return xPos;
-            }
-
-            /**
-             * Sets the value of the xPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setXPos(Float value) {
-                this.xPos = value;
-            }
-
-            /**
-             * Gets the value of the yPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getYPos() {
-                return yPos;
-            }
-
-            /**
-             * Sets the value of the yPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setYPos(Float value) {
-                this.yPos = value;
-            }
-
-            /**
-             * Gets the value of the zPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getZPos() {
-                return zPos;
-            }
-
-            /**
-             * Sets the value of the zPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setZPos(Float value) {
-                this.zPos = value;
-            }
+    /**
+     * Gets the value of the linkToAllViews property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isLinkToAllViews()
+    {
+      if (linkToAllViews == null)
+      {
+        return false;
+      }
+      else
+      {
+        return linkToAllViews;
+      }
+    }
 
-        }
+    /**
+     * Sets the value of the linkToAllViews property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setLinkToAllViews(Boolean value)
+    {
+      this.linkToAllViews = value;
+    }
 
+    /**
+     * Gets the value of the width property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getWidth()
+    {
+      return width;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attGroup ref="{www.jalview.org}position"/>
-         *       &lt;attribute name="sequenceRef" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class SequencePoint {
-
-            @XmlAttribute(name = "sequenceRef")
-            protected String sequenceRef;
-            @XmlAttribute(name = "xPos")
-            protected Float xPos;
-            @XmlAttribute(name = "yPos")
-            protected Float yPos;
-            @XmlAttribute(name = "zPos")
-            protected Float zPos;
-
-            /**
-             * Gets the value of the sequenceRef property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getSequenceRef() {
-                return sequenceRef;
-            }
-
-            /**
-             * Sets the value of the sequenceRef property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setSequenceRef(String value) {
-                this.sequenceRef = value;
-            }
-
-            /**
-             * Gets the value of the xPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getXPos() {
-                return xPos;
-            }
-
-            /**
-             * Sets the value of the xPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setXPos(Float value) {
-                this.xPos = value;
-            }
-
-            /**
-             * Gets the value of the yPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getYPos() {
-                return yPos;
-            }
-
-            /**
-             * Sets the value of the yPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setYPos(Float value) {
-                this.yPos = value;
-            }
-
-            /**
-             * Gets the value of the zPos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Float }
-             *     
-             */
-            public Float getZPos() {
-                return zPos;
-            }
-
-            /**
-             * Sets the value of the zPos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Float }
-             *     
-             */
-            public void setZPos(Float value) {
-                this.zPos = value;
-            }
+    /**
+     * Sets the value of the width property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setWidth(Integer value)
+    {
+      this.width = value;
+    }
 
-        }
+    /**
+     * Gets the value of the height property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getHeight()
+    {
+      return height;
+    }
 
+    /**
+     * Sets the value of the height property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setHeight(Integer value)
+    {
+      this.height = value;
     }
 
+    /**
+     * Gets the value of the xpos property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getXpos()
+    {
+      return xpos;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Sets the value of the xpos property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @param value
+     *          allowed object is {@link Integer }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence minOccurs="0">
-     *         &lt;element name="title" type="{http://www.w3.org/2001/XMLSchema}string"/>
-     *         &lt;element name="newick" type="{http://www.w3.org/2001/XMLSchema}string"/>
-     *       &lt;/sequence>
-     *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-     *       &lt;attribute name="fontName" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="fontSize" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="fontStyle" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="threshold" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *       &lt;attribute name="showBootstrap" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="showDistances" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="markUnlinked" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="fitToWindow" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="currentTree" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="columnWise" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="columnReference" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}ID" />
-     *       &lt;attribute name="linkToAllViews" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public void setXpos(Integer value)
+    {
+      this.xpos = value;
+    }
+
+    /**
+     * Gets the value of the ypos property.
      * 
+     * @return possible object is {@link Integer }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "title",
-        "newick"
-    })
-    public static class Tree {
+    public Integer getYpos()
+    {
+      return ypos;
+    }
 
-        @XmlElement(namespace = "www.jalview.org")
-        protected String title;
-        @XmlElement(namespace = "www.jalview.org")
-        protected String newick;
-        @XmlAttribute(name = "fontName")
-        protected String fontName;
-        @XmlAttribute(name = "fontSize")
-        protected Integer fontSize;
-        @XmlAttribute(name = "fontStyle")
-        protected Integer fontStyle;
-        @XmlAttribute(name = "threshold")
-        protected Float threshold;
-        @XmlAttribute(name = "showBootstrap")
-        protected Boolean showBootstrap;
-        @XmlAttribute(name = "showDistances")
-        protected Boolean showDistances;
-        @XmlAttribute(name = "markUnlinked")
-        protected Boolean markUnlinked;
-        @XmlAttribute(name = "fitToWindow")
-        protected Boolean fitToWindow;
-        @XmlAttribute(name = "currentTree")
-        protected Boolean currentTree;
-        @XmlAttribute(name = "columnWise")
-        protected Boolean columnWise;
-        @XmlAttribute(name = "columnReference")
-        protected String columnReference;
-        @XmlAttribute(name = "id")
-        @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
-        @XmlID
-        @XmlSchemaType(name = "ID")
-        protected String id;
-        @XmlAttribute(name = "linkToAllViews")
-        protected Boolean linkToAllViews;
-        @XmlAttribute(name = "width")
-        protected Integer width;
-        @XmlAttribute(name = "height")
-        protected Integer height;
-        @XmlAttribute(name = "xpos")
-        protected Integer xpos;
-        @XmlAttribute(name = "ypos")
-        protected Integer ypos;
+    /**
+     * Sets the value of the ypos property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setYpos(Integer value)
+    {
+      this.ypos = value;
+    }
 
-        /**
-         * Gets the value of the title property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getTitle() {
-            return title;
-        }
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="UserColourScheme" type="{www.jalview.org/colours}JalviewUserColours"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "userColourScheme" })
+  public static class UserColours
+  {
+
+    @XmlElement(
+      name = "UserColourScheme",
+      namespace = "www.jalview.org",
+      required = true)
+    protected JalviewUserColours userColourScheme;
+
+    @XmlAttribute(name = "id")
+    protected String id;
 
-        /**
-         * Sets the value of the title property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setTitle(String value) {
-            this.title = value;
-        }
+    /**
+     * Gets the value of the userColourScheme property.
+     * 
+     * @return possible object is {@link JalviewUserColours }
+     * 
+     */
+    public JalviewUserColours getUserColourScheme()
+    {
+      return userColourScheme;
+    }
 
-        /**
-         * Gets the value of the newick property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getNewick() {
-            return newick;
-        }
+    /**
+     * Sets the value of the userColourScheme property.
+     * 
+     * @param value
+     *          allowed object is {@link JalviewUserColours }
+     * 
+     */
+    public void setUserColourScheme(JalviewUserColours value)
+    {
+      this.userColourScheme = value;
+    }
 
-        /**
-         * Sets the value of the newick property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setNewick(String value) {
-            this.newick = value;
-        }
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getId()
+    {
+      return id;
+    }
 
-        /**
-         * Gets the value of the fontName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getFontName() {
-            return fontName;
-        }
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setId(String value)
+    {
+      this.id = value;
+    }
 
-        /**
-         * Sets the value of the fontName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setFontName(String value) {
-            this.fontName = value;
-        }
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="AnnotationColours" type="{www.jalview.org}AnnotationColourScheme" minOccurs="0"/>
+   *         &lt;element name="hiddenColumns" maxOccurs="unbounded" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attribute name="start" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *                 &lt;attribute name="end" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="calcIdParam" maxOccurs="unbounded" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;extension base="{www.jalview.org/xml/wsparamset}WebServiceParameterSet">
+   *                 &lt;attribute name="calcId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="needsUpdate" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *                 &lt;attribute name="autoUpdate" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *               &lt;/extension>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *         &lt;element name="overview" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+   *                 &lt;attribute name="showHidden" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *                 &lt;attribute name="residueColour" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *                 &lt;attribute name="gapColour" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *                 &lt;attribute name="hiddenColour" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *                 &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *       &lt;/sequence>
+   *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+   *       &lt;attribute name="conservationSelected" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="pidSelected" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="bgColour" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="consThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="pidThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="showFullId" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="rightAlignIds" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="showText" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="showColourText" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="showUnconserved" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="showBoxes" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="wrapAlignment" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="renderGaps" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="showSequenceFeatures" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="showNPfeatureTooltip" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="showDbRefTooltip" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="followHighlight" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *       &lt;attribute name="followSelection" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *       &lt;attribute name="showAnnotation" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="centreColumnLabels" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="showGroupConservation" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="showGroupConsensus" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="showConsensusHistogram" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *       &lt;attribute name="showSequenceLogo" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="normaliseSequenceLogo" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="ignoreGapsinConsensus" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *       &lt;attribute name="startRes" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="startSeq" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="charWidth" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="charHeight" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="fontName" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="fontSize" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="fontStyle" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="scaleProteinAsCdna" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+   *       &lt;attribute name="viewName" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="sequenceSetId" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="gatheredViews" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="textCol1" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="textCol2" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="textColThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}ID" />
+   *       &lt;attribute name="complementId" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="showComplementFeatures" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="showComplementFeaturesOnTop" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(
+    name = "",
+    propOrder =
+    { "annotationColours", "hiddenColumns", "calcIdParam", "overview" })
+  public static class Viewport
+  {
+
+    @XmlElement(name = "AnnotationColours", namespace = "www.jalview.org")
+    protected AnnotationColourScheme annotationColours;
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected List<JalviewModel.Viewport.HiddenColumns> hiddenColumns;
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected List<JalviewModel.Viewport.CalcIdParam> calcIdParam;
+
+    @XmlElement(namespace = "www.jalview.org")
+    protected JalviewModel.Viewport.Overview overview;
+
+    @XmlAttribute(name = "conservationSelected")
+    protected Boolean conservationSelected;
+
+    @XmlAttribute(name = "pidSelected")
+    protected Boolean pidSelected;
+
+    @XmlAttribute(name = "bgColour")
+    protected String bgColour;
+
+    @XmlAttribute(name = "consThreshold")
+    protected Integer consThreshold;
+
+    @XmlAttribute(name = "pidThreshold")
+    protected Integer pidThreshold;
+
+    @XmlAttribute(name = "title")
+    protected String title;
+
+    @XmlAttribute(name = "showFullId")
+    protected Boolean showFullId;
+
+    @XmlAttribute(name = "rightAlignIds")
+    protected Boolean rightAlignIds;
+
+    @XmlAttribute(name = "showText")
+    protected Boolean showText;
+
+    @XmlAttribute(name = "showColourText")
+    protected Boolean showColourText;
+
+    @XmlAttribute(name = "showUnconserved")
+    protected Boolean showUnconserved;
+
+    @XmlAttribute(name = "showBoxes")
+    protected Boolean showBoxes;
+
+    @XmlAttribute(name = "wrapAlignment")
+    protected Boolean wrapAlignment;
 
-        /**
-         * Gets the value of the fontSize property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getFontSize() {
-            return fontSize;
-        }
+    @XmlAttribute(name = "renderGaps")
+    protected Boolean renderGaps;
 
-        /**
-         * Sets the value of the fontSize property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setFontSize(Integer value) {
-            this.fontSize = value;
-        }
+    @XmlAttribute(name = "showSequenceFeatures")
+    protected Boolean showSequenceFeatures;
 
-        /**
-         * Gets the value of the fontStyle property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getFontStyle() {
-            return fontStyle;
-        }
+    @XmlAttribute(name = "showNPfeatureTooltip")
+    protected Boolean showNPfeatureTooltip;
 
-        /**
-         * Sets the value of the fontStyle property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setFontStyle(Integer value) {
-            this.fontStyle = value;
-        }
+    @XmlAttribute(name = "showDbRefTooltip")
+    protected Boolean showDbRefTooltip;
 
-        /**
-         * Gets the value of the threshold property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Float }
-         *     
-         */
-        public Float getThreshold() {
-            return threshold;
-        }
+    @XmlAttribute(name = "followHighlight")
+    protected Boolean followHighlight;
 
-        /**
-         * Sets the value of the threshold property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Float }
-         *     
-         */
-        public void setThreshold(Float value) {
-            this.threshold = value;
-        }
+    @XmlAttribute(name = "followSelection")
+    protected Boolean followSelection;
 
-        /**
-         * Gets the value of the showBootstrap property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowBootstrap() {
-            return showBootstrap;
-        }
+    @XmlAttribute(name = "showAnnotation")
+    protected Boolean showAnnotation;
 
-        /**
-         * Sets the value of the showBootstrap property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowBootstrap(Boolean value) {
-            this.showBootstrap = value;
-        }
+    @XmlAttribute(name = "centreColumnLabels")
+    protected Boolean centreColumnLabels;
 
-        /**
-         * Gets the value of the showDistances property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowDistances() {
-            return showDistances;
-        }
+    @XmlAttribute(name = "showGroupConservation")
+    protected Boolean showGroupConservation;
 
-        /**
-         * Sets the value of the showDistances property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowDistances(Boolean value) {
-            this.showDistances = value;
-        }
+    @XmlAttribute(name = "showGroupConsensus")
+    protected Boolean showGroupConsensus;
 
-        /**
-         * Gets the value of the markUnlinked property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isMarkUnlinked() {
-            return markUnlinked;
-        }
+    @XmlAttribute(name = "showConsensusHistogram")
+    protected Boolean showConsensusHistogram;
 
-        /**
-         * Sets the value of the markUnlinked property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setMarkUnlinked(Boolean value) {
-            this.markUnlinked = value;
-        }
+    @XmlAttribute(name = "showSequenceLogo")
+    protected Boolean showSequenceLogo;
 
-        /**
-         * Gets the value of the fitToWindow property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isFitToWindow() {
-            return fitToWindow;
-        }
+    @XmlAttribute(name = "normaliseSequenceLogo")
+    protected Boolean normaliseSequenceLogo;
 
-        /**
-         * Sets the value of the fitToWindow property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setFitToWindow(Boolean value) {
-            this.fitToWindow = value;
-        }
+    @XmlAttribute(name = "ignoreGapsinConsensus")
+    protected Boolean ignoreGapsinConsensus;
 
-        /**
-         * Gets the value of the currentTree property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isCurrentTree() {
-            return currentTree;
-        }
+    @XmlAttribute(name = "startRes")
+    protected Integer startRes;
 
-        /**
-         * Sets the value of the currentTree property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setCurrentTree(Boolean value) {
-            this.currentTree = value;
-        }
+    @XmlAttribute(name = "startSeq")
+    protected Integer startSeq;
 
-        /**
-         * Gets the value of the columnWise property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isColumnWise() {
-            if (columnWise == null) {
-                return false;
-            } else {
-                return columnWise;
-            }
-        }
+    @XmlAttribute(name = "charWidth")
+    protected Integer charWidth;
 
-        /**
-         * Sets the value of the columnWise property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setColumnWise(Boolean value) {
-            this.columnWise = value;
-        }
+    @XmlAttribute(name = "charHeight")
+    protected Integer charHeight;
 
-        /**
-         * Gets the value of the columnReference property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getColumnReference() {
-            return columnReference;
-        }
+    @XmlAttribute(name = "fontName")
+    protected String fontName;
 
-        /**
-         * Sets the value of the columnReference property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setColumnReference(String value) {
-            this.columnReference = value;
-        }
+    @XmlAttribute(name = "fontSize")
+    protected Integer fontSize;
 
-        /**
-         * Gets the value of the id property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getId() {
-            return id;
-        }
+    @XmlAttribute(name = "fontStyle")
+    protected Integer fontStyle;
 
-        /**
-         * Sets the value of the id property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setId(String value) {
-            this.id = value;
-        }
+    @XmlAttribute(name = "scaleProteinAsCdna")
+    protected Boolean scaleProteinAsCdna;
 
-        /**
-         * Gets the value of the linkToAllViews property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isLinkToAllViews() {
-            if (linkToAllViews == null) {
-                return false;
-            } else {
-                return linkToAllViews;
-            }
-        }
+    @XmlAttribute(name = "viewName")
+    protected String viewName;
 
-        /**
-         * Sets the value of the linkToAllViews property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setLinkToAllViews(Boolean value) {
-            this.linkToAllViews = value;
-        }
+    @XmlAttribute(name = "sequenceSetId")
+    protected String sequenceSetId;
+
+    @XmlAttribute(name = "gatheredViews")
+    protected Boolean gatheredViews;
 
-        /**
-         * Gets the value of the width property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getWidth() {
-            return width;
-        }
+    @XmlAttribute(name = "textCol1")
+    protected Integer textCol1;
 
-        /**
-         * Sets the value of the width property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setWidth(Integer value) {
-            this.width = value;
-        }
+    @XmlAttribute(name = "textCol2")
+    protected Integer textCol2;
 
-        /**
-         * Gets the value of the height property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getHeight() {
-            return height;
-        }
+    @XmlAttribute(name = "textColThreshold")
+    protected Integer textColThreshold;
 
-        /**
-         * Sets the value of the height property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setHeight(Integer value) {
-            this.height = value;
-        }
+    @XmlAttribute(name = "id")
+    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+    @XmlID
+    @XmlSchemaType(name = "ID")
+    protected String id;
 
-        /**
-         * Gets the value of the xpos property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getXpos() {
-            return xpos;
-        }
+    @XmlAttribute(name = "complementId")
+    protected String complementId;
 
-        /**
-         * Sets the value of the xpos property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setXpos(Integer value) {
-            this.xpos = value;
-        }
+    @XmlAttribute(name = "showComplementFeatures")
+    protected Boolean showComplementFeatures;
 
-        /**
-         * Gets the value of the ypos property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getYpos() {
-            return ypos;
-        }
+    @XmlAttribute(name = "showComplementFeaturesOnTop")
+    protected Boolean showComplementFeaturesOnTop;
 
-        /**
-         * Sets the value of the ypos property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setYpos(Integer value) {
-            this.ypos = value;
-        }
+    @XmlAttribute(name = "width")
+    protected Integer width;
 
+    @XmlAttribute(name = "height")
+    protected Integer height;
+
+    @XmlAttribute(name = "xpos")
+    protected Integer xpos;
+
+    @XmlAttribute(name = "ypos")
+    protected Integer ypos;
+
+    /**
+     * Gets the value of the annotationColours property.
+     * 
+     * @return possible object is {@link AnnotationColourScheme }
+     * 
+     */
+    public AnnotationColourScheme getAnnotationColours()
+    {
+      return annotationColours;
     }
 
+    /**
+     * Sets the value of the annotationColours property.
+     * 
+     * @param value
+     *          allowed object is {@link AnnotationColourScheme }
+     * 
+     */
+    public void setAnnotationColours(AnnotationColourScheme value)
+    {
+      this.annotationColours = value;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the hiddenColumns property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the hiddenColumns property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="UserColourScheme" type="{www.jalview.org/colours}JalviewUserColours"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getHiddenColumns().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link JalviewModel.Viewport.HiddenColumns }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "userColourScheme"
-    })
-    public static class UserColours {
-
-        @XmlElement(name = "UserColourScheme", namespace = "www.jalview.org", required = true)
-        protected JalviewUserColours userColourScheme;
-        @XmlAttribute(name = "id")
-        protected String id;
-
-        /**
-         * Gets the value of the userColourScheme property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link JalviewUserColours }
-         *     
-         */
-        public JalviewUserColours getUserColourScheme() {
-            return userColourScheme;
-        }
-
-        /**
-         * Sets the value of the userColourScheme property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link JalviewUserColours }
-         *     
-         */
-        public void setUserColourScheme(JalviewUserColours value) {
-            this.userColourScheme = value;
-        }
-
-        /**
-         * Gets the value of the id property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getId() {
-            return id;
-        }
-
-        /**
-         * Sets the value of the id property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setId(String value) {
-            this.id = value;
-        }
-
+    public List<JalviewModel.Viewport.HiddenColumns> getHiddenColumns()
+    {
+      if (hiddenColumns == null)
+      {
+        hiddenColumns = new ArrayList<JalviewModel.Viewport.HiddenColumns>();
+      }
+      return this.hiddenColumns;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the calcIdParam property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the calcIdParam property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="AnnotationColours" type="{www.jalview.org}AnnotationColourScheme" minOccurs="0"/>
-     *         &lt;element name="hiddenColumns" maxOccurs="unbounded" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attribute name="start" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *                 &lt;attribute name="end" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="calcIdParam" maxOccurs="unbounded" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;extension base="{www.jalview.org/xml/wsparamset}WebServiceParameterSet">
-     *                 &lt;attribute name="calcId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="needsUpdate" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *                 &lt;attribute name="autoUpdate" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *               &lt;/extension>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *         &lt;element name="overview" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-     *                 &lt;attribute name="showHidden" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *                 &lt;attribute name="residueColour" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *                 &lt;attribute name="gapColour" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *                 &lt;attribute name="hiddenColour" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *                 &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *       &lt;/sequence>
-     *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-     *       &lt;attribute name="conservationSelected" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="pidSelected" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="bgColour" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="consThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="pidThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="showFullId" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="rightAlignIds" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="showText" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="showColourText" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="showUnconserved" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="showBoxes" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="wrapAlignment" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="renderGaps" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="showSequenceFeatures" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="showNPfeatureTooltip" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="showDbRefTooltip" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="followHighlight" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *       &lt;attribute name="followSelection" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *       &lt;attribute name="showAnnotation" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="centreColumnLabels" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="showGroupConservation" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="showGroupConsensus" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="showConsensusHistogram" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *       &lt;attribute name="showSequenceLogo" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="normaliseSequenceLogo" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="ignoreGapsinConsensus" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *       &lt;attribute name="startRes" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="startSeq" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="charWidth" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="charHeight" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="fontName" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="fontSize" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="fontStyle" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="scaleProteinAsCdna" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
-     *       &lt;attribute name="viewName" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="sequenceSetId" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="gatheredViews" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="textCol1" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="textCol2" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="textColThreshold" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}ID" />
-     *       &lt;attribute name="complementId" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="showComplementFeatures" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="showComplementFeaturesOnTop" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getCalcIdParam().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link JalviewModel.Viewport.CalcIdParam }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "annotationColours",
-        "hiddenColumns",
-        "calcIdParam",
-        "overview"
-    })
-    public static class Viewport {
-
-        @XmlElement(name = "AnnotationColours", namespace = "www.jalview.org")
-        protected AnnotationColourScheme annotationColours;
-        @XmlElement(namespace = "www.jalview.org")
-        protected List<JalviewModel.Viewport.HiddenColumns> hiddenColumns;
-        @XmlElement(namespace = "www.jalview.org")
-        protected List<JalviewModel.Viewport.CalcIdParam> calcIdParam;
-        @XmlElement(namespace = "www.jalview.org")
-        protected JalviewModel.Viewport.Overview overview;
-        @XmlAttribute(name = "conservationSelected")
-        protected Boolean conservationSelected;
-        @XmlAttribute(name = "pidSelected")
-        protected Boolean pidSelected;
-        @XmlAttribute(name = "bgColour")
-        protected String bgColour;
-        @XmlAttribute(name = "consThreshold")
-        protected Integer consThreshold;
-        @XmlAttribute(name = "pidThreshold")
-        protected Integer pidThreshold;
-        @XmlAttribute(name = "title")
-        protected String title;
-        @XmlAttribute(name = "showFullId")
-        protected Boolean showFullId;
-        @XmlAttribute(name = "rightAlignIds")
-        protected Boolean rightAlignIds;
-        @XmlAttribute(name = "showText")
-        protected Boolean showText;
-        @XmlAttribute(name = "showColourText")
-        protected Boolean showColourText;
-        @XmlAttribute(name = "showUnconserved")
-        protected Boolean showUnconserved;
-        @XmlAttribute(name = "showBoxes")
-        protected Boolean showBoxes;
-        @XmlAttribute(name = "wrapAlignment")
-        protected Boolean wrapAlignment;
-        @XmlAttribute(name = "renderGaps")
-        protected Boolean renderGaps;
-        @XmlAttribute(name = "showSequenceFeatures")
-        protected Boolean showSequenceFeatures;
-        @XmlAttribute(name = "showNPfeatureTooltip")
-        protected Boolean showNPfeatureTooltip;
-        @XmlAttribute(name = "showDbRefTooltip")
-        protected Boolean showDbRefTooltip;
-        @XmlAttribute(name = "followHighlight")
-        protected Boolean followHighlight;
-        @XmlAttribute(name = "followSelection")
-        protected Boolean followSelection;
-        @XmlAttribute(name = "showAnnotation")
-        protected Boolean showAnnotation;
-        @XmlAttribute(name = "centreColumnLabels")
-        protected Boolean centreColumnLabels;
-        @XmlAttribute(name = "showGroupConservation")
-        protected Boolean showGroupConservation;
-        @XmlAttribute(name = "showGroupConsensus")
-        protected Boolean showGroupConsensus;
-        @XmlAttribute(name = "showConsensusHistogram")
-        protected Boolean showConsensusHistogram;
-        @XmlAttribute(name = "showSequenceLogo")
-        protected Boolean showSequenceLogo;
-        @XmlAttribute(name = "normaliseSequenceLogo")
-        protected Boolean normaliseSequenceLogo;
-        @XmlAttribute(name = "ignoreGapsinConsensus")
-        protected Boolean ignoreGapsinConsensus;
-        @XmlAttribute(name = "startRes")
-        protected Integer startRes;
-        @XmlAttribute(name = "startSeq")
-        protected Integer startSeq;
-        @XmlAttribute(name = "charWidth")
-        protected Integer charWidth;
-        @XmlAttribute(name = "charHeight")
-        protected Integer charHeight;
-        @XmlAttribute(name = "fontName")
-        protected String fontName;
-        @XmlAttribute(name = "fontSize")
-        protected Integer fontSize;
-        @XmlAttribute(name = "fontStyle")
-        protected Integer fontStyle;
-        @XmlAttribute(name = "scaleProteinAsCdna")
-        protected Boolean scaleProteinAsCdna;
-        @XmlAttribute(name = "viewName")
-        protected String viewName;
-        @XmlAttribute(name = "sequenceSetId")
-        protected String sequenceSetId;
-        @XmlAttribute(name = "gatheredViews")
-        protected Boolean gatheredViews;
-        @XmlAttribute(name = "textCol1")
-        protected Integer textCol1;
-        @XmlAttribute(name = "textCol2")
-        protected Integer textCol2;
-        @XmlAttribute(name = "textColThreshold")
-        protected Integer textColThreshold;
-        @XmlAttribute(name = "id")
-        @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
-        @XmlID
-        @XmlSchemaType(name = "ID")
-        protected String id;
-        @XmlAttribute(name = "complementId")
-        protected String complementId;
-        @XmlAttribute(name = "showComplementFeatures")
-        protected Boolean showComplementFeatures;
-        @XmlAttribute(name = "showComplementFeaturesOnTop")
-        protected Boolean showComplementFeaturesOnTop;
-        @XmlAttribute(name = "width")
-        protected Integer width;
-        @XmlAttribute(name = "height")
-        protected Integer height;
-        @XmlAttribute(name = "xpos")
-        protected Integer xpos;
-        @XmlAttribute(name = "ypos")
-        protected Integer ypos;
-
-        /**
-         * Gets the value of the annotationColours property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link AnnotationColourScheme }
-         *     
-         */
-        public AnnotationColourScheme getAnnotationColours() {
-            return annotationColours;
-        }
-
-        /**
-         * Sets the value of the annotationColours property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link AnnotationColourScheme }
-         *     
-         */
-        public void setAnnotationColours(AnnotationColourScheme value) {
-            this.annotationColours = value;
-        }
-
-        /**
-         * Gets the value of the hiddenColumns property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the hiddenColumns property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getHiddenColumns().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link JalviewModel.Viewport.HiddenColumns }
-         * 
-         * 
-         */
-        public List<JalviewModel.Viewport.HiddenColumns> getHiddenColumns() {
-            if (hiddenColumns == null) {
-                hiddenColumns = new ArrayList<JalviewModel.Viewport.HiddenColumns>();
-            }
-            return this.hiddenColumns;
-        }
-
-        /**
-         * Gets the value of the calcIdParam property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the calcIdParam property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getCalcIdParam().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link JalviewModel.Viewport.CalcIdParam }
-         * 
-         * 
-         */
-        public List<JalviewModel.Viewport.CalcIdParam> getCalcIdParam() {
-            if (calcIdParam == null) {
-                calcIdParam = new ArrayList<JalviewModel.Viewport.CalcIdParam>();
-            }
-            return this.calcIdParam;
-        }
-
-        /**
-         * Gets the value of the overview property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link JalviewModel.Viewport.Overview }
-         *     
-         */
-        public JalviewModel.Viewport.Overview getOverview() {
-            return overview;
-        }
-
-        /**
-         * Sets the value of the overview property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link JalviewModel.Viewport.Overview }
-         *     
-         */
-        public void setOverview(JalviewModel.Viewport.Overview value) {
-            this.overview = value;
-        }
-
-        /**
-         * Gets the value of the conservationSelected property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isConservationSelected() {
-            return conservationSelected;
-        }
-
-        /**
-         * Sets the value of the conservationSelected property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setConservationSelected(Boolean value) {
-            this.conservationSelected = value;
-        }
-
-        /**
-         * Gets the value of the pidSelected property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isPidSelected() {
-            return pidSelected;
-        }
-
-        /**
-         * Sets the value of the pidSelected property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setPidSelected(Boolean value) {
-            this.pidSelected = value;
-        }
-
-        /**
-         * Gets the value of the bgColour property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getBgColour() {
-            return bgColour;
-        }
+    public List<JalviewModel.Viewport.CalcIdParam> getCalcIdParam()
+    {
+      if (calcIdParam == null)
+      {
+        calcIdParam = new ArrayList<JalviewModel.Viewport.CalcIdParam>();
+      }
+      return this.calcIdParam;
+    }
 
-        /**
-         * Sets the value of the bgColour property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setBgColour(String value) {
-            this.bgColour = value;
-        }
+    /**
+     * Gets the value of the overview property.
+     * 
+     * @return possible object is {@link JalviewModel.Viewport.Overview }
+     * 
+     */
+    public JalviewModel.Viewport.Overview getOverview()
+    {
+      return overview;
+    }
 
-        /**
-         * Gets the value of the consThreshold property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getConsThreshold() {
-            return consThreshold;
-        }
+    /**
+     * Sets the value of the overview property.
+     * 
+     * @param value
+     *          allowed object is {@link JalviewModel.Viewport.Overview }
+     * 
+     */
+    public void setOverview(JalviewModel.Viewport.Overview value)
+    {
+      this.overview = value;
+    }
 
-        /**
-         * Sets the value of the consThreshold property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setConsThreshold(Integer value) {
-            this.consThreshold = value;
-        }
+    /**
+     * Gets the value of the conservationSelected property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isConservationSelected()
+    {
+      return conservationSelected;
+    }
 
-        /**
-         * Gets the value of the pidThreshold property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getPidThreshold() {
-            return pidThreshold;
-        }
+    /**
+     * Sets the value of the conservationSelected property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setConservationSelected(Boolean value)
+    {
+      this.conservationSelected = value;
+    }
 
-        /**
-         * Sets the value of the pidThreshold property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setPidThreshold(Integer value) {
-            this.pidThreshold = value;
-        }
+    /**
+     * Gets the value of the pidSelected property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isPidSelected()
+    {
+      return pidSelected;
+    }
 
-        /**
-         * Gets the value of the title property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getTitle() {
-            return title;
-        }
+    /**
+     * Sets the value of the pidSelected property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setPidSelected(Boolean value)
+    {
+      this.pidSelected = value;
+    }
 
-        /**
-         * Sets the value of the title property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setTitle(String value) {
-            this.title = value;
-        }
+    /**
+     * Gets the value of the bgColour property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getBgColour()
+    {
+      return bgColour;
+    }
 
-        /**
-         * Gets the value of the showFullId property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowFullId() {
-            return showFullId;
-        }
+    /**
+     * Sets the value of the bgColour property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setBgColour(String value)
+    {
+      this.bgColour = value;
+    }
 
-        /**
-         * Sets the value of the showFullId property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowFullId(Boolean value) {
-            this.showFullId = value;
-        }
+    /**
+     * Gets the value of the consThreshold property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getConsThreshold()
+    {
+      return consThreshold;
+    }
 
-        /**
-         * Gets the value of the rightAlignIds property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isRightAlignIds() {
-            return rightAlignIds;
-        }
+    /**
+     * Sets the value of the consThreshold property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setConsThreshold(Integer value)
+    {
+      this.consThreshold = value;
+    }
 
-        /**
-         * Sets the value of the rightAlignIds property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setRightAlignIds(Boolean value) {
-            this.rightAlignIds = value;
-        }
+    /**
+     * Gets the value of the pidThreshold property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getPidThreshold()
+    {
+      return pidThreshold;
+    }
 
-        /**
-         * Gets the value of the showText property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowText() {
-            return showText;
-        }
+    /**
+     * Sets the value of the pidThreshold property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setPidThreshold(Integer value)
+    {
+      this.pidThreshold = value;
+    }
 
-        /**
-         * Sets the value of the showText property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowText(Boolean value) {
-            this.showText = value;
-        }
+    /**
+     * Gets the value of the title property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getTitle()
+    {
+      return title;
+    }
 
-        /**
-         * Gets the value of the showColourText property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowColourText() {
-            return showColourText;
-        }
+    /**
+     * Sets the value of the title property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setTitle(String value)
+    {
+      this.title = value;
+    }
 
-        /**
-         * Sets the value of the showColourText property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowColourText(Boolean value) {
-            this.showColourText = value;
-        }
+    /**
+     * Gets the value of the showFullId property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowFullId()
+    {
+      return showFullId;
+    }
 
-        /**
-         * Gets the value of the showUnconserved property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isShowUnconserved() {
-            if (showUnconserved == null) {
-                return false;
-            } else {
-                return showUnconserved;
-            }
-        }
+    /**
+     * Sets the value of the showFullId property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowFullId(Boolean value)
+    {
+      this.showFullId = value;
+    }
 
-        /**
-         * Sets the value of the showUnconserved property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowUnconserved(Boolean value) {
-            this.showUnconserved = value;
-        }
+    /**
+     * Gets the value of the rightAlignIds property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isRightAlignIds()
+    {
+      return rightAlignIds;
+    }
 
-        /**
-         * Gets the value of the showBoxes property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowBoxes() {
-            return showBoxes;
-        }
+    /**
+     * Sets the value of the rightAlignIds property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setRightAlignIds(Boolean value)
+    {
+      this.rightAlignIds = value;
+    }
 
-        /**
-         * Sets the value of the showBoxes property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowBoxes(Boolean value) {
-            this.showBoxes = value;
-        }
+    /**
+     * Gets the value of the showText property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowText()
+    {
+      return showText;
+    }
 
-        /**
-         * Gets the value of the wrapAlignment property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isWrapAlignment() {
-            return wrapAlignment;
-        }
+    /**
+     * Sets the value of the showText property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowText(Boolean value)
+    {
+      this.showText = value;
+    }
 
-        /**
-         * Sets the value of the wrapAlignment property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setWrapAlignment(Boolean value) {
-            this.wrapAlignment = value;
-        }
+    /**
+     * Gets the value of the showColourText property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowColourText()
+    {
+      return showColourText;
+    }
 
-        /**
-         * Gets the value of the renderGaps property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isRenderGaps() {
-            return renderGaps;
-        }
+    /**
+     * Sets the value of the showColourText property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowColourText(Boolean value)
+    {
+      this.showColourText = value;
+    }
 
-        /**
-         * Sets the value of the renderGaps property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setRenderGaps(Boolean value) {
-            this.renderGaps = value;
-        }
+    /**
+     * Gets the value of the showUnconserved property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowUnconserved()
+    {
+      if (showUnconserved == null)
+      {
+        return false;
+      }
+      else
+      {
+        return showUnconserved;
+      }
+    }
 
-        /**
-         * Gets the value of the showSequenceFeatures property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowSequenceFeatures() {
-            return showSequenceFeatures;
-        }
+    /**
+     * Sets the value of the showUnconserved property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowUnconserved(Boolean value)
+    {
+      this.showUnconserved = value;
+    }
 
-        /**
-         * Sets the value of the showSequenceFeatures property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowSequenceFeatures(Boolean value) {
-            this.showSequenceFeatures = value;
-        }
+    /**
+     * Gets the value of the showBoxes property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowBoxes()
+    {
+      return showBoxes;
+    }
 
-        /**
-         * Gets the value of the showNPfeatureTooltip property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowNPfeatureTooltip() {
-            return showNPfeatureTooltip;
-        }
+    /**
+     * Sets the value of the showBoxes property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowBoxes(Boolean value)
+    {
+      this.showBoxes = value;
+    }
 
-        /**
-         * Sets the value of the showNPfeatureTooltip property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowNPfeatureTooltip(Boolean value) {
-            this.showNPfeatureTooltip = value;
-        }
+    /**
+     * Gets the value of the wrapAlignment property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isWrapAlignment()
+    {
+      return wrapAlignment;
+    }
 
-        /**
-         * Gets the value of the showDbRefTooltip property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowDbRefTooltip() {
-            return showDbRefTooltip;
-        }
+    /**
+     * Sets the value of the wrapAlignment property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setWrapAlignment(Boolean value)
+    {
+      this.wrapAlignment = value;
+    }
 
-        /**
-         * Sets the value of the showDbRefTooltip property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowDbRefTooltip(Boolean value) {
-            this.showDbRefTooltip = value;
-        }
+    /**
+     * Gets the value of the renderGaps property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isRenderGaps()
+    {
+      return renderGaps;
+    }
 
-        /**
-         * Gets the value of the followHighlight property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isFollowHighlight() {
-            if (followHighlight == null) {
-                return true;
-            } else {
-                return followHighlight;
-            }
-        }
+    /**
+     * Sets the value of the renderGaps property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setRenderGaps(Boolean value)
+    {
+      this.renderGaps = value;
+    }
 
-        /**
-         * Sets the value of the followHighlight property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setFollowHighlight(Boolean value) {
-            this.followHighlight = value;
-        }
+    /**
+     * Gets the value of the showSequenceFeatures property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowSequenceFeatures()
+    {
+      return showSequenceFeatures;
+    }
 
-        /**
-         * Gets the value of the followSelection property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isFollowSelection() {
-            if (followSelection == null) {
-                return true;
-            } else {
-                return followSelection;
-            }
-        }
+    /**
+     * Sets the value of the showSequenceFeatures property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowSequenceFeatures(Boolean value)
+    {
+      this.showSequenceFeatures = value;
+    }
 
-        /**
-         * Sets the value of the followSelection property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setFollowSelection(Boolean value) {
-            this.followSelection = value;
-        }
+    /**
+     * Gets the value of the showNPfeatureTooltip property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowNPfeatureTooltip()
+    {
+      return showNPfeatureTooltip;
+    }
 
-        /**
-         * Gets the value of the showAnnotation property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isShowAnnotation() {
-            return showAnnotation;
-        }
+    /**
+     * Sets the value of the showNPfeatureTooltip property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowNPfeatureTooltip(Boolean value)
+    {
+      this.showNPfeatureTooltip = value;
+    }
 
-        /**
-         * Sets the value of the showAnnotation property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowAnnotation(Boolean value) {
-            this.showAnnotation = value;
-        }
+    /**
+     * Gets the value of the showDbRefTooltip property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowDbRefTooltip()
+    {
+      return showDbRefTooltip;
+    }
 
-        /**
-         * Gets the value of the centreColumnLabels property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isCentreColumnLabels() {
-            if (centreColumnLabels == null) {
-                return false;
-            } else {
-                return centreColumnLabels;
-            }
-        }
+    /**
+     * Sets the value of the showDbRefTooltip property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowDbRefTooltip(Boolean value)
+    {
+      this.showDbRefTooltip = value;
+    }
 
-        /**
-         * Sets the value of the centreColumnLabels property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setCentreColumnLabels(Boolean value) {
-            this.centreColumnLabels = value;
-        }
+    /**
+     * Gets the value of the followHighlight property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isFollowHighlight()
+    {
+      if (followHighlight == null)
+      {
+        return true;
+      }
+      else
+      {
+        return followHighlight;
+      }
+    }
 
-        /**
-         * Gets the value of the showGroupConservation property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isShowGroupConservation() {
-            if (showGroupConservation == null) {
-                return false;
-            } else {
-                return showGroupConservation;
-            }
-        }
+    /**
+     * Sets the value of the followHighlight property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setFollowHighlight(Boolean value)
+    {
+      this.followHighlight = value;
+    }
 
-        /**
-         * Sets the value of the showGroupConservation property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowGroupConservation(Boolean value) {
-            this.showGroupConservation = value;
-        }
+    /**
+     * Gets the value of the followSelection property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isFollowSelection()
+    {
+      if (followSelection == null)
+      {
+        return true;
+      }
+      else
+      {
+        return followSelection;
+      }
+    }
 
-        /**
-         * Gets the value of the showGroupConsensus property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isShowGroupConsensus() {
-            if (showGroupConsensus == null) {
-                return false;
-            } else {
-                return showGroupConsensus;
-            }
-        }
+    /**
+     * Sets the value of the followSelection property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setFollowSelection(Boolean value)
+    {
+      this.followSelection = value;
+    }
 
-        /**
-         * Sets the value of the showGroupConsensus property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowGroupConsensus(Boolean value) {
-            this.showGroupConsensus = value;
-        }
+    /**
+     * Gets the value of the showAnnotation property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isShowAnnotation()
+    {
+      return showAnnotation;
+    }
 
-        /**
-         * Gets the value of the showConsensusHistogram property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isShowConsensusHistogram() {
-            if (showConsensusHistogram == null) {
-                return true;
-            } else {
-                return showConsensusHistogram;
-            }
-        }
+    /**
+     * Sets the value of the showAnnotation property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowAnnotation(Boolean value)
+    {
+      this.showAnnotation = value;
+    }
 
-        /**
-         * Sets the value of the showConsensusHistogram property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowConsensusHistogram(Boolean value) {
-            this.showConsensusHistogram = value;
-        }
+    /**
+     * Gets the value of the centreColumnLabels property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isCentreColumnLabels()
+    {
+      if (centreColumnLabels == null)
+      {
+        return false;
+      }
+      else
+      {
+        return centreColumnLabels;
+      }
+    }
 
-        /**
-         * Gets the value of the showSequenceLogo property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isShowSequenceLogo() {
-            if (showSequenceLogo == null) {
-                return false;
-            } else {
-                return showSequenceLogo;
-            }
-        }
+    /**
+     * Sets the value of the centreColumnLabels property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setCentreColumnLabels(Boolean value)
+    {
+      this.centreColumnLabels = value;
+    }
 
-        /**
-         * Sets the value of the showSequenceLogo property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowSequenceLogo(Boolean value) {
-            this.showSequenceLogo = value;
-        }
+    /**
+     * Gets the value of the showGroupConservation property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowGroupConservation()
+    {
+      if (showGroupConservation == null)
+      {
+        return false;
+      }
+      else
+      {
+        return showGroupConservation;
+      }
+    }
 
-        /**
-         * Gets the value of the normaliseSequenceLogo property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isNormaliseSequenceLogo() {
-            if (normaliseSequenceLogo == null) {
-                return false;
-            } else {
-                return normaliseSequenceLogo;
-            }
-        }
+    /**
+     * Sets the value of the showGroupConservation property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowGroupConservation(Boolean value)
+    {
+      this.showGroupConservation = value;
+    }
 
-        /**
-         * Sets the value of the normaliseSequenceLogo property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setNormaliseSequenceLogo(Boolean value) {
-            this.normaliseSequenceLogo = value;
-        }
+    /**
+     * Gets the value of the showGroupConsensus property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowGroupConsensus()
+    {
+      if (showGroupConsensus == null)
+      {
+        return false;
+      }
+      else
+      {
+        return showGroupConsensus;
+      }
+    }
 
-        /**
-         * Gets the value of the ignoreGapsinConsensus property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isIgnoreGapsinConsensus() {
-            if (ignoreGapsinConsensus == null) {
-                return true;
-            } else {
-                return ignoreGapsinConsensus;
-            }
-        }
+    /**
+     * Sets the value of the showGroupConsensus property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowGroupConsensus(Boolean value)
+    {
+      this.showGroupConsensus = value;
+    }
 
-        /**
-         * Sets the value of the ignoreGapsinConsensus property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setIgnoreGapsinConsensus(Boolean value) {
-            this.ignoreGapsinConsensus = value;
-        }
+    /**
+     * Gets the value of the showConsensusHistogram property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowConsensusHistogram()
+    {
+      if (showConsensusHistogram == null)
+      {
+        return true;
+      }
+      else
+      {
+        return showConsensusHistogram;
+      }
+    }
 
-        /**
-         * Gets the value of the startRes property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getStartRes() {
-            return startRes;
-        }
+    /**
+     * Sets the value of the showConsensusHistogram property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowConsensusHistogram(Boolean value)
+    {
+      this.showConsensusHistogram = value;
+    }
 
-        /**
-         * Sets the value of the startRes property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setStartRes(Integer value) {
-            this.startRes = value;
-        }
+    /**
+     * Gets the value of the showSequenceLogo property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowSequenceLogo()
+    {
+      if (showSequenceLogo == null)
+      {
+        return false;
+      }
+      else
+      {
+        return showSequenceLogo;
+      }
+    }
 
-        /**
-         * Gets the value of the startSeq property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getStartSeq() {
-            return startSeq;
-        }
+    /**
+     * Sets the value of the showSequenceLogo property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowSequenceLogo(Boolean value)
+    {
+      this.showSequenceLogo = value;
+    }
 
-        /**
-         * Sets the value of the startSeq property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setStartSeq(Integer value) {
-            this.startSeq = value;
-        }
+    /**
+     * Gets the value of the normaliseSequenceLogo property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isNormaliseSequenceLogo()
+    {
+      if (normaliseSequenceLogo == null)
+      {
+        return false;
+      }
+      else
+      {
+        return normaliseSequenceLogo;
+      }
+    }
 
-        /**
-         * Gets the value of the charWidth property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getCharWidth() {
-            return charWidth;
-        }
+    /**
+     * Sets the value of the normaliseSequenceLogo property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setNormaliseSequenceLogo(Boolean value)
+    {
+      this.normaliseSequenceLogo = value;
+    }
+
+    /**
+     * Gets the value of the ignoreGapsinConsensus property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isIgnoreGapsinConsensus()
+    {
+      if (ignoreGapsinConsensus == null)
+      {
+        return true;
+      }
+      else
+      {
+        return ignoreGapsinConsensus;
+      }
+    }
 
-        /**
-         * Sets the value of the charWidth property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setCharWidth(Integer value) {
-            this.charWidth = value;
-        }
+    /**
+     * Sets the value of the ignoreGapsinConsensus property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setIgnoreGapsinConsensus(Boolean value)
+    {
+      this.ignoreGapsinConsensus = value;
+    }
 
-        /**
-         * Gets the value of the charHeight property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getCharHeight() {
-            return charHeight;
-        }
+    /**
+     * Gets the value of the startRes property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getStartRes()
+    {
+      return startRes;
+    }
 
-        /**
-         * Sets the value of the charHeight property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setCharHeight(Integer value) {
-            this.charHeight = value;
-        }
+    /**
+     * Sets the value of the startRes property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setStartRes(Integer value)
+    {
+      this.startRes = value;
+    }
 
-        /**
-         * Gets the value of the fontName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getFontName() {
-            return fontName;
-        }
+    /**
+     * Gets the value of the startSeq property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getStartSeq()
+    {
+      return startSeq;
+    }
 
-        /**
-         * Sets the value of the fontName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setFontName(String value) {
-            this.fontName = value;
-        }
+    /**
+     * Sets the value of the startSeq property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setStartSeq(Integer value)
+    {
+      this.startSeq = value;
+    }
 
-        /**
-         * Gets the value of the fontSize property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getFontSize() {
-            return fontSize;
-        }
+    /**
+     * Gets the value of the charWidth property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getCharWidth()
+    {
+      return charWidth;
+    }
 
-        /**
-         * Sets the value of the fontSize property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setFontSize(Integer value) {
-            this.fontSize = value;
-        }
+    /**
+     * Sets the value of the charWidth property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setCharWidth(Integer value)
+    {
+      this.charWidth = value;
+    }
 
-        /**
-         * Gets the value of the fontStyle property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getFontStyle() {
-            return fontStyle;
-        }
+    /**
+     * Gets the value of the charHeight property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getCharHeight()
+    {
+      return charHeight;
+    }
 
-        /**
-         * Sets the value of the fontStyle property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setFontStyle(Integer value) {
-            this.fontStyle = value;
-        }
+    /**
+     * Sets the value of the charHeight property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setCharHeight(Integer value)
+    {
+      this.charHeight = value;
+    }
 
-        /**
-         * Gets the value of the scaleProteinAsCdna property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isScaleProteinAsCdna() {
-            if (scaleProteinAsCdna == null) {
-                return true;
-            } else {
-                return scaleProteinAsCdna;
-            }
-        }
+    /**
+     * Gets the value of the fontName property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getFontName()
+    {
+      return fontName;
+    }
 
-        /**
-         * Sets the value of the scaleProteinAsCdna property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setScaleProteinAsCdna(Boolean value) {
-            this.scaleProteinAsCdna = value;
-        }
+    /**
+     * Sets the value of the fontName property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setFontName(String value)
+    {
+      this.fontName = value;
+    }
 
-        /**
-         * Gets the value of the viewName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getViewName() {
-            return viewName;
-        }
+    /**
+     * Gets the value of the fontSize property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getFontSize()
+    {
+      return fontSize;
+    }
 
-        /**
-         * Sets the value of the viewName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setViewName(String value) {
-            this.viewName = value;
-        }
+    /**
+     * Sets the value of the fontSize property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setFontSize(Integer value)
+    {
+      this.fontSize = value;
+    }
 
-        /**
-         * Gets the value of the sequenceSetId property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getSequenceSetId() {
-            return sequenceSetId;
-        }
+    /**
+     * Gets the value of the fontStyle property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getFontStyle()
+    {
+      return fontStyle;
+    }
 
-        /**
-         * Sets the value of the sequenceSetId property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setSequenceSetId(String value) {
-            this.sequenceSetId = value;
-        }
+    /**
+     * Sets the value of the fontStyle property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setFontStyle(Integer value)
+    {
+      this.fontStyle = value;
+    }
 
-        /**
-         * Gets the value of the gatheredViews property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isGatheredViews() {
-            return gatheredViews;
-        }
+    /**
+     * Gets the value of the scaleProteinAsCdna property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isScaleProteinAsCdna()
+    {
+      if (scaleProteinAsCdna == null)
+      {
+        return true;
+      }
+      else
+      {
+        return scaleProteinAsCdna;
+      }
+    }
 
-        /**
-         * Sets the value of the gatheredViews property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setGatheredViews(Boolean value) {
-            this.gatheredViews = value;
-        }
+    /**
+     * Sets the value of the scaleProteinAsCdna property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setScaleProteinAsCdna(Boolean value)
+    {
+      this.scaleProteinAsCdna = value;
+    }
 
-        /**
-         * Gets the value of the textCol1 property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getTextCol1() {
-            return textCol1;
-        }
+    /**
+     * Gets the value of the viewName property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getViewName()
+    {
+      return viewName;
+    }
 
-        /**
-         * Sets the value of the textCol1 property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setTextCol1(Integer value) {
-            this.textCol1 = value;
-        }
+    /**
+     * Sets the value of the viewName property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setViewName(String value)
+    {
+      this.viewName = value;
+    }
 
-        /**
-         * Gets the value of the textCol2 property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getTextCol2() {
-            return textCol2;
-        }
+    /**
+     * Gets the value of the sequenceSetId property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getSequenceSetId()
+    {
+      return sequenceSetId;
+    }
 
-        /**
-         * Sets the value of the textCol2 property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setTextCol2(Integer value) {
-            this.textCol2 = value;
-        }
+    /**
+     * Sets the value of the sequenceSetId property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setSequenceSetId(String value)
+    {
+      this.sequenceSetId = value;
+    }
 
-        /**
-         * Gets the value of the textColThreshold property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getTextColThreshold() {
-            return textColThreshold;
-        }
+    /**
+     * Gets the value of the gatheredViews property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isGatheredViews()
+    {
+      return gatheredViews;
+    }
 
-        /**
-         * Sets the value of the textColThreshold property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setTextColThreshold(Integer value) {
-            this.textColThreshold = value;
-        }
+    /**
+     * Sets the value of the gatheredViews property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setGatheredViews(Boolean value)
+    {
+      this.gatheredViews = value;
+    }
 
-        /**
-         * Gets the value of the id property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getId() {
-            return id;
-        }
+    /**
+     * Gets the value of the textCol1 property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getTextCol1()
+    {
+      return textCol1;
+    }
 
-        /**
-         * Sets the value of the id property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setId(String value) {
-            this.id = value;
-        }
+    /**
+     * Sets the value of the textCol1 property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setTextCol1(Integer value)
+    {
+      this.textCol1 = value;
+    }
 
-        /**
-         * Gets the value of the complementId property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getComplementId() {
-            return complementId;
-        }
+    /**
+     * Gets the value of the textCol2 property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getTextCol2()
+    {
+      return textCol2;
+    }
 
-        /**
-         * Sets the value of the complementId property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setComplementId(String value) {
-            this.complementId = value;
-        }
+    /**
+     * Sets the value of the textCol2 property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setTextCol2(Integer value)
+    {
+      this.textCol2 = value;
+    }
 
-        /**
-         * Gets the value of the showComplementFeatures property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isShowComplementFeatures() {
-            if (showComplementFeatures == null) {
-                return false;
-            } else {
-                return showComplementFeatures;
-            }
-        }
+    /**
+     * Gets the value of the textColThreshold property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getTextColThreshold()
+    {
+      return textColThreshold;
+    }
 
-        /**
-         * Sets the value of the showComplementFeatures property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowComplementFeatures(Boolean value) {
-            this.showComplementFeatures = value;
-        }
+    /**
+     * Sets the value of the textColThreshold property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setTextColThreshold(Integer value)
+    {
+      this.textColThreshold = value;
+    }
 
-        /**
-         * Gets the value of the showComplementFeaturesOnTop property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isShowComplementFeaturesOnTop() {
-            if (showComplementFeaturesOnTop == null) {
-                return false;
-            } else {
-                return showComplementFeaturesOnTop;
-            }
-        }
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getId()
+    {
+      return id;
+    }
 
-        /**
-         * Sets the value of the showComplementFeaturesOnTop property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setShowComplementFeaturesOnTop(Boolean value) {
-            this.showComplementFeaturesOnTop = value;
-        }
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setId(String value)
+    {
+      this.id = value;
+    }
 
-        /**
-         * Gets the value of the width property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getWidth() {
-            return width;
-        }
+    /**
+     * Gets the value of the complementId property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getComplementId()
+    {
+      return complementId;
+    }
 
-        /**
-         * Sets the value of the width property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setWidth(Integer value) {
-            this.width = value;
-        }
+    /**
+     * Sets the value of the complementId property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setComplementId(String value)
+    {
+      this.complementId = value;
+    }
 
-        /**
-         * Gets the value of the height property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getHeight() {
-            return height;
-        }
+    /**
+     * Gets the value of the showComplementFeatures property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowComplementFeatures()
+    {
+      if (showComplementFeatures == null)
+      {
+        return false;
+      }
+      else
+      {
+        return showComplementFeatures;
+      }
+    }
 
-        /**
-         * Sets the value of the height property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setHeight(Integer value) {
-            this.height = value;
-        }
+    /**
+     * Sets the value of the showComplementFeatures property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowComplementFeatures(Boolean value)
+    {
+      this.showComplementFeatures = value;
+    }
 
-        /**
-         * Gets the value of the xpos property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getXpos() {
-            return xpos;
-        }
+    /**
+     * Gets the value of the showComplementFeaturesOnTop property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isShowComplementFeaturesOnTop()
+    {
+      if (showComplementFeaturesOnTop == null)
+      {
+        return false;
+      }
+      else
+      {
+        return showComplementFeaturesOnTop;
+      }
+    }
 
-        /**
-         * Sets the value of the xpos property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setXpos(Integer value) {
-            this.xpos = value;
-        }
+    /**
+     * Sets the value of the showComplementFeaturesOnTop property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setShowComplementFeaturesOnTop(Boolean value)
+    {
+      this.showComplementFeaturesOnTop = value;
+    }
 
-        /**
-         * Gets the value of the ypos property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Integer }
-         *     
-         */
-        public Integer getYpos() {
-            return ypos;
-        }
+    /**
+     * Gets the value of the width property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getWidth()
+    {
+      return width;
+    }
 
-        /**
-         * Sets the value of the ypos property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Integer }
-         *     
-         */
-        public void setYpos(Integer value) {
-            this.ypos = value;
-        }
+    /**
+     * Sets the value of the width property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setWidth(Integer value)
+    {
+      this.width = value;
+    }
 
+    /**
+     * Gets the value of the height property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getHeight()
+    {
+      return height;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;extension base="{www.jalview.org/xml/wsparamset}WebServiceParameterSet">
-         *       &lt;attribute name="calcId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="needsUpdate" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-         *       &lt;attribute name="autoUpdate" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-         *     &lt;/extension>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class CalcIdParam
-            extends WebServiceParameterSet
-        {
+    /**
+     * Sets the value of the height property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setHeight(Integer value)
+    {
+      this.height = value;
+    }
 
-            @XmlAttribute(name = "calcId", required = true)
-            protected String calcId;
-            @XmlAttribute(name = "needsUpdate")
-            protected Boolean needsUpdate;
-            @XmlAttribute(name = "autoUpdate", required = true)
-            protected boolean autoUpdate;
-
-            /**
-             * Gets the value of the calcId property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getCalcId() {
-                return calcId;
-            }
-
-            /**
-             * Sets the value of the calcId property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setCalcId(String value) {
-                this.calcId = value;
-            }
-
-            /**
-             * Gets the value of the needsUpdate property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Boolean }
-             *     
-             */
-            public boolean isNeedsUpdate() {
-                if (needsUpdate == null) {
-                    return false;
-                } else {
-                    return needsUpdate;
-                }
-            }
-
-            /**
-             * Sets the value of the needsUpdate property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Boolean }
-             *     
-             */
-            public void setNeedsUpdate(Boolean value) {
-                this.needsUpdate = value;
-            }
-
-            /**
-             * Gets the value of the autoUpdate property.
-             * 
-             */
-            public boolean isAutoUpdate() {
-                return autoUpdate;
-            }
-
-            /**
-             * Sets the value of the autoUpdate property.
-             * 
-             */
-            public void setAutoUpdate(boolean value) {
-                this.autoUpdate = value;
-            }
+    /**
+     * Gets the value of the xpos property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getXpos()
+    {
+      return xpos;
+    }
 
-        }
+    /**
+     * Sets the value of the xpos property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setXpos(Integer value)
+    {
+      this.xpos = value;
+    }
 
+    /**
+     * Gets the value of the ypos property.
+     * 
+     * @return possible object is {@link Integer }
+     * 
+     */
+    public Integer getYpos()
+    {
+      return ypos;
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attribute name="start" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *       &lt;attribute name="end" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class HiddenColumns {
-
-            @XmlAttribute(name = "start")
-            protected Integer start;
-            @XmlAttribute(name = "end")
-            protected Integer end;
-
-            /**
-             * Gets the value of the start property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getStart() {
-                return start;
-            }
-
-            /**
-             * Sets the value of the start property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setStart(Integer value) {
-                this.start = value;
-            }
-
-            /**
-             * Gets the value of the end property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getEnd() {
-                return end;
-            }
-
-            /**
-             * Sets the value of the end property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setEnd(Integer value) {
-                this.end = value;
-            }
+    /**
+     * Sets the value of the ypos property.
+     * 
+     * @param value
+     *          allowed object is {@link Integer }
+     * 
+     */
+    public void setYpos(Integer value)
+    {
+      this.ypos = value;
+    }
 
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;extension base="{www.jalview.org/xml/wsparamset}WebServiceParameterSet">
+     *       &lt;attribute name="calcId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="needsUpdate" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+     *       &lt;attribute name="autoUpdate" use="required" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *     &lt;/extension>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class CalcIdParam extends WebServiceParameterSet
+    {
+
+      @XmlAttribute(name = "calcId", required = true)
+      protected String calcId;
+
+      @XmlAttribute(name = "needsUpdate")
+      protected Boolean needsUpdate;
+
+      @XmlAttribute(name = "autoUpdate", required = true)
+      protected boolean autoUpdate;
+
+      /**
+       * Gets the value of the calcId property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getCalcId()
+      {
+        return calcId;
+      }
+
+      /**
+       * Sets the value of the calcId property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setCalcId(String value)
+      {
+        this.calcId = value;
+      }
+
+      /**
+       * Gets the value of the needsUpdate property.
+       * 
+       * @return possible object is {@link Boolean }
+       * 
+       */
+      public boolean isNeedsUpdate()
+      {
+        if (needsUpdate == null)
+        {
+          return false;
         }
+        else
+        {
+          return needsUpdate;
+        }
+      }
+
+      /**
+       * Sets the value of the needsUpdate property.
+       * 
+       * @param value
+       *          allowed object is {@link Boolean }
+       * 
+       */
+      public void setNeedsUpdate(Boolean value)
+      {
+        this.needsUpdate = value;
+      }
+
+      /**
+       * Gets the value of the autoUpdate property.
+       * 
+       */
+      public boolean isAutoUpdate()
+      {
+        return autoUpdate;
+      }
+
+      /**
+       * Sets the value of the autoUpdate property.
+       * 
+       */
+      public void setAutoUpdate(boolean value)
+      {
+        this.autoUpdate = value;
+      }
 
+    }
 
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
-         *       &lt;attribute name="showHidden" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-         *       &lt;attribute name="residueColour" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *       &lt;attribute name="gapColour" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *       &lt;attribute name="hiddenColour" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class Overview {
-
-            @XmlAttribute(name = "showHidden")
-            protected Boolean showHidden;
-            @XmlAttribute(name = "residueColour")
-            protected Integer residueColour;
-            @XmlAttribute(name = "gapColour")
-            protected Integer gapColour;
-            @XmlAttribute(name = "hiddenColour")
-            protected Integer hiddenColour;
-            @XmlAttribute(name = "title")
-            protected String title;
-            @XmlAttribute(name = "width")
-            protected Integer width;
-            @XmlAttribute(name = "height")
-            protected Integer height;
-            @XmlAttribute(name = "xpos")
-            protected Integer xpos;
-            @XmlAttribute(name = "ypos")
-            protected Integer ypos;
-
-            /**
-             * Gets the value of the showHidden property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Boolean }
-             *     
-             */
-            public Boolean isShowHidden() {
-                return showHidden;
-            }
-
-            /**
-             * Sets the value of the showHidden property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Boolean }
-             *     
-             */
-            public void setShowHidden(Boolean value) {
-                this.showHidden = value;
-            }
-
-            /**
-             * Gets the value of the residueColour property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getResidueColour() {
-                return residueColour;
-            }
-
-            /**
-             * Sets the value of the residueColour property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setResidueColour(Integer value) {
-                this.residueColour = value;
-            }
-
-            /**
-             * Gets the value of the gapColour property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getGapColour() {
-                return gapColour;
-            }
-
-            /**
-             * Sets the value of the gapColour property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setGapColour(Integer value) {
-                this.gapColour = value;
-            }
-
-            /**
-             * Gets the value of the hiddenColour property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getHiddenColour() {
-                return hiddenColour;
-            }
-
-            /**
-             * Sets the value of the hiddenColour property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setHiddenColour(Integer value) {
-                this.hiddenColour = value;
-            }
-
-            /**
-             * Gets the value of the title property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getTitle() {
-                return title;
-            }
-
-            /**
-             * Sets the value of the title property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setTitle(String value) {
-                this.title = value;
-            }
-
-            /**
-             * Gets the value of the width property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getWidth() {
-                return width;
-            }
-
-            /**
-             * Sets the value of the width property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setWidth(Integer value) {
-                this.width = value;
-            }
-
-            /**
-             * Gets the value of the height property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getHeight() {
-                return height;
-            }
-
-            /**
-             * Sets the value of the height property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setHeight(Integer value) {
-                this.height = value;
-            }
-
-            /**
-             * Gets the value of the xpos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getXpos() {
-                return xpos;
-            }
-
-            /**
-             * Sets the value of the xpos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setXpos(Integer value) {
-                this.xpos = value;
-            }
-
-            /**
-             * Gets the value of the ypos property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getYpos() {
-                return ypos;
-            }
-
-            /**
-             * Sets the value of the ypos property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setYpos(Integer value) {
-                this.ypos = value;
-            }
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="start" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *       &lt;attribute name="end" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class HiddenColumns
+    {
+
+      @XmlAttribute(name = "start")
+      protected Integer start;
+
+      @XmlAttribute(name = "end")
+      protected Integer end;
+
+      /**
+       * Gets the value of the start property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getStart()
+      {
+        return start;
+      }
+
+      /**
+       * Sets the value of the start property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setStart(Integer value)
+      {
+        this.start = value;
+      }
+
+      /**
+       * Gets the value of the end property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getEnd()
+      {
+        return end;
+      }
+
+      /**
+       * Sets the value of the end property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setEnd(Integer value)
+      {
+        this.end = value;
+      }
 
-        }
+    }
+
+    /**
+     * <p>
+     * Java class for anonymous complex type.
+     * 
+     * <p>
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attGroup ref="{www.jalview.org}swingwindow"/>
+     *       &lt;attribute name="showHidden" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+     *       &lt;attribute name="residueColour" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *       &lt;attribute name="gapColour" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *       &lt;attribute name="hiddenColour" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *       &lt;attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Overview
+    {
+
+      @XmlAttribute(name = "showHidden")
+      protected Boolean showHidden;
+
+      @XmlAttribute(name = "residueColour")
+      protected Integer residueColour;
+
+      @XmlAttribute(name = "gapColour")
+      protected Integer gapColour;
+
+      @XmlAttribute(name = "hiddenColour")
+      protected Integer hiddenColour;
+
+      @XmlAttribute(name = "title")
+      protected String title;
+
+      @XmlAttribute(name = "width")
+      protected Integer width;
+
+      @XmlAttribute(name = "height")
+      protected Integer height;
+
+      @XmlAttribute(name = "xpos")
+      protected Integer xpos;
+
+      @XmlAttribute(name = "ypos")
+      protected Integer ypos;
+
+      /**
+       * Gets the value of the showHidden property.
+       * 
+       * @return possible object is {@link Boolean }
+       * 
+       */
+      public Boolean isShowHidden()
+      {
+        return showHidden;
+      }
+
+      /**
+       * Sets the value of the showHidden property.
+       * 
+       * @param value
+       *          allowed object is {@link Boolean }
+       * 
+       */
+      public void setShowHidden(Boolean value)
+      {
+        this.showHidden = value;
+      }
+
+      /**
+       * Gets the value of the residueColour property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getResidueColour()
+      {
+        return residueColour;
+      }
+
+      /**
+       * Sets the value of the residueColour property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setResidueColour(Integer value)
+      {
+        this.residueColour = value;
+      }
+
+      /**
+       * Gets the value of the gapColour property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getGapColour()
+      {
+        return gapColour;
+      }
+
+      /**
+       * Sets the value of the gapColour property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setGapColour(Integer value)
+      {
+        this.gapColour = value;
+      }
+
+      /**
+       * Gets the value of the hiddenColour property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getHiddenColour()
+      {
+        return hiddenColour;
+      }
+
+      /**
+       * Sets the value of the hiddenColour property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setHiddenColour(Integer value)
+      {
+        this.hiddenColour = value;
+      }
+
+      /**
+       * Gets the value of the title property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getTitle()
+      {
+        return title;
+      }
+
+      /**
+       * Sets the value of the title property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setTitle(String value)
+      {
+        this.title = value;
+      }
+
+      /**
+       * Gets the value of the width property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getWidth()
+      {
+        return width;
+      }
+
+      /**
+       * Sets the value of the width property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setWidth(Integer value)
+      {
+        this.width = value;
+      }
+
+      /**
+       * Gets the value of the height property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getHeight()
+      {
+        return height;
+      }
+
+      /**
+       * Sets the value of the height property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setHeight(Integer value)
+      {
+        this.height = value;
+      }
+
+      /**
+       * Gets the value of the xpos property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getXpos()
+      {
+        return xpos;
+      }
+
+      /**
+       * Sets the value of the xpos property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setXpos(Integer value)
+      {
+        this.xpos = value;
+      }
+
+      /**
+       * Gets the value of the ypos property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getYpos()
+      {
+        return ypos;
+      }
+
+      /**
+       * Sets the value of the ypos property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setYpos(Integer value)
+      {
+        this.ypos = value;
+      }
 
     }
 
+  }
+
 }
index b62cf15..e4b160f 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for JalviewUserColours complex type.
+ * <p>
+ * Java class for JalviewUserColours complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="JalviewUserColours">
@@ -71,542 +72,556 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "JalviewUserColours", namespace = "www.jalview.org/colours", propOrder = {
-    "version",
-    "colour",
-    "filter"
-})
-public class JalviewUserColours {
-
-    @XmlElement(name = "Version", namespace = "")
-    protected String version;
-    @XmlElement(namespace = "")
-    protected List<JalviewUserColours.Colour> colour;
+@XmlType(
+  name = "JalviewUserColours",
+  namespace = "www.jalview.org/colours",
+  propOrder =
+  { "version", "colour", "filter" })
+public class JalviewUserColours
+{
+
+  @XmlElement(name = "Version", namespace = "")
+  protected String version;
+
+  @XmlElement(namespace = "")
+  protected List<JalviewUserColours.Colour> colour;
+
+  @XmlElement(namespace = "")
+  protected List<JalviewUserColours.Filter> filter;
+
+  @XmlAttribute(name = "schemeName")
+  protected String schemeName;
+
+  /**
+   * Gets the value of the version property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getVersion()
+  {
+    return version;
+  }
+
+  /**
+   * Sets the value of the version property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setVersion(String value)
+  {
+    this.version = value;
+  }
+
+  /**
+   * Gets the value of the colour property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the colour property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getColour().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link JalviewUserColours.Colour }
+   * 
+   * 
+   */
+  public List<JalviewUserColours.Colour> getColour()
+  {
+    if (colour == null)
+    {
+      colour = new ArrayList<JalviewUserColours.Colour>();
+    }
+    return this.colour;
+  }
+
+  /**
+   * Gets the value of the filter property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the filter property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getFilter().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link JalviewUserColours.Filter }
+   * 
+   * 
+   */
+  public List<JalviewUserColours.Filter> getFilter()
+  {
+    if (filter == null)
+    {
+      filter = new ArrayList<JalviewUserColours.Filter>();
+    }
+    return this.filter;
+  }
+
+  /**
+   * Gets the value of the schemeName property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getSchemeName()
+  {
+    return schemeName;
+  }
+
+  /**
+   * Sets the value of the schemeName property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setSchemeName(String value)
+  {
+    this.schemeName = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="attributeName" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="2" minOccurs="0"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="Name" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="RGB" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="minRGB" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="noValueColour" type="{www.jalview.org/colours}NoValueColour" default="Min" />
+   *       &lt;attribute name="threshType" type="{www.jalview.org/colours}ThresholdType" />
+   *       &lt;attribute name="threshold" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *       &lt;attribute name="max" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *       &lt;attribute name="min" type="{http://www.w3.org/2001/XMLSchema}float" />
+   *       &lt;attribute name="colourByLabel" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *       &lt;attribute name="autoScale" type="{http://www.w3.org/2001/XMLSchema}boolean" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "attributeName" })
+  public static class Colour
+  {
+
     @XmlElement(namespace = "")
-    protected List<JalviewUserColours.Filter> filter;
-    @XmlAttribute(name = "schemeName")
-    protected String schemeName;
+    protected List<String> attributeName;
+
+    @XmlAttribute(name = "Name")
+    protected String name;
+
+    @XmlAttribute(name = "RGB", required = true)
+    protected String rgb;
+
+    @XmlAttribute(name = "minRGB")
+    protected String minRGB;
+
+    @XmlAttribute(name = "noValueColour")
+    protected NoValueColour noValueColour;
+
+    @XmlAttribute(name = "threshType")
+    protected ThresholdType threshType;
+
+    @XmlAttribute(name = "threshold")
+    protected Float threshold;
+
+    @XmlAttribute(name = "max")
+    protected Float max;
+
+    @XmlAttribute(name = "min")
+    protected Float min;
+
+    @XmlAttribute(name = "colourByLabel")
+    protected Boolean colourByLabel;
+
+    @XmlAttribute(name = "autoScale")
+    protected Boolean autoScale;
 
     /**
-     * Gets the value of the version property.
+     * Gets the value of the attributeName property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the attributeName property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getAttributeName().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link String }
+     * 
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getVersion() {
-        return version;
+    public List<String> getAttributeName()
+    {
+      if (attributeName == null)
+      {
+        attributeName = new ArrayList<String>();
+      }
+      return this.attributeName;
     }
 
     /**
-     * Sets the value of the version property.
+     * Gets the value of the name property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getName()
+    {
+      return name;
+    }
+
+    /**
+     * Sets the value of the name property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *          allowed object is {@link String }
+     * 
      */
-    public void setVersion(String value) {
-        this.version = value;
+    public void setName(String value)
+    {
+      this.name = value;
     }
 
     /**
-     * Gets the value of the colour property.
+     * Gets the value of the rgb property.
      * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the colour property.
+     * @return possible object is {@link String }
      * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getColour().add(newItem);
-     * </pre>
+     */
+    public String getRGB()
+    {
+      return rgb;
+    }
+
+    /**
+     * Sets the value of the rgb property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link JalviewUserColours.Colour }
+     */
+    public void setRGB(String value)
+    {
+      this.rgb = value;
+    }
+
+    /**
+     * Gets the value of the minRGB property.
      * 
+     * @return possible object is {@link String }
      * 
      */
-    public List<JalviewUserColours.Colour> getColour() {
-        if (colour == null) {
-            colour = new ArrayList<JalviewUserColours.Colour>();
-        }
-        return this.colour;
+    public String getMinRGB()
+    {
+      return minRGB;
     }
 
     /**
-     * Gets the value of the filter property.
+     * Sets the value of the minRGB property.
      * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the filter property.
+     * @param value
+     *          allowed object is {@link String }
      * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getFilter().add(newItem);
-     * </pre>
+     */
+    public void setMinRGB(String value)
+    {
+      this.minRGB = value;
+    }
+
+    /**
+     * Gets the value of the noValueColour property.
      * 
+     * @return possible object is {@link NoValueColour }
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link JalviewUserColours.Filter }
+     */
+    public NoValueColour getNoValueColour()
+    {
+      if (noValueColour == null)
+      {
+        return NoValueColour.MIN;
+      }
+      else
+      {
+        return noValueColour;
+      }
+    }
+
+    /**
+     * Sets the value of the noValueColour property.
      * 
+     * @param value
+     *          allowed object is {@link NoValueColour }
      * 
      */
-    public List<JalviewUserColours.Filter> getFilter() {
-        if (filter == null) {
-            filter = new ArrayList<JalviewUserColours.Filter>();
-        }
-        return this.filter;
+    public void setNoValueColour(NoValueColour value)
+    {
+      this.noValueColour = value;
     }
 
     /**
-     * Gets the value of the schemeName property.
+     * Gets the value of the threshType property.
+     * 
+     * @return possible object is {@link ThresholdType }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getSchemeName() {
-        return schemeName;
+    public ThresholdType getThreshType()
+    {
+      return threshType;
     }
 
     /**
-     * Sets the value of the schemeName property.
+     * Sets the value of the threshType property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *          allowed object is {@link ThresholdType }
+     * 
      */
-    public void setSchemeName(String value) {
-        this.schemeName = value;
+    public void setThreshType(ThresholdType value)
+    {
+      this.threshType = value;
     }
 
+    /**
+     * Gets the value of the threshold property.
+     * 
+     * @return possible object is {@link Float }
+     * 
+     */
+    public Float getThreshold()
+    {
+      return threshold;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Sets the value of the threshold property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @param value
+     *          allowed object is {@link Float }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="attributeName" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="2" minOccurs="0"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="Name" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="RGB" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="minRGB" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="noValueColour" type="{www.jalview.org/colours}NoValueColour" default="Min" />
-     *       &lt;attribute name="threshType" type="{www.jalview.org/colours}ThresholdType" />
-     *       &lt;attribute name="threshold" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *       &lt;attribute name="max" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *       &lt;attribute name="min" type="{http://www.w3.org/2001/XMLSchema}float" />
-     *       &lt;attribute name="colourByLabel" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *       &lt;attribute name="autoScale" type="{http://www.w3.org/2001/XMLSchema}boolean" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public void setThreshold(Float value)
+    {
+      this.threshold = value;
+    }
+
+    /**
+     * Gets the value of the max property.
+     * 
+     * @return possible object is {@link Float }
+     * 
+     */
+    public Float getMax()
+    {
+      return max;
+    }
+
+    /**
+     * Sets the value of the max property.
+     * 
+     * @param value
+     *          allowed object is {@link Float }
+     * 
+     */
+    public void setMax(Float value)
+    {
+      this.max = value;
+    }
+
+    /**
+     * Gets the value of the min property.
      * 
+     * @return possible object is {@link Float }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "attributeName"
-    })
-    public static class Colour {
-
-        @XmlElement(namespace = "")
-        protected List<String> attributeName;
-        @XmlAttribute(name = "Name")
-        protected String name;
-        @XmlAttribute(name = "RGB", required = true)
-        protected String rgb;
-        @XmlAttribute(name = "minRGB")
-        protected String minRGB;
-        @XmlAttribute(name = "noValueColour")
-        protected NoValueColour noValueColour;
-        @XmlAttribute(name = "threshType")
-        protected ThresholdType threshType;
-        @XmlAttribute(name = "threshold")
-        protected Float threshold;
-        @XmlAttribute(name = "max")
-        protected Float max;
-        @XmlAttribute(name = "min")
-        protected Float min;
-        @XmlAttribute(name = "colourByLabel")
-        protected Boolean colourByLabel;
-        @XmlAttribute(name = "autoScale")
-        protected Boolean autoScale;
-
-        /**
-         * Gets the value of the attributeName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the attributeName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getAttributeName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link String }
-         * 
-         * 
-         */
-        public List<String> getAttributeName() {
-            if (attributeName == null) {
-                attributeName = new ArrayList<String>();
-            }
-            return this.attributeName;
-        }
-
-        /**
-         * Gets the value of the name property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Sets the value of the name property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setName(String value) {
-            this.name = value;
-        }
-
-        /**
-         * Gets the value of the rgb property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getRGB() {
-            return rgb;
-        }
-
-        /**
-         * Sets the value of the rgb property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setRGB(String value) {
-            this.rgb = value;
-        }
-
-        /**
-         * Gets the value of the minRGB property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getMinRGB() {
-            return minRGB;
-        }
-
-        /**
-         * Sets the value of the minRGB property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setMinRGB(String value) {
-            this.minRGB = value;
-        }
-
-        /**
-         * Gets the value of the noValueColour property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link NoValueColour }
-         *     
-         */
-        public NoValueColour getNoValueColour() {
-            if (noValueColour == null) {
-                return NoValueColour.MIN;
-            } else {
-                return noValueColour;
-            }
-        }
-
-        /**
-         * Sets the value of the noValueColour property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link NoValueColour }
-         *     
-         */
-        public void setNoValueColour(NoValueColour value) {
-            this.noValueColour = value;
-        }
-
-        /**
-         * Gets the value of the threshType property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link ThresholdType }
-         *     
-         */
-        public ThresholdType getThreshType() {
-            return threshType;
-        }
-
-        /**
-         * Sets the value of the threshType property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link ThresholdType }
-         *     
-         */
-        public void setThreshType(ThresholdType value) {
-            this.threshType = value;
-        }
-
-        /**
-         * Gets the value of the threshold property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Float }
-         *     
-         */
-        public Float getThreshold() {
-            return threshold;
-        }
-
-        /**
-         * Sets the value of the threshold property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Float }
-         *     
-         */
-        public void setThreshold(Float value) {
-            this.threshold = value;
-        }
-
-        /**
-         * Gets the value of the max property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Float }
-         *     
-         */
-        public Float getMax() {
-            return max;
-        }
-
-        /**
-         * Sets the value of the max property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Float }
-         *     
-         */
-        public void setMax(Float value) {
-            this.max = value;
-        }
-
-        /**
-         * Gets the value of the min property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Float }
-         *     
-         */
-        public Float getMin() {
-            return min;
-        }
-
-        /**
-         * Sets the value of the min property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Float }
-         *     
-         */
-        public void setMin(Float value) {
-            this.min = value;
-        }
-
-        /**
-         * Gets the value of the colourByLabel property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isColourByLabel() {
-            return colourByLabel;
-        }
-
-        /**
-         * Sets the value of the colourByLabel property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setColourByLabel(Boolean value) {
-            this.colourByLabel = value;
-        }
-
-        /**
-         * Gets the value of the autoScale property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public Boolean isAutoScale() {
-            return autoScale;
-        }
-
-        /**
-         * Sets the value of the autoScale property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setAutoScale(Boolean value) {
-            this.autoScale = value;
-        }
+    public Float getMin()
+    {
+      return min;
+    }
 
+    /**
+     * Sets the value of the min property.
+     * 
+     * @param value
+     *          allowed object is {@link Float }
+     * 
+     */
+    public void setMin(Float value)
+    {
+      this.min = value;
     }
 
+    /**
+     * Gets the value of the colourByLabel property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isColourByLabel()
+    {
+      return colourByLabel;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Sets the value of the colourByLabel property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @param value
+     *          allowed object is {@link Boolean }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="matcherSet" type="{www.jalview.org/colours}FeatureMatcherSet"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="featureType" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public void setColourByLabel(Boolean value)
+    {
+      this.colourByLabel = value;
+    }
+
+    /**
+     * Gets the value of the autoScale property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public Boolean isAutoScale()
+    {
+      return autoScale;
+    }
+
+    /**
+     * Sets the value of the autoScale property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setAutoScale(Boolean value)
+    {
+      this.autoScale = value;
+    }
+
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="matcherSet" type="{www.jalview.org/colours}FeatureMatcherSet"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="featureType" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "matcherSet" })
+  public static class Filter
+  {
+
+    @XmlElement(namespace = "", required = true)
+    protected FeatureMatcherSet matcherSet;
+
+    @XmlAttribute(name = "featureType", required = true)
+    protected String featureType;
+
+    /**
+     * Gets the value of the matcherSet property.
+     * 
+     * @return possible object is {@link FeatureMatcherSet }
+     * 
+     */
+    public FeatureMatcherSet getMatcherSet()
+    {
+      return matcherSet;
+    }
+
+    /**
+     * Sets the value of the matcherSet property.
+     * 
+     * @param value
+     *          allowed object is {@link FeatureMatcherSet }
+     * 
+     */
+    public void setMatcherSet(FeatureMatcherSet value)
+    {
+      this.matcherSet = value;
+    }
+
+    /**
+     * Gets the value of the featureType property.
      * 
+     * @return possible object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "matcherSet"
-    })
-    public static class Filter {
-
-        @XmlElement(namespace = "", required = true)
-        protected FeatureMatcherSet matcherSet;
-        @XmlAttribute(name = "featureType", required = true)
-        protected String featureType;
-
-        /**
-         * Gets the value of the matcherSet property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link FeatureMatcherSet }
-         *     
-         */
-        public FeatureMatcherSet getMatcherSet() {
-            return matcherSet;
-        }
-
-        /**
-         * Sets the value of the matcherSet property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link FeatureMatcherSet }
-         *     
-         */
-        public void setMatcherSet(FeatureMatcherSet value) {
-            this.matcherSet = value;
-        }
-
-        /**
-         * Gets the value of the featureType property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getFeatureType() {
-            return featureType;
-        }
-
-        /**
-         * Sets the value of the featureType property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setFeatureType(String value) {
-            this.featureType = value;
-        }
+    public String getFeatureType()
+    {
+      return featureType;
+    }
 
+    /**
+     * Sets the value of the featureType property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setFeatureType(String value)
+    {
+      this.featureType = value;
     }
 
+  }
+
 }
index 7a86123..1f16680 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.math.BigInteger;
@@ -18,15 +17,17 @@ import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * 
- *                             This effectively represents a java.util.MapList object
- *                     
+ * This effectively represents a java.util.MapList object
  * 
- * <p>Java class for mapListType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * Java class for mapListType complex type.
+ * 
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="mapListType">
@@ -64,252 +65,271 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "mapListType", propOrder = {
-    "mapListFrom",
-    "mapListTo"
-})
-@XmlSeeAlso({
-    Mapping.class
-})
-public class MapListType {
+@XmlType(name = "mapListType", propOrder = { "mapListFrom", "mapListTo" })
+@XmlSeeAlso({ Mapping.class })
+public class MapListType
+{
+
+  protected List<MapListType.MapListFrom> mapListFrom;
+
+  protected List<MapListType.MapListTo> mapListTo;
+
+  @XmlAttribute(name = "mapFromUnit", required = true)
+  @XmlSchemaType(name = "positiveInteger")
+  protected BigInteger mapFromUnit;
+
+  @XmlAttribute(name = "mapToUnit", required = true)
+  @XmlSchemaType(name = "positiveInteger")
+  protected BigInteger mapToUnit;
+
+  /**
+   * Gets the value of the mapListFrom property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the mapListFrom property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getMapListFrom().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link MapListType.MapListFrom }
+   * 
+   * 
+   */
+  public List<MapListType.MapListFrom> getMapListFrom()
+  {
+    if (mapListFrom == null)
+    {
+      mapListFrom = new ArrayList<MapListType.MapListFrom>();
+    }
+    return this.mapListFrom;
+  }
+
+  /**
+   * Gets the value of the mapListTo property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the mapListTo property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getMapListTo().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link MapListType.MapListTo }
+   * 
+   * 
+   */
+  public List<MapListType.MapListTo> getMapListTo()
+  {
+    if (mapListTo == null)
+    {
+      mapListTo = new ArrayList<MapListType.MapListTo>();
+    }
+    return this.mapListTo;
+  }
+
+  /**
+   * Gets the value of the mapFromUnit property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getMapFromUnit()
+  {
+    return mapFromUnit;
+  }
+
+  /**
+   * Sets the value of the mapFromUnit property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setMapFromUnit(BigInteger value)
+  {
+    this.mapFromUnit = value;
+  }
 
-    protected List<MapListType.MapListFrom> mapListFrom;
-    protected List<MapListType.MapListTo> mapListTo;
-    @XmlAttribute(name = "mapFromUnit", required = true)
-    @XmlSchemaType(name = "positiveInteger")
-    protected BigInteger mapFromUnit;
-    @XmlAttribute(name = "mapToUnit", required = true)
-    @XmlSchemaType(name = "positiveInteger")
-    protected BigInteger mapToUnit;
+  /**
+   * Gets the value of the mapToUnit property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getMapToUnit()
+  {
+    return mapToUnit;
+  }
+
+  /**
+   * Sets the value of the mapToUnit property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setMapToUnit(BigInteger value)
+  {
+    this.mapToUnit = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="start" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class MapListFrom
+  {
+
+    @XmlAttribute(name = "start", required = true)
+    protected int start;
+
+    @XmlAttribute(name = "end", required = true)
+    protected int end;
 
     /**
-     * Gets the value of the mapListFrom property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the mapListFrom property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getMapListFrom().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link MapListType.MapListFrom }
-     * 
+     * Gets the value of the start property.
      * 
      */
-    public List<MapListType.MapListFrom> getMapListFrom() {
-        if (mapListFrom == null) {
-            mapListFrom = new ArrayList<MapListType.MapListFrom>();
-        }
-        return this.mapListFrom;
+    public int getStart()
+    {
+      return start;
     }
 
     /**
-     * Gets the value of the mapListTo property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the mapListTo property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getMapListTo().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link MapListType.MapListTo }
-     * 
+     * Sets the value of the start property.
      * 
      */
-    public List<MapListType.MapListTo> getMapListTo() {
-        if (mapListTo == null) {
-            mapListTo = new ArrayList<MapListType.MapListTo>();
-        }
-        return this.mapListTo;
+    public void setStart(int value)
+    {
+      this.start = value;
     }
 
     /**
-     * Gets the value of the mapFromUnit property.
+     * Gets the value of the end property.
      * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
      */
-    public BigInteger getMapFromUnit() {
-        return mapFromUnit;
+    public int getEnd()
+    {
+      return end;
     }
 
     /**
-     * Sets the value of the mapFromUnit property.
+     * Sets the value of the end property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
      */
-    public void setMapFromUnit(BigInteger value) {
-        this.mapFromUnit = value;
+    public void setEnd(int value)
+    {
+      this.end = value;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="start" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class MapListTo
+  {
+
+    @XmlAttribute(name = "start", required = true)
+    protected int start;
+
+    @XmlAttribute(name = "end", required = true)
+    protected int end;
+
     /**
-     * Gets the value of the mapToUnit property.
+     * Gets the value of the start property.
      * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
      */
-    public BigInteger getMapToUnit() {
-        return mapToUnit;
+    public int getStart()
+    {
+      return start;
     }
 
     /**
-     * Sets the value of the mapToUnit property.
+     * Sets the value of the start property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
      */
-    public void setMapToUnit(BigInteger value) {
-        this.mapToUnit = value;
+    public void setStart(int value)
+    {
+      this.start = value;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="start" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
-     * 
+     * Gets the value of the end property.
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class MapListFrom {
-
-        @XmlAttribute(name = "start", required = true)
-        protected int start;
-        @XmlAttribute(name = "end", required = true)
-        protected int end;
-
-        /**
-         * Gets the value of the start property.
-         * 
-         */
-        public int getStart() {
-            return start;
-        }
-
-        /**
-         * Sets the value of the start property.
-         * 
-         */
-        public void setStart(int value) {
-            this.start = value;
-        }
-
-        /**
-         * Gets the value of the end property.
-         * 
-         */
-        public int getEnd() {
-            return end;
-        }
-
-        /**
-         * Sets the value of the end property.
-         * 
-         */
-        public void setEnd(int value) {
-            this.end = value;
-        }
-
+    public int getEnd()
+    {
+      return end;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="start" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *       &lt;attribute name="end" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
-     * 
+     * Sets the value of the end property.
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class MapListTo {
-
-        @XmlAttribute(name = "start", required = true)
-        protected int start;
-        @XmlAttribute(name = "end", required = true)
-        protected int end;
-
-        /**
-         * Gets the value of the start property.
-         * 
-         */
-        public int getStart() {
-            return start;
-        }
-
-        /**
-         * Sets the value of the start property.
-         * 
-         */
-        public void setStart(int value) {
-            this.start = value;
-        }
-
-        /**
-         * Gets the value of the end property.
-         * 
-         */
-        public int getEnd() {
-            return end;
-        }
-
-        /**
-         * Sets the value of the end property.
-         * 
-         */
-        public void setEnd(int value) {
-            this.end = value;
-        }
-
+    public void setEnd(int value)
+    {
+      this.end = value;
     }
 
+  }
+
 }
index 10d3d5b..69bf01d 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -15,17 +14,19 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * 
- *                                     Represent the jalview.datamodel.Mapping object - it also provides
- *                                     a way of storing sequences that are mapped 'to' without adding them
- *                                     to the sequence set (which will mean they are then added to the alignment too).
- *                             
+ * Represent the jalview.datamodel.Mapping object - it also provides a way of
+ * storing sequences that are mapped 'to' without adding them to the sequence
+ * set (which will mean they are then added to the alignment too).
+ * 
  * 
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -51,91 +52,86 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "sequence",
-    "dseqFor"
-})
+@XmlType(name = "", propOrder = { "sequence", "dseqFor" })
 @XmlRootElement(name = "Mapping")
-public class Mapping
-    extends MapListType
+public class Mapping extends MapListType
 {
 
-    @XmlElement(name = "Sequence")
-    protected Sequence sequence;
-    protected String dseqFor;
-    @XmlAttribute(name = "mappingType")
-    protected String mappingType;
+  @XmlElement(name = "Sequence")
+  protected Sequence sequence;
+
+  protected String dseqFor;
+
+  @XmlAttribute(name = "mappingType")
+  protected String mappingType;
 
-    /**
-     * Gets the value of the sequence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Sequence }
-     *     
-     */
-    public Sequence getSequence() {
-        return sequence;
-    }
+  /**
+   * Gets the value of the sequence property.
+   * 
+   * @return possible object is {@link Sequence }
+   * 
+   */
+  public Sequence getSequence()
+  {
+    return sequence;
+  }
 
-    /**
-     * Sets the value of the sequence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Sequence }
-     *     
-     */
-    public void setSequence(Sequence value) {
-        this.sequence = value;
-    }
+  /**
+   * Sets the value of the sequence property.
+   * 
+   * @param value
+   *          allowed object is {@link Sequence }
+   * 
+   */
+  public void setSequence(Sequence value)
+  {
+    this.sequence = value;
+  }
 
-    /**
-     * Gets the value of the dseqFor property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDseqFor() {
-        return dseqFor;
-    }
+  /**
+   * Gets the value of the dseqFor property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDseqFor()
+  {
+    return dseqFor;
+  }
 
-    /**
-     * Sets the value of the dseqFor property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDseqFor(String value) {
-        this.dseqFor = value;
-    }
+  /**
+   * Sets the value of the dseqFor property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDseqFor(String value)
+  {
+    this.dseqFor = value;
+  }
 
-    /**
-     * Gets the value of the mappingType property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getMappingType() {
-        return mappingType;
-    }
+  /**
+   * Gets the value of the mappingType property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getMappingType()
+  {
+    return mappingType;
+  }
 
-    /**
-     * Sets the value of the mappingType property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setMappingType(String value) {
-        this.mappingType = value;
-    }
+  /**
+   * Sets the value of the mappingType property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setMappingType(String value)
+  {
+    this.mappingType = value;
+  }
 
 }
index d884100..c405597 100644 (file)
@@ -2,7 +2,7 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
 
@@ -19,9 +19,12 @@ import javax.xml.bind.annotation.XmlType;
 
 
 /**
- * <p>Java class for MatrixType complex type.
+ * <p>
+ * Java class for MatrixType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="MatrixType">
@@ -32,6 +35,7 @@ import javax.xml.bind.annotation.XmlType;
  *         &lt;element name="groups" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
  *         &lt;element name="newick" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
  *         &lt;element name="property" type="{www.vamsas.ac.uk/jalview/version2}property" maxOccurs="unbounded" minOccurs="0"/>
+ *         &lt;element name="mapping" type="{www.vamsas.ac.uk/jalview/version2}mapListType" minOccurs="0"/>
  *       &lt;/sequence>
  *       &lt;attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
  *       &lt;attribute name="rows" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
@@ -47,285 +51,317 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "MatrixType", propOrder = {
-    "elements",
-    "groups",
-    "newick",
-    "property"
-})
-public class MatrixType {
-
-    @XmlElement(required = true)
-    protected String elements;
-    protected List<String> groups;
-    protected List<String> newick;
-    protected List<Property> property;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "rows", required = true)
-    protected BigInteger rows;
-    @XmlAttribute(name = "cols", required = true)
-    protected BigInteger cols;
-    @XmlAttribute(name = "treeMethod")
-    protected String treeMethod;
-    @XmlAttribute(name = "cutHeight")
-    protected Double cutHeight;
-    @XmlAttribute(name = "id")
-    protected String id;
-
-    /**
-     * Gets the value of the elements property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getElements() {
-        return elements;
-    }
+@XmlType(
+  name = "MatrixType",
+  propOrder =
+  { "elements", "groups", "newick", "property", "mapping" })
+public class MatrixType
+{
 
-    /**
-     * Sets the value of the elements property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setElements(String value) {
-        this.elements = value;
-    }
+  @XmlElement(required = true)
+  protected String elements;
 
-    /**
-     * Gets the value of the groups property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the groups property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getGroups().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getGroups() {
-        if (groups == null) {
-            groups = new ArrayList<String>();
-        }
-        return this.groups;
-    }
+  protected List<String> groups;
 
-    /**
-     * Gets the value of the newick property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the newick property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getNewick().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getNewick() {
-        if (newick == null) {
-            newick = new ArrayList<String>();
-        }
-        return this.newick;
-    }
+  protected List<String> newick;
 
-    /**
-     * Gets the value of the property property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the property property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getProperty().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Property }
-     * 
-     * 
-     */
-    public List<Property> getProperty() {
-        if (property == null) {
-            property = new ArrayList<Property>();
-        }
-        return this.property;
-    }
+  protected List<Property> property;
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  protected MapListType mapping;
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    /**
-     * Gets the value of the rows property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
-     */
-    public BigInteger getRows() {
-        return rows;
-    }
+  @XmlAttribute(name = "rows", required = true)
+  protected BigInteger rows;
 
-    /**
-     * Sets the value of the rows property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setRows(BigInteger value) {
-        this.rows = value;
-    }
+  @XmlAttribute(name = "cols", required = true)
+  protected BigInteger cols;
 
-    /**
-     * Gets the value of the cols property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
-     */
-    public BigInteger getCols() {
-        return cols;
-    }
+  @XmlAttribute(name = "treeMethod")
+  protected String treeMethod;
 
-    /**
-     * Sets the value of the cols property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setCols(BigInteger value) {
-        this.cols = value;
-    }
+  @XmlAttribute(name = "cutHeight")
+  protected Double cutHeight;
 
-    /**
-     * Gets the value of the treeMethod property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getTreeMethod() {
-        return treeMethod;
-    }
+  @XmlAttribute(name = "id")
+  protected String id;
 
-    /**
-     * Sets the value of the treeMethod property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setTreeMethod(String value) {
-        this.treeMethod = value;
-    }
+  /**
+   * Gets the value of the elements property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getElements()
+  {
+    return elements;
+  }
 
-    /**
-     * Gets the value of the cutHeight property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Double }
-     *     
-     */
-    public Double getCutHeight() {
-        return cutHeight;
-    }
+  /**
+   * Sets the value of the elements property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setElements(String value)
+  {
+    this.elements = value;
+  }
 
-    /**
-     * Sets the value of the cutHeight property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Double }
-     *     
-     */
-    public void setCutHeight(Double value) {
-        this.cutHeight = value;
+  /**
+   * Gets the value of the groups property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the groups property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getGroups().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getGroups()
+  {
+    if (groups == null)
+    {
+      groups = new ArrayList<String>();
     }
+    return this.groups;
+  }
 
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
+  /**
+   * Gets the value of the newick property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the newick property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getNewick().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getNewick()
+  {
+    if (newick == null)
+    {
+      newick = new ArrayList<String>();
     }
+    return this.newick;
+  }
 
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
+  /**
+   * Gets the value of the property property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the property property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getProperty().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Property }
+   * 
+   * 
+   */
+  public List<Property> getProperty()
+  {
+    if (property == null)
+    {
+      property = new ArrayList<Property>();
     }
+    return this.property;
+  }
+
+  /**
+   * Gets the value of the mapping property.
+   * 
+   * @return possible object is {@link MapListType }
+   * 
+   */
+  public MapListType getMapping()
+  {
+    return mapping;
+  }
+
+  /**
+   * Sets the value of the mapping property.
+   * 
+   * @param value
+   *          allowed object is {@link MapListType }
+   * 
+   */
+  public void setMapping(MapListType value)
+  {
+    this.mapping = value;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
+
+  /**
+   * Gets the value of the rows property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getRows()
+  {
+    return rows;
+  }
+
+  /**
+   * Sets the value of the rows property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setRows(BigInteger value)
+  {
+    this.rows = value;
+  }
+
+  /**
+   * Gets the value of the cols property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getCols()
+  {
+    return cols;
+  }
+
+  /**
+   * Sets the value of the cols property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setCols(BigInteger value)
+  {
+    this.cols = value;
+  }
+
+  /**
+   * Gets the value of the treeMethod property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getTreeMethod()
+  {
+    return treeMethod;
+  }
+
+  /**
+   * Sets the value of the treeMethod property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setTreeMethod(String value)
+  {
+    this.treeMethod = value;
+  }
+
+  /**
+   * Gets the value of the cutHeight property.
+   * 
+   * @return possible object is {@link Double }
+   * 
+   */
+  public Double getCutHeight()
+  {
+    return cutHeight;
+  }
+
+  /**
+   * Sets the value of the cutHeight property.
+   * 
+   * @param value
+   *          allowed object is {@link Double }
+   * 
+   */
+  public void setCutHeight(Double value)
+  {
+    this.cutHeight = value;
+  }
+
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
+
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
 
 }
index 22b78a5..eeeed22 100644 (file)
@@ -2,22 +2,24 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlEnum;
 import javax.xml.bind.annotation.XmlEnumValue;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for NoValueColour.
+ * <p>
+ * Java class for NoValueColour.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
  * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
+ * <p>
+ * 
  * <pre>
  * &lt;simpleType name="NoValueColour">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -31,31 +33,36 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlType(name = "NoValueColour", namespace = "www.jalview.org/colours")
 @XmlEnum
-public enum NoValueColour {
-
-    @XmlEnumValue("None")
-    NONE("None"),
-    @XmlEnumValue("Min")
-    MIN("Min"),
-    @XmlEnumValue("Max")
-    MAX("Max");
-    private final String value;
-
-    NoValueColour(String v) {
-        value = v;
-    }
+public enum NoValueColour
+{
 
-    public String value() {
-        return value;
-    }
+  @XmlEnumValue("None")
+  NONE("None"), @XmlEnumValue("Min")
+  MIN("Min"), @XmlEnumValue("Max")
+  MAX("Max");
+
+  private final String value;
+
+  NoValueColour(String v)
+  {
+    value = v;
+  }
+
+  public String value()
+  {
+    return value;
+  }
 
-    public static NoValueColour fromValue(String v) {
-        for (NoValueColour c: NoValueColour.values()) {
-            if (c.value.equals(v)) {
-                return c;
-            }
-        }
-        throw new IllegalArgumentException(v);
+  public static NoValueColour fromValue(String v)
+  {
+    for (NoValueColour c : NoValueColour.values())
+    {
+      if (c.value.equals(v))
+      {
+        return c;
+      }
     }
+    throw new IllegalArgumentException(v);
+  }
 
 }
index f034a2a..993adae 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.JAXBElement;
@@ -13,492 +12,567 @@ import javax.xml.bind.annotation.XmlElementDecl;
 import javax.xml.bind.annotation.XmlRegistry;
 import javax.xml.namespace.QName;
 
-
 /**
- * This object contains factory methods for each 
- * Java content interface and Java element interface 
- * generated in the jalview.xml.binding.jalview package. 
- * <p>An ObjectFactory allows you to programatically 
- * construct new instances of the Java representation 
- * for XML content. The Java representation of XML 
- * content can consist of schema derived interfaces 
- * and classes representing the binding of schema 
- * type definitions, element declarations and model 
- * groups.  Factory methods for each of these are 
- * provided in this class.
+ * This object contains factory methods for each Java content interface and Java
+ * element interface generated in the jalview.xml.binding.jalview package.
+ * <p>
+ * An ObjectFactory allows you to programatically construct new instances of the
+ * Java representation for XML content. The Java representation of XML content
+ * can consist of schema derived interfaces and classes representing the binding
+ * of schema type definitions, element declarations and model groups. Factory
+ * methods for each of these are provided in this class.
  * 
  */
 @XmlRegistry
-public class ObjectFactory {
-
-    private final static QName _WebServiceParameterSet_QNAME = new QName("www.jalview.org/xml/wsparamset", "WebServiceParameterSet");
-    private final static QName _JalviewModel_QNAME = new QName("www.jalview.org", "JalviewModel");
-    private final static QName _JalviewUserColours_QNAME = new QName("www.jalview.org/colours", "JalviewUserColours");
-
-    /**
-     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: jalview.xml.binding.jalview
-     * 
-     */
-    public ObjectFactory() {
-    }
-
-    /**
-     * Create an instance of {@link AlcodonFrame }
-     * 
-     */
-    public AlcodonFrame createAlcodonFrame() {
-        return new AlcodonFrame();
-    }
-
-    /**
-     * Create an instance of {@link MapListType }
-     * 
-     */
-    public MapListType createMapListType() {
-        return new MapListType();
-    }
-
-    /**
-     * Create an instance of {@link Sequence }
-     * 
-     */
-    public Sequence createSequence() {
-        return new Sequence();
-    }
-
-    /**
-     * Create an instance of {@link Annotation }
-     * 
-     */
-    public Annotation createAnnotation() {
-        return new Annotation();
-    }
-
-    /**
-     * Create an instance of {@link SequenceSet }
-     * 
-     */
-    public SequenceSet createSequenceSet() {
-        return new SequenceSet();
-    }
-
-    /**
-     * Create an instance of {@link FeatureMatcherSet }
-     * 
-     */
-    public FeatureMatcherSet createFeatureMatcherSet() {
-        return new FeatureMatcherSet();
-    }
-
-    /**
-     * Create an instance of {@link JalviewUserColours }
-     * 
-     */
-    public JalviewUserColours createJalviewUserColours() {
-        return new JalviewUserColours();
-    }
-
-    /**
-     * Create an instance of {@link Pdbentry }
-     * 
-     */
-    public Pdbentry createPdbentry() {
-        return new Pdbentry();
-    }
-
-    /**
-     * Create an instance of {@link Feature }
-     * 
-     */
-    public Feature createFeature() {
-        return new Feature();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel }
-     * 
-     */
-    public JalviewModel createJalviewModel() {
-        return new JalviewModel();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.FeatureSettings }
-     * 
-     */
-    public JalviewModel.FeatureSettings createJalviewModelFeatureSettings() {
-        return new JalviewModel.FeatureSettings();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.PcaViewer }
-     * 
-     */
-    public JalviewModel.PcaViewer createJalviewModelPcaViewer() {
-        return new JalviewModel.PcaViewer();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.Viewport }
-     * 
-     */
-    public JalviewModel.Viewport createJalviewModelViewport() {
-        return new JalviewModel.Viewport();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.JSeq }
-     * 
-     */
-    public JalviewModel.JSeq createJalviewModelJSeq() {
-        return new JalviewModel.JSeq();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.JSeq.RnaViewer }
-     * 
-     */
-    public JalviewModel.JSeq.RnaViewer createJalviewModelJSeqRnaViewer() {
-        return new JalviewModel.JSeq.RnaViewer();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.JSeq.Pdbids }
-     * 
-     */
-    public JalviewModel.JSeq.Pdbids createJalviewModelJSeqPdbids() {
-        return new JalviewModel.JSeq.Pdbids();
-    }
-
-    /**
-     * Create an instance of {@link DoubleMatrix }
-     * 
-     */
-    public DoubleMatrix createDoubleMatrix() {
-        return new DoubleMatrix();
-    }
-
-    /**
-     * Create an instance of {@link AnnotationColourScheme }
-     * 
-     */
-    public AnnotationColourScheme createAnnotationColourScheme() {
-        return new AnnotationColourScheme();
-    }
-
-    /**
-     * Create an instance of {@link PcaDataType }
-     * 
-     */
-    public PcaDataType createPcaDataType() {
-        return new PcaDataType();
-    }
-
-    /**
-     * Create an instance of {@link DoubleVector }
-     * 
-     */
-    public DoubleVector createDoubleVector() {
-        return new DoubleVector();
-    }
-
-    /**
-     * Create an instance of {@link AlcodonFrame.Alcodon }
-     * 
-     */
-    public AlcodonFrame.Alcodon createAlcodonFrameAlcodon() {
-        return new AlcodonFrame.Alcodon();
-    }
-
-    /**
-     * Create an instance of {@link AlcodonFrame.AlcodMap }
-     * 
-     */
-    public AlcodonFrame.AlcodMap createAlcodonFrameAlcodMap() {
-        return new AlcodonFrame.AlcodMap();
-    }
-
-    /**
-     * Create an instance of {@link AnnotationElement }
-     * 
-     */
-    public AnnotationElement createAnnotationElement() {
-        return new AnnotationElement();
-    }
-
-    /**
-     * Create an instance of {@link Mapping }
-     * 
-     */
-    public Mapping createMapping() {
-        return new Mapping();
-    }
-
-    /**
-     * Create an instance of {@link MapListType.MapListFrom }
-     * 
-     */
-    public MapListType.MapListFrom createMapListTypeMapListFrom() {
-        return new MapListType.MapListFrom();
-    }
-
-    /**
-     * Create an instance of {@link MapListType.MapListTo }
-     * 
-     */
-    public MapListType.MapListTo createMapListTypeMapListTo() {
-        return new MapListType.MapListTo();
-    }
-
-    /**
-     * Create an instance of {@link SequenceType }
-     * 
-     */
-    public SequenceType createSequenceType() {
-        return new SequenceType();
-    }
-
-    /**
-     * Create an instance of {@link Sequence.DBRef }
-     * 
-     */
-    public Sequence.DBRef createSequenceDBRef() {
-        return new Sequence.DBRef();
-    }
-
-    /**
-     * Create an instance of {@link Annotation.ThresholdLine }
-     * 
-     */
-    public Annotation.ThresholdLine createAnnotationThresholdLine() {
-        return new Annotation.ThresholdLine();
-    }
-
-    /**
-     * Create an instance of {@link MatrixType }
-     * 
-     */
-    public MatrixType createMatrixType() {
-        return new MatrixType();
-    }
-
-    /**
-     * Create an instance of {@link jalview.xml.binding.jalview.Property }
-     * 
-     */
-    public jalview.xml.binding.jalview.Property createProperty() {
-        return new jalview.xml.binding.jalview.Property();
-    }
-
-    /**
-     * Create an instance of {@link SequenceSet.SequenceSetProperties }
-     * 
-     */
-    public SequenceSet.SequenceSetProperties createSequenceSetSequenceSetProperties() {
-        return new SequenceSet.SequenceSetProperties();
-    }
-
-    /**
-     * Create an instance of {@link VAMSAS }
-     * 
-     */
-    public VAMSAS createVAMSAS() {
-        return new VAMSAS();
-    }
-
-    /**
-     * Create an instance of {@link FeatureMatcher }
-     * 
-     */
-    public FeatureMatcher createFeatureMatcher() {
-        return new FeatureMatcher();
-    }
-
-    /**
-     * Create an instance of {@link WebServiceParameterSet }
-     * 
-     */
-    public WebServiceParameterSet createWebServiceParameterSet() {
-        return new WebServiceParameterSet();
-    }
-
-    /**
-     * Create an instance of {@link FeatureMatcherSet.CompoundMatcher }
-     * 
-     */
-    public FeatureMatcherSet.CompoundMatcher createFeatureMatcherSetCompoundMatcher() {
-        return new FeatureMatcherSet.CompoundMatcher();
-    }
-
-    /**
-     * Create an instance of {@link JalviewUserColours.Colour }
-     * 
-     */
-    public JalviewUserColours.Colour createJalviewUserColoursColour() {
-        return new JalviewUserColours.Colour();
-    }
-
-    /**
-     * Create an instance of {@link JalviewUserColours.Filter }
-     * 
-     */
-    public JalviewUserColours.Filter createJalviewUserColoursFilter() {
-        return new JalviewUserColours.Filter();
-    }
-
-    /**
-     * Create an instance of {@link Pdbentry.Property }
-     * 
-     */
-    public Pdbentry.Property createPdbentryProperty() {
-        return new Pdbentry.Property();
-    }
-
-    /**
-     * Create an instance of {@link Feature.OtherData }
-     * 
-     */
-    public Feature.OtherData createFeatureOtherData() {
-        return new Feature.OtherData();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.JGroup }
-     * 
-     */
-    public JalviewModel.JGroup createJalviewModelJGroup() {
-        return new JalviewModel.JGroup();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.UserColours }
-     * 
-     */
-    public JalviewModel.UserColours createJalviewModelUserColours() {
-        return new JalviewModel.UserColours();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.Tree }
-     * 
-     */
-    public JalviewModel.Tree createJalviewModelTree() {
-        return new JalviewModel.Tree();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.FeatureSettings.Setting }
-     * 
-     */
-    public JalviewModel.FeatureSettings.Setting createJalviewModelFeatureSettingsSetting() {
-        return new JalviewModel.FeatureSettings.Setting();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.FeatureSettings.Group }
-     * 
-     */
-    public JalviewModel.FeatureSettings.Group createJalviewModelFeatureSettingsGroup() {
-        return new JalviewModel.FeatureSettings.Group();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.PcaViewer.SequencePoint }
-     * 
-     */
-    public JalviewModel.PcaViewer.SequencePoint createJalviewModelPcaViewerSequencePoint() {
-        return new JalviewModel.PcaViewer.SequencePoint();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.PcaViewer.Axis }
-     * 
-     */
-    public JalviewModel.PcaViewer.Axis createJalviewModelPcaViewerAxis() {
-        return new JalviewModel.PcaViewer.Axis();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.PcaViewer.SeqPointMin }
-     * 
-     */
-    public JalviewModel.PcaViewer.SeqPointMin createJalviewModelPcaViewerSeqPointMin() {
-        return new JalviewModel.PcaViewer.SeqPointMin();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.PcaViewer.SeqPointMax }
-     * 
-     */
-    public JalviewModel.PcaViewer.SeqPointMax createJalviewModelPcaViewerSeqPointMax() {
-        return new JalviewModel.PcaViewer.SeqPointMax();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.Viewport.HiddenColumns }
-     * 
-     */
-    public JalviewModel.Viewport.HiddenColumns createJalviewModelViewportHiddenColumns() {
-        return new JalviewModel.Viewport.HiddenColumns();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.Viewport.CalcIdParam }
-     * 
-     */
-    public JalviewModel.Viewport.CalcIdParam createJalviewModelViewportCalcIdParam() {
-        return new JalviewModel.Viewport.CalcIdParam();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.Viewport.Overview }
-     * 
-     */
-    public JalviewModel.Viewport.Overview createJalviewModelViewportOverview() {
-        return new JalviewModel.Viewport.Overview();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.JSeq.RnaViewer.SecondaryStructure }
-     * 
-     */
-    public JalviewModel.JSeq.RnaViewer.SecondaryStructure createJalviewModelJSeqRnaViewerSecondaryStructure() {
-        return new JalviewModel.JSeq.RnaViewer.SecondaryStructure();
-    }
-
-    /**
-     * Create an instance of {@link JalviewModel.JSeq.Pdbids.StructureState }
-     * 
-     */
-    public JalviewModel.JSeq.Pdbids.StructureState createJalviewModelJSeqPdbidsStructureState() {
-        return new JalviewModel.JSeq.Pdbids.StructureState();
-    }
-
-    /**
-     * Create an instance of {@link JAXBElement }{@code <}{@link WebServiceParameterSet }{@code >}}
-     * 
-     */
-    @XmlElementDecl(namespace = "www.jalview.org/xml/wsparamset", name = "WebServiceParameterSet")
-    public JAXBElement<WebServiceParameterSet> createWebServiceParameterSet(WebServiceParameterSet value) {
-        return new JAXBElement<WebServiceParameterSet>(_WebServiceParameterSet_QNAME, WebServiceParameterSet.class, null, value);
-    }
-
-    /**
-     * Create an instance of {@link JAXBElement }{@code <}{@link JalviewModel }{@code >}}
-     * 
-     */
-    @XmlElementDecl(namespace = "www.jalview.org", name = "JalviewModel")
-    public JAXBElement<JalviewModel> createJalviewModel(JalviewModel value) {
-        return new JAXBElement<JalviewModel>(_JalviewModel_QNAME, JalviewModel.class, null, value);
-    }
-
-    /**
-     * Create an instance of {@link JAXBElement }{@code <}{@link JalviewUserColours }{@code >}}
-     * 
-     */
-    @XmlElementDecl(namespace = "www.jalview.org/colours", name = "JalviewUserColours")
-    public JAXBElement<JalviewUserColours> createJalviewUserColours(JalviewUserColours value) {
-        return new JAXBElement<JalviewUserColours>(_JalviewUserColours_QNAME, JalviewUserColours.class, null, value);
-    }
+public class ObjectFactory
+{
+
+  private final static QName _WebServiceParameterSet_QNAME = new QName(
+          "www.jalview.org/xml/wsparamset", "WebServiceParameterSet");
+
+  private final static QName _JalviewModel_QNAME = new QName(
+          "www.jalview.org", "JalviewModel");
+
+  private final static QName _JalviewUserColours_QNAME = new QName(
+          "www.jalview.org/colours", "JalviewUserColours");
+
+  /**
+   * Create a new ObjectFactory that can be used to create new instances of
+   * schema derived classes for package: jalview.xml.binding.jalview
+   * 
+   */
+  public ObjectFactory()
+  {
+  }
+
+  /**
+   * Create an instance of {@link AlcodonFrame }
+   * 
+   */
+  public AlcodonFrame createAlcodonFrame()
+  {
+    return new AlcodonFrame();
+  }
+
+  /**
+   * Create an instance of {@link MapListType }
+   * 
+   */
+  public MapListType createMapListType()
+  {
+    return new MapListType();
+  }
+
+  /**
+   * Create an instance of {@link Sequence }
+   * 
+   */
+  public Sequence createSequence()
+  {
+    return new Sequence();
+  }
+
+  /**
+   * Create an instance of {@link Annotation }
+   * 
+   */
+  public Annotation createAnnotation()
+  {
+    return new Annotation();
+  }
+
+  /**
+   * Create an instance of {@link SequenceSet }
+   * 
+   */
+  public SequenceSet createSequenceSet()
+  {
+    return new SequenceSet();
+  }
+
+  /**
+   * Create an instance of {@link FeatureMatcherSet }
+   * 
+   */
+  public FeatureMatcherSet createFeatureMatcherSet()
+  {
+    return new FeatureMatcherSet();
+  }
+
+  /**
+   * Create an instance of {@link JalviewUserColours }
+   * 
+   */
+  public JalviewUserColours createJalviewUserColours()
+  {
+    return new JalviewUserColours();
+  }
+
+  /**
+   * Create an instance of {@link Pdbentry }
+   * 
+   */
+  public Pdbentry createPdbentry()
+  {
+    return new Pdbentry();
+  }
+
+  /**
+   * Create an instance of {@link Feature }
+   * 
+   */
+  public Feature createFeature()
+  {
+    return new Feature();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel }
+   * 
+   */
+  public JalviewModel createJalviewModel()
+  {
+    return new JalviewModel();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.FeatureSettings }
+   * 
+   */
+  public JalviewModel.FeatureSettings createJalviewModelFeatureSettings()
+  {
+    return new JalviewModel.FeatureSettings();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.PcaViewer }
+   * 
+   */
+  public JalviewModel.PcaViewer createJalviewModelPcaViewer()
+  {
+    return new JalviewModel.PcaViewer();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.Viewport }
+   * 
+   */
+  public JalviewModel.Viewport createJalviewModelViewport()
+  {
+    return new JalviewModel.Viewport();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.JSeq }
+   * 
+   */
+  public JalviewModel.JSeq createJalviewModelJSeq()
+  {
+    return new JalviewModel.JSeq();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.JSeq.RnaViewer }
+   * 
+   */
+  public JalviewModel.JSeq.RnaViewer createJalviewModelJSeqRnaViewer()
+  {
+    return new JalviewModel.JSeq.RnaViewer();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.JSeq.Pdbids }
+   * 
+   */
+  public JalviewModel.JSeq.Pdbids createJalviewModelJSeqPdbids()
+  {
+    return new JalviewModel.JSeq.Pdbids();
+  }
+
+  /**
+   * Create an instance of {@link DoubleMatrix }
+   * 
+   */
+  public DoubleMatrix createDoubleMatrix()
+  {
+    return new DoubleMatrix();
+  }
+
+  /**
+   * Create an instance of {@link AnnotationColourScheme }
+   * 
+   */
+  public AnnotationColourScheme createAnnotationColourScheme()
+  {
+    return new AnnotationColourScheme();
+  }
+
+  /**
+   * Create an instance of {@link PcaDataType }
+   * 
+   */
+  public PcaDataType createPcaDataType()
+  {
+    return new PcaDataType();
+  }
+
+  /**
+   * Create an instance of {@link DoubleVector }
+   * 
+   */
+  public DoubleVector createDoubleVector()
+  {
+    return new DoubleVector();
+  }
+
+  /**
+   * Create an instance of {@link AlcodonFrame.Alcodon }
+   * 
+   */
+  public AlcodonFrame.Alcodon createAlcodonFrameAlcodon()
+  {
+    return new AlcodonFrame.Alcodon();
+  }
+
+  /**
+   * Create an instance of {@link AlcodonFrame.AlcodMap }
+   * 
+   */
+  public AlcodonFrame.AlcodMap createAlcodonFrameAlcodMap()
+  {
+    return new AlcodonFrame.AlcodMap();
+  }
+
+  /**
+   * Create an instance of {@link AnnotationElement }
+   * 
+   */
+  public AnnotationElement createAnnotationElement()
+  {
+    return new AnnotationElement();
+  }
+
+  /**
+   * Create an instance of {@link Mapping }
+   * 
+   */
+  public Mapping createMapping()
+  {
+    return new Mapping();
+  }
+
+  /**
+   * Create an instance of {@link MapListType.MapListFrom }
+   * 
+   */
+  public MapListType.MapListFrom createMapListTypeMapListFrom()
+  {
+    return new MapListType.MapListFrom();
+  }
+
+  /**
+   * Create an instance of {@link MapListType.MapListTo }
+   * 
+   */
+  public MapListType.MapListTo createMapListTypeMapListTo()
+  {
+    return new MapListType.MapListTo();
+  }
+
+  /**
+   * Create an instance of {@link SequenceType }
+   * 
+   */
+  public SequenceType createSequenceType()
+  {
+    return new SequenceType();
+  }
+
+  /**
+   * Create an instance of {@link Sequence.DBRef }
+   * 
+   */
+  public Sequence.DBRef createSequenceDBRef()
+  {
+    return new Sequence.DBRef();
+  }
+
+  /**
+   * Create an instance of {@link Annotation.ThresholdLine }
+   * 
+   */
+  public Annotation.ThresholdLine createAnnotationThresholdLine()
+  {
+    return new Annotation.ThresholdLine();
+  }
+
+  /**
+   * Create an instance of {@link MatrixType }
+   * 
+   */
+  public MatrixType createMatrixType()
+  {
+    return new MatrixType();
+  }
+
+  /**
+   * Create an instance of {@link jalview.xml.binding.jalview.Property }
+   * 
+   */
+  public jalview.xml.binding.jalview.Property createProperty()
+  {
+    return new jalview.xml.binding.jalview.Property();
+  }
+
+  /**
+   * Create an instance of {@link SequenceSet.SequenceSetProperties }
+   * 
+   */
+  public SequenceSet.SequenceSetProperties createSequenceSetSequenceSetProperties()
+  {
+    return new SequenceSet.SequenceSetProperties();
+  }
+
+  /**
+   * Create an instance of {@link VAMSAS }
+   * 
+   */
+  public VAMSAS createVAMSAS()
+  {
+    return new VAMSAS();
+  }
+
+  /**
+   * Create an instance of {@link FeatureMatcher }
+   * 
+   */
+  public FeatureMatcher createFeatureMatcher()
+  {
+    return new FeatureMatcher();
+  }
+
+  /**
+   * Create an instance of {@link WebServiceParameterSet }
+   * 
+   */
+  public WebServiceParameterSet createWebServiceParameterSet()
+  {
+    return new WebServiceParameterSet();
+  }
+
+  /**
+   * Create an instance of {@link FeatureMatcherSet.CompoundMatcher }
+   * 
+   */
+  public FeatureMatcherSet.CompoundMatcher createFeatureMatcherSetCompoundMatcher()
+  {
+    return new FeatureMatcherSet.CompoundMatcher();
+  }
+
+  /**
+   * Create an instance of {@link JalviewUserColours.Colour }
+   * 
+   */
+  public JalviewUserColours.Colour createJalviewUserColoursColour()
+  {
+    return new JalviewUserColours.Colour();
+  }
+
+  /**
+   * Create an instance of {@link JalviewUserColours.Filter }
+   * 
+   */
+  public JalviewUserColours.Filter createJalviewUserColoursFilter()
+  {
+    return new JalviewUserColours.Filter();
+  }
+
+  /**
+   * Create an instance of {@link Pdbentry.Property }
+   * 
+   */
+  public Pdbentry.Property createPdbentryProperty()
+  {
+    return new Pdbentry.Property();
+  }
+
+  /**
+   * Create an instance of {@link Feature.OtherData }
+   * 
+   */
+  public Feature.OtherData createFeatureOtherData()
+  {
+    return new Feature.OtherData();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.JGroup }
+   * 
+   */
+  public JalviewModel.JGroup createJalviewModelJGroup()
+  {
+    return new JalviewModel.JGroup();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.UserColours }
+   * 
+   */
+  public JalviewModel.UserColours createJalviewModelUserColours()
+  {
+    return new JalviewModel.UserColours();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.Tree }
+   * 
+   */
+  public JalviewModel.Tree createJalviewModelTree()
+  {
+    return new JalviewModel.Tree();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.FeatureSettings.Setting }
+   * 
+   */
+  public JalviewModel.FeatureSettings.Setting createJalviewModelFeatureSettingsSetting()
+  {
+    return new JalviewModel.FeatureSettings.Setting();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.FeatureSettings.Group }
+   * 
+   */
+  public JalviewModel.FeatureSettings.Group createJalviewModelFeatureSettingsGroup()
+  {
+    return new JalviewModel.FeatureSettings.Group();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.PcaViewer.SequencePoint }
+   * 
+   */
+  public JalviewModel.PcaViewer.SequencePoint createJalviewModelPcaViewerSequencePoint()
+  {
+    return new JalviewModel.PcaViewer.SequencePoint();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.PcaViewer.Axis }
+   * 
+   */
+  public JalviewModel.PcaViewer.Axis createJalviewModelPcaViewerAxis()
+  {
+    return new JalviewModel.PcaViewer.Axis();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.PcaViewer.SeqPointMin }
+   * 
+   */
+  public JalviewModel.PcaViewer.SeqPointMin createJalviewModelPcaViewerSeqPointMin()
+  {
+    return new JalviewModel.PcaViewer.SeqPointMin();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.PcaViewer.SeqPointMax }
+   * 
+   */
+  public JalviewModel.PcaViewer.SeqPointMax createJalviewModelPcaViewerSeqPointMax()
+  {
+    return new JalviewModel.PcaViewer.SeqPointMax();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.Viewport.HiddenColumns }
+   * 
+   */
+  public JalviewModel.Viewport.HiddenColumns createJalviewModelViewportHiddenColumns()
+  {
+    return new JalviewModel.Viewport.HiddenColumns();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.Viewport.CalcIdParam }
+   * 
+   */
+  public JalviewModel.Viewport.CalcIdParam createJalviewModelViewportCalcIdParam()
+  {
+    return new JalviewModel.Viewport.CalcIdParam();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.Viewport.Overview }
+   * 
+   */
+  public JalviewModel.Viewport.Overview createJalviewModelViewportOverview()
+  {
+    return new JalviewModel.Viewport.Overview();
+  }
+
+  /**
+   * Create an instance of
+   * {@link JalviewModel.JSeq.RnaViewer.SecondaryStructure }
+   * 
+   */
+  public JalviewModel.JSeq.RnaViewer.SecondaryStructure createJalviewModelJSeqRnaViewerSecondaryStructure()
+  {
+    return new JalviewModel.JSeq.RnaViewer.SecondaryStructure();
+  }
+
+  /**
+   * Create an instance of {@link JalviewModel.JSeq.Pdbids.StructureState }
+   * 
+   */
+  public JalviewModel.JSeq.Pdbids.StructureState createJalviewModelJSeqPdbidsStructureState()
+  {
+    return new JalviewModel.JSeq.Pdbids.StructureState();
+  }
+
+  /**
+   * Create an instance of {@link JAXBElement
+   * }{@code <}{@link WebServiceParameterSet }{@code >}}
+   * 
+   */
+  @XmlElementDecl(
+    namespace = "www.jalview.org/xml/wsparamset",
+    name = "WebServiceParameterSet")
+  public JAXBElement<WebServiceParameterSet> createWebServiceParameterSet(
+          WebServiceParameterSet value)
+  {
+    return new JAXBElement<WebServiceParameterSet>(
+            _WebServiceParameterSet_QNAME, WebServiceParameterSet.class,
+            null, value);
+  }
+
+  /**
+   * Create an instance of {@link JAXBElement }{@code <}{@link JalviewModel
+   * }{@code >}}
+   * 
+   */
+  @XmlElementDecl(namespace = "www.jalview.org", name = "JalviewModel")
+  public JAXBElement<JalviewModel> createJalviewModel(JalviewModel value)
+  {
+    return new JAXBElement<JalviewModel>(_JalviewModel_QNAME,
+            JalviewModel.class, null, value);
+  }
+
+  /**
+   * Create an instance of {@link JAXBElement
+   * }{@code <}{@link JalviewUserColours }{@code >}}
+   * 
+   */
+  @XmlElementDecl(
+    namespace = "www.jalview.org/colours",
+    name = "JalviewUserColours")
+  public JAXBElement<JalviewUserColours> createJalviewUserColours(
+          JalviewUserColours value)
+  {
+    return new JAXBElement<JalviewUserColours>(_JalviewUserColours_QNAME,
+            JalviewUserColours.class, null, value);
+  }
 
 }
index 06aecab..2ff7a55 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,15 +12,17 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * 
- *                             The results of a PCA calculation
- *                     
+ * The results of a PCA calculation
+ * 
  * 
- * <p>Java class for PcaDataType complex type.
+ * <p>
+ * Java class for PcaDataType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="PcaDataType">
@@ -40,90 +41,90 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "PcaDataType", namespace = "www.jalview.org", propOrder = {
-    "pairwiseMatrix",
-    "tridiagonalMatrix",
-    "eigenMatrix"
-})
-public class PcaDataType {
+@XmlType(
+  name = "PcaDataType",
+  namespace = "www.jalview.org",
+  propOrder =
+  { "pairwiseMatrix", "tridiagonalMatrix", "eigenMatrix" })
+public class PcaDataType
+{
+
+  @XmlElement(required = true)
+  protected DoubleMatrix pairwiseMatrix;
+
+  @XmlElement(required = true)
+  protected DoubleMatrix tridiagonalMatrix;
 
-    @XmlElement(required = true)
-    protected DoubleMatrix pairwiseMatrix;
-    @XmlElement(required = true)
-    protected DoubleMatrix tridiagonalMatrix;
-    @XmlElement(required = true)
-    protected DoubleMatrix eigenMatrix;
+  @XmlElement(required = true)
+  protected DoubleMatrix eigenMatrix;
 
-    /**
-     * Gets the value of the pairwiseMatrix property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DoubleMatrix }
-     *     
-     */
-    public DoubleMatrix getPairwiseMatrix() {
-        return pairwiseMatrix;
-    }
+  /**
+   * Gets the value of the pairwiseMatrix property.
+   * 
+   * @return possible object is {@link DoubleMatrix }
+   * 
+   */
+  public DoubleMatrix getPairwiseMatrix()
+  {
+    return pairwiseMatrix;
+  }
 
-    /**
-     * Sets the value of the pairwiseMatrix property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DoubleMatrix }
-     *     
-     */
-    public void setPairwiseMatrix(DoubleMatrix value) {
-        this.pairwiseMatrix = value;
-    }
+  /**
+   * Sets the value of the pairwiseMatrix property.
+   * 
+   * @param value
+   *          allowed object is {@link DoubleMatrix }
+   * 
+   */
+  public void setPairwiseMatrix(DoubleMatrix value)
+  {
+    this.pairwiseMatrix = value;
+  }
 
-    /**
-     * Gets the value of the tridiagonalMatrix property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DoubleMatrix }
-     *     
-     */
-    public DoubleMatrix getTridiagonalMatrix() {
-        return tridiagonalMatrix;
-    }
+  /**
+   * Gets the value of the tridiagonalMatrix property.
+   * 
+   * @return possible object is {@link DoubleMatrix }
+   * 
+   */
+  public DoubleMatrix getTridiagonalMatrix()
+  {
+    return tridiagonalMatrix;
+  }
 
-    /**
-     * Sets the value of the tridiagonalMatrix property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DoubleMatrix }
-     *     
-     */
-    public void setTridiagonalMatrix(DoubleMatrix value) {
-        this.tridiagonalMatrix = value;
-    }
+  /**
+   * Sets the value of the tridiagonalMatrix property.
+   * 
+   * @param value
+   *          allowed object is {@link DoubleMatrix }
+   * 
+   */
+  public void setTridiagonalMatrix(DoubleMatrix value)
+  {
+    this.tridiagonalMatrix = value;
+  }
 
-    /**
-     * Gets the value of the eigenMatrix property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DoubleMatrix }
-     *     
-     */
-    public DoubleMatrix getEigenMatrix() {
-        return eigenMatrix;
-    }
+  /**
+   * Gets the value of the eigenMatrix property.
+   * 
+   * @return possible object is {@link DoubleMatrix }
+   * 
+   */
+  public DoubleMatrix getEigenMatrix()
+  {
+    return eigenMatrix;
+  }
 
-    /**
-     * Sets the value of the eigenMatrix property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DoubleMatrix }
-     *     
-     */
-    public void setEigenMatrix(DoubleMatrix value) {
-        this.eigenMatrix = value;
-    }
+  /**
+   * Sets the value of the eigenMatrix property.
+   * 
+   * @param value
+   *          allowed object is {@link DoubleMatrix }
+   * 
+   */
+  public void setEigenMatrix(DoubleMatrix value)
+  {
+    this.eigenMatrix = value;
+  }
 
 }
index 401022a..f0fd2f3 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for pdbentry complex type.
+ * <p>
+ * Java class for pdbentry complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="pdbentry">
@@ -49,199 +50,205 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "pdbentry", namespace = "www.jalview.org", propOrder = {
-    "property"
-})
-@XmlSeeAlso({
-    jalview.xml.binding.jalview.JalviewModel.JSeq.Pdbids.class
-})
-public class Pdbentry {
-
-    protected List<Pdbentry.Property> property;
-    @XmlAttribute(name = "id", required = true)
-    protected String id;
-    @XmlAttribute(name = "type")
-    protected String type;
-    @XmlAttribute(name = "file")
-    protected String file;
-
-    /**
-     * Gets the value of the property property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the property property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getProperty().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Pdbentry.Property }
-     * 
-     * 
-     */
-    public List<Pdbentry.Property> getProperty() {
-        if (property == null) {
-            property = new ArrayList<Pdbentry.Property>();
-        }
-        return this.property;
+@XmlType(
+  name = "pdbentry",
+  namespace = "www.jalview.org",
+  propOrder =
+  { "property" })
+@XmlSeeAlso({ jalview.xml.binding.jalview.JalviewModel.JSeq.Pdbids.class })
+public class Pdbentry
+{
+
+  protected List<Pdbentry.Property> property;
+
+  @XmlAttribute(name = "id", required = true)
+  protected String id;
+
+  @XmlAttribute(name = "type")
+  protected String type;
+
+  @XmlAttribute(name = "file")
+  protected String file;
+
+  /**
+   * Gets the value of the property property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the property property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getProperty().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link Pdbentry.Property }
+   * 
+   * 
+   */
+  public List<Pdbentry.Property> getProperty()
+  {
+    if (property == null)
+    {
+      property = new ArrayList<Pdbentry.Property>();
     }
+    return this.property;
+  }
+
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
+
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
+
+  /**
+   * Gets the value of the file property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getFile()
+  {
+    return file;
+  }
+
+  /**
+   * Sets the value of the file property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setFile(String value)
+  {
+    this.file = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class Property
+  {
+
+    @XmlAttribute(name = "name", required = true)
+    protected String name;
+
+    @XmlAttribute(name = "value", required = true)
+    protected String value;
 
     /**
-     * Gets the value of the id property.
+     * Gets the value of the name property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getId() {
-        return id;
+    public String getName()
+    {
+      return name;
     }
 
     /**
-     * Sets the value of the id property.
+     * Sets the value of the name property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
-    }
-
-    /**
-     * Gets the value of the type property.
+     *          allowed object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getType() {
-        return type;
+    public void setName(String value)
+    {
+      this.name = value;
     }
 
     /**
-     * Sets the value of the type property.
+     * Gets the value of the value property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
-
-    /**
-     * Gets the value of the file property.
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getFile() {
-        return file;
+    public String getValue()
+    {
+      return value;
     }
 
     /**
-     * Sets the value of the file property.
+     * Sets the value of the value property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setFile(String value) {
-        this.file = value;
-    }
-
-
-    /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
-     * 
+     *          allowed object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class Property {
-
-        @XmlAttribute(name = "name", required = true)
-        protected String name;
-        @XmlAttribute(name = "value", required = true)
-        protected String value;
-
-        /**
-         * Gets the value of the name property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Sets the value of the name property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setName(String value) {
-            this.name = value;
-        }
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-
+    public void setValue(String value)
+    {
+      this.value = value;
     }
 
+  }
+
 }
index 3c0879d..b70e665 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,11 +12,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for property complex type.
+ * <p>
+ * Java class for property complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="property">
@@ -34,59 +35,59 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "property")
-public class Property {
+public class Property
+{
+
+  @XmlAttribute(name = "name")
+  protected String name;
 
-    @XmlAttribute(name = "name")
-    protected String name;
-    @XmlAttribute(name = "value")
-    protected String value;
+  @XmlAttribute(name = "value")
+  protected String value;
 
-    /**
-     * Gets the value of the name property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getName() {
-        return name;
-    }
+  /**
+   * Gets the value of the name property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getName()
+  {
+    return name;
+  }
 
-    /**
-     * Sets the value of the name property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setName(String value) {
-        this.name = value;
-    }
+  /**
+   * Sets the value of the name property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setName(String value)
+  {
+    this.name = value;
+  }
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
 
 }
index d02fd03..a5923e1 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -17,11 +16,13 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -55,294 +56,300 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "dbRef"
-})
+@XmlType(name = "", propOrder = { "dbRef" })
 @XmlRootElement(name = "Sequence")
-public class Sequence
-    extends SequenceType
+public class Sequence extends SequenceType
 {
 
-    @XmlElement(name = "DBRef")
-    protected List<Sequence.DBRef> dbRef;
-    @XmlAttribute(name = "dsseqid")
-    protected String dsseqid;
-    @XmlAttribute(name = "biotype")
-    protected String biotype;
+  @XmlElement(name = "DBRef")
+  protected List<Sequence.DBRef> dbRef;
+
+  @XmlAttribute(name = "dsseqid")
+  protected String dsseqid;
+
+  @XmlAttribute(name = "biotype")
+  protected String biotype;
+
+  /**
+   * Gets the value of the dbRef property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the dbRef property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getDBRef().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link Sequence.DBRef }
+   * 
+   * 
+   */
+  public List<Sequence.DBRef> getDBRef()
+  {
+    if (dbRef == null)
+    {
+      dbRef = new ArrayList<Sequence.DBRef>();
+    }
+    return this.dbRef;
+  }
+
+  /**
+   * Gets the value of the dsseqid property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDsseqid()
+  {
+    return dsseqid;
+  }
+
+  /**
+   * Sets the value of the dsseqid property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDsseqid(String value)
+  {
+    this.dsseqid = value;
+  }
+
+  /**
+   * Gets the value of the biotype property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getBiotype()
+  {
+    return biotype;
+  }
+
+  /**
+   * Sets the value of the biotype property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setBiotype(String value)
+  {
+    this.biotype = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element ref="{www.vamsas.ac.uk/jalview/version2}Mapping" minOccurs="0"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="source" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="accessionId" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="locus" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *       &lt;attribute name="canonical" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "mapping" })
+  public static class DBRef
+  {
+
+    @XmlElement(name = "Mapping")
+    protected Mapping mapping;
+
+    @XmlAttribute(name = "source")
+    protected String source;
+
+    @XmlAttribute(name = "version")
+    protected String version;
+
+    @XmlAttribute(name = "accessionId")
+    protected String accessionId;
+
+    @XmlAttribute(name = "locus")
+    protected Boolean locus;
+
+    @XmlAttribute(name = "canonical")
+    protected Boolean canonical;
 
     /**
-     * Gets the value of the dbRef property.
+     * Gets the value of the mapping property.
      * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the dbRef property.
+     * @return possible object is {@link Mapping }
      * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getDBRef().add(newItem);
-     * </pre>
+     */
+    public Mapping getMapping()
+    {
+      return mapping;
+    }
+
+    /**
+     * Sets the value of the mapping property.
+     * 
+     * @param value
+     *          allowed object is {@link Mapping }
+     * 
+     */
+    public void setMapping(Mapping value)
+    {
+      this.mapping = value;
+    }
+
+    /**
+     * Gets the value of the source property.
      * 
+     * @return possible object is {@link String }
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Sequence.DBRef }
+     */
+    public String getSource()
+    {
+      return source;
+    }
+
+    /**
+     * Sets the value of the source property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    public List<Sequence.DBRef> getDBRef() {
-        if (dbRef == null) {
-            dbRef = new ArrayList<Sequence.DBRef>();
-        }
-        return this.dbRef;
+    public void setSource(String value)
+    {
+      this.source = value;
     }
 
     /**
-     * Gets the value of the dsseqid property.
+     * Gets the value of the version property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getDsseqid() {
-        return dsseqid;
+    public String getVersion()
+    {
+      return version;
     }
 
     /**
-     * Sets the value of the dsseqid property.
+     * Sets the value of the version property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *          allowed object is {@link String }
+     * 
      */
-    public void setDsseqid(String value) {
-        this.dsseqid = value;
+    public void setVersion(String value)
+    {
+      this.version = value;
     }
 
     /**
-     * Gets the value of the biotype property.
+     * Gets the value of the accessionId property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getBiotype() {
-        return biotype;
+    public String getAccessionId()
+    {
+      return accessionId;
     }
 
     /**
-     * Sets the value of the biotype property.
+     * Sets the value of the accessionId property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *          allowed object is {@link String }
+     * 
      */
-    public void setBiotype(String value) {
-        this.biotype = value;
+    public void setAccessionId(String value)
+    {
+      this.accessionId = value;
     }
 
+    /**
+     * Gets the value of the locus property.
+     * 
+     * @return possible object is {@link Boolean }
+     * 
+     */
+    public boolean isLocus()
+    {
+      if (locus == null)
+      {
+        return false;
+      }
+      else
+      {
+        return locus;
+      }
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Sets the value of the locus property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @param value
+     *          allowed object is {@link Boolean }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element ref="{www.vamsas.ac.uk/jalview/version2}Mapping" minOccurs="0"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="source" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="version" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="accessionId" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="locus" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *       &lt;attribute name="canonical" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public void setLocus(Boolean value)
+    {
+      this.locus = value;
+    }
+
+    /**
+     * Gets the value of the canonical property.
      * 
+     * @return possible object is {@link Boolean }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "mapping"
-    })
-    public static class DBRef {
-
-        @XmlElement(name = "Mapping")
-        protected Mapping mapping;
-        @XmlAttribute(name = "source")
-        protected String source;
-        @XmlAttribute(name = "version")
-        protected String version;
-        @XmlAttribute(name = "accessionId")
-        protected String accessionId;
-        @XmlAttribute(name = "locus")
-        protected Boolean locus;
-        @XmlAttribute(name = "canonical")
-        protected Boolean canonical;
-
-        /**
-         * Gets the value of the mapping property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Mapping }
-         *     
-         */
-        public Mapping getMapping() {
-            return mapping;
-        }
-
-        /**
-         * Sets the value of the mapping property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Mapping }
-         *     
-         */
-        public void setMapping(Mapping value) {
-            this.mapping = value;
-        }
-
-        /**
-         * Gets the value of the source property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getSource() {
-            return source;
-        }
-
-        /**
-         * Sets the value of the source property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setSource(String value) {
-            this.source = value;
-        }
-
-        /**
-         * Gets the value of the version property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getVersion() {
-            return version;
-        }
-
-        /**
-         * Sets the value of the version property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setVersion(String value) {
-            this.version = value;
-        }
-
-        /**
-         * Gets the value of the accessionId property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getAccessionId() {
-            return accessionId;
-        }
-
-        /**
-         * Sets the value of the accessionId property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setAccessionId(String value) {
-            this.accessionId = value;
-        }
-
-        /**
-         * Gets the value of the locus property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isLocus() {
-            if (locus == null) {
-                return false;
-            } else {
-                return locus;
-            }
-        }
-
-        /**
-         * Sets the value of the locus property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setLocus(Boolean value) {
-            this.locus = value;
-        }
-
-        /**
-         * Gets the value of the canonical property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link Boolean }
-         *     
-         */
-        public boolean isCanonical() {
-            if (canonical == null) {
-                return false;
-            } else {
-                return canonical;
-            }
-        }
-
-        /**
-         * Sets the value of the canonical property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link Boolean }
-         *     
-         */
-        public void setCanonical(Boolean value) {
-            this.canonical = value;
-        }
+    public boolean isCanonical()
+    {
+      if (canonical == null)
+      {
+        return false;
+      }
+      else
+      {
+        return canonical;
+      }
+    }
 
+    /**
+     * Sets the value of the canonical property.
+     * 
+     * @param value
+     *          allowed object is {@link Boolean }
+     * 
+     */
+    public void setCanonical(Boolean value)
+    {
+      this.canonical = value;
     }
 
+  }
+
 }
index a915d94..f08b225 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -17,11 +16,13 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -52,267 +53,282 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "sequence",
-    "annotation",
-    "sequenceSetProperties",
-    "alcodonFrame"
-})
+@XmlType(
+  name = "",
+  propOrder =
+  { "sequence", "annotation", "sequenceSetProperties", "alcodonFrame" })
 @XmlRootElement(name = "SequenceSet")
-public class SequenceSet {
+public class SequenceSet
+{
 
-    @XmlElement(name = "Sequence")
-    protected List<Sequence> sequence;
-    @XmlElement(name = "Annotation")
-    protected List<Annotation> annotation;
-    protected List<SequenceSet.SequenceSetProperties> sequenceSetProperties;
-    @XmlElement(name = "AlcodonFrame")
-    protected List<AlcodonFrame> alcodonFrame;
-    @XmlAttribute(name = "gapChar", required = true)
-    protected String gapChar;
-    @XmlAttribute(name = "datasetId")
-    protected String datasetId;
+  @XmlElement(name = "Sequence")
+  protected List<Sequence> sequence;
 
-    /**
-     * Gets the value of the sequence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the sequence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getSequence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Sequence }
-     * 
-     * 
-     */
-    public List<Sequence> getSequence() {
-        if (sequence == null) {
-            sequence = new ArrayList<Sequence>();
-        }
-        return this.sequence;
+  @XmlElement(name = "Annotation")
+  protected List<Annotation> annotation;
+
+  protected List<SequenceSet.SequenceSetProperties> sequenceSetProperties;
+
+  @XmlElement(name = "AlcodonFrame")
+  protected List<AlcodonFrame> alcodonFrame;
+
+  @XmlAttribute(name = "gapChar", required = true)
+  protected String gapChar;
+
+  @XmlAttribute(name = "datasetId")
+  protected String datasetId;
+
+  /**
+   * Gets the value of the sequence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the sequence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getSequence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Sequence }
+   * 
+   * 
+   */
+  public List<Sequence> getSequence()
+  {
+    if (sequence == null)
+    {
+      sequence = new ArrayList<Sequence>();
     }
+    return this.sequence;
+  }
 
-    /**
-     * Gets the value of the annotation property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the annotation property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getAnnotation().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Annotation }
-     * 
-     * 
-     */
-    public List<Annotation> getAnnotation() {
-        if (annotation == null) {
-            annotation = new ArrayList<Annotation>();
-        }
-        return this.annotation;
+  /**
+   * Gets the value of the annotation property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the annotation property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getAnnotation().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Annotation
+   * }
+   * 
+   * 
+   */
+  public List<Annotation> getAnnotation()
+  {
+    if (annotation == null)
+    {
+      annotation = new ArrayList<Annotation>();
     }
+    return this.annotation;
+  }
 
-    /**
-     * Gets the value of the sequenceSetProperties property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the sequenceSetProperties property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getSequenceSetProperties().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link SequenceSet.SequenceSetProperties }
-     * 
-     * 
-     */
-    public List<SequenceSet.SequenceSetProperties> getSequenceSetProperties() {
-        if (sequenceSetProperties == null) {
-            sequenceSetProperties = new ArrayList<SequenceSet.SequenceSetProperties>();
-        }
-        return this.sequenceSetProperties;
+  /**
+   * Gets the value of the sequenceSetProperties property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the sequenceSetProperties property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getSequenceSetProperties().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link SequenceSet.SequenceSetProperties }
+   * 
+   * 
+   */
+  public List<SequenceSet.SequenceSetProperties> getSequenceSetProperties()
+  {
+    if (sequenceSetProperties == null)
+    {
+      sequenceSetProperties = new ArrayList<SequenceSet.SequenceSetProperties>();
     }
+    return this.sequenceSetProperties;
+  }
 
-    /**
-     * Gets the value of the alcodonFrame property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the alcodonFrame property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getAlcodonFrame().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link AlcodonFrame }
-     * 
-     * 
-     */
-    public List<AlcodonFrame> getAlcodonFrame() {
-        if (alcodonFrame == null) {
-            alcodonFrame = new ArrayList<AlcodonFrame>();
-        }
-        return this.alcodonFrame;
+  /**
+   * Gets the value of the alcodonFrame property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the alcodonFrame property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getAlcodonFrame().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link AlcodonFrame }
+   * 
+   * 
+   */
+  public List<AlcodonFrame> getAlcodonFrame()
+  {
+    if (alcodonFrame == null)
+    {
+      alcodonFrame = new ArrayList<AlcodonFrame>();
     }
+    return this.alcodonFrame;
+  }
+
+  /**
+   * Gets the value of the gapChar property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getGapChar()
+  {
+    return gapChar;
+  }
+
+  /**
+   * Sets the value of the gapChar property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setGapChar(String value)
+  {
+    this.gapChar = value;
+  }
+
+  /**
+   * Gets the value of the datasetId property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDatasetId()
+  {
+    return datasetId;
+  }
+
+  /**
+   * Sets the value of the datasetId property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDatasetId(String value)
+  {
+    this.datasetId = value;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="key" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *       &lt;attribute name="value" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class SequenceSetProperties
+  {
+
+    @XmlAttribute(name = "key")
+    protected String key;
+
+    @XmlAttribute(name = "value")
+    protected String value;
 
     /**
-     * Gets the value of the gapChar property.
+     * Gets the value of the key property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getGapChar() {
-        return gapChar;
+    public String getKey()
+    {
+      return key;
     }
 
     /**
-     * Sets the value of the gapChar property.
+     * Sets the value of the key property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setGapChar(String value) {
-        this.gapChar = value;
-    }
-
-    /**
-     * Gets the value of the datasetId property.
+     *          allowed object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getDatasetId() {
-        return datasetId;
+    public void setKey(String value)
+    {
+      this.key = value;
     }
 
     /**
-     * Sets the value of the datasetId property.
+     * Gets the value of the value property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
      */
-    public void setDatasetId(String value) {
-        this.datasetId = value;
+    public String getValue()
+    {
+      return value;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="key" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *       &lt;attribute name="value" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     * Sets the value of the value property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class SequenceSetProperties {
-
-        @XmlAttribute(name = "key")
-        protected String key;
-        @XmlAttribute(name = "value")
-        protected String value;
-
-        /**
-         * Gets the value of the key property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getKey() {
-            return key;
-        }
-
-        /**
-         * Sets the value of the key property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setKey(String value) {
-            this.key = value;
-        }
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-
+    public void setValue(String value)
+    {
+      this.value = value;
     }
 
+  }
+
 }
index fa65d58..44e606d 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -14,11 +13,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for SequenceType complex type.
+ * <p>
+ * Java class for SequenceType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="SequenceType">
@@ -38,116 +39,111 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "SequenceType", propOrder = {
-    "sequence",
-    "name"
-})
-@XmlSeeAlso({
-    Sequence.class
-})
-public class SequenceType {
-
-    protected String sequence;
-    protected String name;
-    @XmlAttribute(name = "id")
-    protected String id;
-    @XmlAttribute(name = "description")
-    protected String description;
-
-    /**
-     * Gets the value of the sequence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getSequence() {
-        return sequence;
-    }
-
-    /**
-     * Sets the value of the sequence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setSequence(String value) {
-        this.sequence = value;
-    }
-
-    /**
-     * Gets the value of the name property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Sets the value of the name property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setName(String value) {
-        this.name = value;
-    }
-
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
-    }
-
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
-    }
-
-    /**
-     * Gets the value of the description property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDescription() {
-        return description;
-    }
-
-    /**
-     * Sets the value of the description property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDescription(String value) {
-        this.description = value;
-    }
+@XmlType(name = "SequenceType", propOrder = { "sequence", "name" })
+@XmlSeeAlso({ Sequence.class })
+public class SequenceType
+{
+
+  protected String sequence;
+
+  protected String name;
+
+  @XmlAttribute(name = "id")
+  protected String id;
+
+  @XmlAttribute(name = "description")
+  protected String description;
+
+  /**
+   * Gets the value of the sequence property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getSequence()
+  {
+    return sequence;
+  }
+
+  /**
+   * Sets the value of the sequence property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setSequence(String value)
+  {
+    this.sequence = value;
+  }
+
+  /**
+   * Gets the value of the name property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Sets the value of the name property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setName(String value)
+  {
+    this.name = value;
+  }
+
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
+
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
+
+  /**
+   * Gets the value of the description property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /**
+   * Sets the value of the description property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDescription(String value)
+  {
+    this.description = value;
+  }
 
 }
index 192caf8..ad0ea1e 100644 (file)
@@ -2,21 +2,23 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import javax.xml.bind.annotation.XmlEnum;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for ThresholdType.
+ * <p>
+ * Java class for ThresholdType.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
  * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
+ * <p>
+ * 
  * <pre>
  * &lt;simpleType name="ThresholdType">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -30,18 +32,19 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlType(name = "ThresholdType", namespace = "www.jalview.org/colours")
 @XmlEnum
-public enum ThresholdType {
+public enum ThresholdType
+{
 
-    NONE,
-    ABOVE,
-    BELOW;
+  NONE, ABOVE, BELOW;
 
-    public String value() {
-        return name();
-    }
+  public String value()
+  {
+    return name();
+  }
 
-    public static ThresholdType fromValue(String v) {
-        return valueOf(v);
-    }
+  public static ThresholdType fromValue(String v)
+  {
+    return valueOf(v);
+  }
 
 }
index dd41877..099af84 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -15,11 +14,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for VAMSAS complex type.
+ * <p>
+ * Java class for VAMSAS complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="VAMSAS">
@@ -37,73 +38,77 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "VAMSAS", propOrder = {
-    "tree",
-    "sequenceSet"
-})
-public class VAMSAS {
+@XmlType(name = "VAMSAS", propOrder = { "tree", "sequenceSet" })
+public class VAMSAS
+{
+
+  @XmlElement(name = "Tree")
+  protected List<String> tree;
 
-    @XmlElement(name = "Tree")
-    protected List<String> tree;
-    @XmlElement(name = "SequenceSet")
-    protected List<SequenceSet> sequenceSet;
+  @XmlElement(name = "SequenceSet")
+  protected List<SequenceSet> sequenceSet;
 
-    /**
-     * Gets the value of the tree property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the tree property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getTree().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getTree() {
-        if (tree == null) {
-            tree = new ArrayList<String>();
-        }
-        return this.tree;
+  /**
+   * Gets the value of the tree property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the tree property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getTree().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getTree()
+  {
+    if (tree == null)
+    {
+      tree = new ArrayList<String>();
     }
+    return this.tree;
+  }
 
-    /**
-     * Gets the value of the sequenceSet property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the sequenceSet property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getSequenceSet().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link SequenceSet }
-     * 
-     * 
-     */
-    public List<SequenceSet> getSequenceSet() {
-        if (sequenceSet == null) {
-            sequenceSet = new ArrayList<SequenceSet>();
-        }
-        return this.sequenceSet;
+  /**
+   * Gets the value of the sequenceSet property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the sequenceSet property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getSequenceSet().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link SequenceSet
+   * }
+   * 
+   * 
+   */
+  public List<SequenceSet> getSequenceSet()
+  {
+    if (sequenceSet == null)
+    {
+      sequenceSet = new ArrayList<SequenceSet>();
     }
+    return this.sequenceSet;
+  }
 
 }
index d3c2098..4374c83 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-
 package jalview.xml.binding.jalview;
 
 import java.util.ArrayList;
@@ -18,11 +17,13 @@ import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for WebServiceParameterSet complex type.
+ * <p>
+ * Java class for WebServiceParameterSet complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="WebServiceParameterSet">
@@ -43,152 +44,153 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "WebServiceParameterSet", namespace = "www.jalview.org/xml/wsparamset", propOrder = {
-    "version",
-    "description",
-    "serviceURL",
-    "parameters"
-})
+@XmlType(
+  name = "WebServiceParameterSet",
+  namespace = "www.jalview.org/xml/wsparamset",
+  propOrder =
+  { "version", "description", "serviceURL", "parameters" })
 @XmlSeeAlso({
-    jalview.xml.binding.jalview.JalviewModel.Viewport.CalcIdParam.class
-})
-public class WebServiceParameterSet {
-
-    @XmlElement(name = "Version", namespace = "")
-    protected String version;
-    @XmlElement(namespace = "")
-    protected String description;
-    @XmlElement(namespace = "", required = true)
-    @XmlSchemaType(name = "anyURI")
-    protected List<String> serviceURL;
-    @XmlElement(namespace = "", required = true)
-    protected String parameters;
-    @XmlAttribute(name = "name", required = true)
-    protected String name;
-
-    /**
-     * Gets the value of the version property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getVersion() {
-        return version;
-    }
-
-    /**
-     * Sets the value of the version property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setVersion(String value) {
-        this.version = value;
-    }
-
-    /**
-     * Gets the value of the description property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDescription() {
-        return description;
-    }
-
-    /**
-     * Sets the value of the description property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDescription(String value) {
-        this.description = value;
-    }
-
-    /**
-     * Gets the value of the serviceURL property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the serviceURL property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getServiceURL().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getServiceURL() {
-        if (serviceURL == null) {
-            serviceURL = new ArrayList<String>();
-        }
-        return this.serviceURL;
-    }
-
-    /**
-     * Gets the value of the parameters property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getParameters() {
-        return parameters;
-    }
-
-    /**
-     * Sets the value of the parameters property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setParameters(String value) {
-        this.parameters = value;
-    }
-
-    /**
-     * Gets the value of the name property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Sets the value of the name property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setName(String value) {
-        this.name = value;
+    jalview.xml.binding.jalview.JalviewModel.Viewport.CalcIdParam.class })
+public class WebServiceParameterSet
+{
+
+  @XmlElement(name = "Version", namespace = "")
+  protected String version;
+
+  @XmlElement(namespace = "")
+  protected String description;
+
+  @XmlElement(namespace = "", required = true)
+  @XmlSchemaType(name = "anyURI")
+  protected List<String> serviceURL;
+
+  @XmlElement(namespace = "", required = true)
+  protected String parameters;
+
+  @XmlAttribute(name = "name", required = true)
+  protected String name;
+
+  /**
+   * Gets the value of the version property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getVersion()
+  {
+    return version;
+  }
+
+  /**
+   * Sets the value of the version property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setVersion(String value)
+  {
+    this.version = value;
+  }
+
+  /**
+   * Gets the value of the description property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /**
+   * Sets the value of the description property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDescription(String value)
+  {
+    this.description = value;
+  }
+
+  /**
+   * Gets the value of the serviceURL property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the serviceURL property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getServiceURL().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getServiceURL()
+  {
+    if (serviceURL == null)
+    {
+      serviceURL = new ArrayList<String>();
     }
+    return this.serviceURL;
+  }
+
+  /**
+   * Gets the value of the parameters property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getParameters()
+  {
+    return parameters;
+  }
+
+  /**
+   * Sets the value of the parameters property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setParameters(String value)
+  {
+    this.parameters = value;
+  }
+
+  /**
+   * Gets the value of the name property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Sets the value of the name property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setName(String value)
+  {
+    this.name = value;
+  }
 
 }
index 2cfefda..65d49d5 100644 (file)
@@ -2,8 +2,10 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:44 PM GMT 
+// Generated on: 2023.05.13 at 06:58:41 PM BST 
 //
 
-@javax.xml.bind.annotation.XmlSchema(namespace = "www.vamsas.ac.uk/jalview/version2", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+@javax.xml.bind.annotation.XmlSchema(
+  namespace = "www.vamsas.ac.uk/jalview/version2",
+  elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
 package jalview.xml.binding.jalview;
index de12eb2..c5980b3 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -15,14 +14,16 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes different types of citations.
- *             Equivalent to the flat file RX-, RG-, RA-, RT- and RL-lines.
+ * Describes different types of citations. Equivalent to the flat file RX-, RG-,
+ * RA-, RT- and RL-lines.
  * 
- * <p>Java class for citationType complex type.
+ * <p>
+ * Java class for citationType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="citationType">
@@ -72,456 +73,457 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "citationType", propOrder = {
-    "title",
-    "editorList",
-    "authorList",
-    "locator",
-    "dbReference"
-})
-public class CitationType {
-
-    protected String title;
-    protected NameListType editorList;
-    protected NameListType authorList;
-    protected String locator;
-    protected List<DbReferenceType> dbReference;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "date")
-    protected String date;
-    @XmlAttribute(name = "name")
-    protected String name;
-    @XmlAttribute(name = "volume")
-    protected String volume;
-    @XmlAttribute(name = "first")
-    protected String first;
-    @XmlAttribute(name = "last")
-    protected String last;
-    @XmlAttribute(name = "publisher")
-    protected String publisher;
-    @XmlAttribute(name = "city")
-    protected String city;
-    @XmlAttribute(name = "db")
-    protected String db;
-    @XmlAttribute(name = "number")
-    protected String number;
-    @XmlAttribute(name = "institute")
-    protected String institute;
-    @XmlAttribute(name = "country")
-    protected String country;
-
-    /**
-     * Gets the value of the title property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getTitle() {
-        return title;
-    }
-
-    /**
-     * Sets the value of the title property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setTitle(String value) {
-        this.title = value;
-    }
-
-    /**
-     * Gets the value of the editorList property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link NameListType }
-     *     
-     */
-    public NameListType getEditorList() {
-        return editorList;
-    }
-
-    /**
-     * Sets the value of the editorList property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link NameListType }
-     *     
-     */
-    public void setEditorList(NameListType value) {
-        this.editorList = value;
-    }
-
-    /**
-     * Gets the value of the authorList property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link NameListType }
-     *     
-     */
-    public NameListType getAuthorList() {
-        return authorList;
-    }
-
-    /**
-     * Sets the value of the authorList property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link NameListType }
-     *     
-     */
-    public void setAuthorList(NameListType value) {
-        this.authorList = value;
-    }
-
-    /**
-     * Gets the value of the locator property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getLocator() {
-        return locator;
-    }
-
-    /**
-     * Sets the value of the locator property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setLocator(String value) {
-        this.locator = value;
-    }
-
-    /**
-     * Gets the value of the dbReference property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the dbReference property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getDbReference().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link DbReferenceType }
-     * 
-     * 
-     */
-    public List<DbReferenceType> getDbReference() {
-        if (dbReference == null) {
-            dbReference = new ArrayList<DbReferenceType>();
-        }
-        return this.dbReference;
-    }
-
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
-
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
-
-    /**
-     * Gets the value of the date property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDate() {
-        return date;
-    }
-
-    /**
-     * Sets the value of the date property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDate(String value) {
-        this.date = value;
-    }
-
-    /**
-     * Gets the value of the name property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Sets the value of the name property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setName(String value) {
-        this.name = value;
-    }
-
-    /**
-     * Gets the value of the volume property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getVolume() {
-        return volume;
-    }
-
-    /**
-     * Sets the value of the volume property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setVolume(String value) {
-        this.volume = value;
-    }
-
-    /**
-     * Gets the value of the first property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getFirst() {
-        return first;
-    }
-
-    /**
-     * Sets the value of the first property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setFirst(String value) {
-        this.first = value;
-    }
-
-    /**
-     * Gets the value of the last property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getLast() {
-        return last;
-    }
-
-    /**
-     * Sets the value of the last property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setLast(String value) {
-        this.last = value;
-    }
-
-    /**
-     * Gets the value of the publisher property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getPublisher() {
-        return publisher;
-    }
-
-    /**
-     * Sets the value of the publisher property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setPublisher(String value) {
-        this.publisher = value;
-    }
-
-    /**
-     * Gets the value of the city property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getCity() {
-        return city;
-    }
-
-    /**
-     * Sets the value of the city property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setCity(String value) {
-        this.city = value;
-    }
-
-    /**
-     * Gets the value of the db property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDb() {
-        return db;
-    }
-
-    /**
-     * Sets the value of the db property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDb(String value) {
-        this.db = value;
-    }
-
-    /**
-     * Gets the value of the number property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getNumber() {
-        return number;
-    }
-
-    /**
-     * Sets the value of the number property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setNumber(String value) {
-        this.number = value;
-    }
-
-    /**
-     * Gets the value of the institute property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getInstitute() {
-        return institute;
-    }
-
-    /**
-     * Sets the value of the institute property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setInstitute(String value) {
-        this.institute = value;
-    }
-
-    /**
-     * Gets the value of the country property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getCountry() {
-        return country;
-    }
-
-    /**
-     * Sets the value of the country property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setCountry(String value) {
-        this.country = value;
-    }
+@XmlType(
+  name = "citationType",
+  propOrder =
+  { "title", "editorList", "authorList", "locator", "dbReference" })
+public class CitationType
+{
+
+  protected String title;
+
+  protected NameListType editorList;
+
+  protected NameListType authorList;
+
+  protected String locator;
+
+  protected List<DbReferenceType> dbReference;
+
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
+
+  @XmlAttribute(name = "date")
+  protected String date;
+
+  @XmlAttribute(name = "name")
+  protected String name;
+
+  @XmlAttribute(name = "volume")
+  protected String volume;
+
+  @XmlAttribute(name = "first")
+  protected String first;
+
+  @XmlAttribute(name = "last")
+  protected String last;
+
+  @XmlAttribute(name = "publisher")
+  protected String publisher;
+
+  @XmlAttribute(name = "city")
+  protected String city;
+
+  @XmlAttribute(name = "db")
+  protected String db;
+
+  @XmlAttribute(name = "number")
+  protected String number;
+
+  @XmlAttribute(name = "institute")
+  protected String institute;
+
+  @XmlAttribute(name = "country")
+  protected String country;
+
+  /**
+   * Gets the value of the title property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getTitle()
+  {
+    return title;
+  }
+
+  /**
+   * Sets the value of the title property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setTitle(String value)
+  {
+    this.title = value;
+  }
+
+  /**
+   * Gets the value of the editorList property.
+   * 
+   * @return possible object is {@link NameListType }
+   * 
+   */
+  public NameListType getEditorList()
+  {
+    return editorList;
+  }
+
+  /**
+   * Sets the value of the editorList property.
+   * 
+   * @param value
+   *          allowed object is {@link NameListType }
+   * 
+   */
+  public void setEditorList(NameListType value)
+  {
+    this.editorList = value;
+  }
+
+  /**
+   * Gets the value of the authorList property.
+   * 
+   * @return possible object is {@link NameListType }
+   * 
+   */
+  public NameListType getAuthorList()
+  {
+    return authorList;
+  }
+
+  /**
+   * Sets the value of the authorList property.
+   * 
+   * @param value
+   *          allowed object is {@link NameListType }
+   * 
+   */
+  public void setAuthorList(NameListType value)
+  {
+    this.authorList = value;
+  }
+
+  /**
+   * Gets the value of the locator property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getLocator()
+  {
+    return locator;
+  }
+
+  /**
+   * Sets the value of the locator property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setLocator(String value)
+  {
+    this.locator = value;
+  }
+
+  /**
+   * Gets the value of the dbReference property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the dbReference property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getDbReference().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link DbReferenceType }
+   * 
+   * 
+   */
+  public List<DbReferenceType> getDbReference()
+  {
+    if (dbReference == null)
+    {
+      dbReference = new ArrayList<DbReferenceType>();
+    }
+    return this.dbReference;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
+
+  /**
+   * Gets the value of the date property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDate()
+  {
+    return date;
+  }
+
+  /**
+   * Sets the value of the date property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDate(String value)
+  {
+    this.date = value;
+  }
+
+  /**
+   * Gets the value of the name property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Sets the value of the name property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setName(String value)
+  {
+    this.name = value;
+  }
+
+  /**
+   * Gets the value of the volume property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getVolume()
+  {
+    return volume;
+  }
+
+  /**
+   * Sets the value of the volume property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setVolume(String value)
+  {
+    this.volume = value;
+  }
+
+  /**
+   * Gets the value of the first property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getFirst()
+  {
+    return first;
+  }
+
+  /**
+   * Sets the value of the first property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setFirst(String value)
+  {
+    this.first = value;
+  }
+
+  /**
+   * Gets the value of the last property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getLast()
+  {
+    return last;
+  }
+
+  /**
+   * Sets the value of the last property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setLast(String value)
+  {
+    this.last = value;
+  }
+
+  /**
+   * Gets the value of the publisher property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getPublisher()
+  {
+    return publisher;
+  }
+
+  /**
+   * Sets the value of the publisher property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setPublisher(String value)
+  {
+    this.publisher = value;
+  }
+
+  /**
+   * Gets the value of the city property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getCity()
+  {
+    return city;
+  }
+
+  /**
+   * Sets the value of the city property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setCity(String value)
+  {
+    this.city = value;
+  }
+
+  /**
+   * Gets the value of the db property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDb()
+  {
+    return db;
+  }
+
+  /**
+   * Sets the value of the db property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDb(String value)
+  {
+    this.db = value;
+  }
+
+  /**
+   * Gets the value of the number property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getNumber()
+  {
+    return number;
+  }
+
+  /**
+   * Sets the value of the number property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setNumber(String value)
+  {
+    this.number = value;
+  }
+
+  /**
+   * Gets the value of the institute property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getInstitute()
+  {
+    return institute;
+  }
+
+  /**
+   * Sets the value of the institute property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setInstitute(String value)
+  {
+    this.institute = value;
+  }
+
+  /**
+   * Gets the value of the country property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getCountry()
+  {
+    return country;
+  }
+
+  /**
+   * Sets the value of the country property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setCountry(String value)
+  {
+    this.country = value;
+  }
 
 }
index e9244e9..d7f0cdb 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,13 +15,15 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * Describes a cofactor.
  * 
- * <p>Java class for cofactorType complex type.
+ * <p>
+ * Java class for cofactorType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="cofactorType">
@@ -41,94 +42,94 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "cofactorType", propOrder = {
-    "name",
-    "dbReference"
-})
-public class CofactorType {
+@XmlType(name = "cofactorType", propOrder = { "name", "dbReference" })
+public class CofactorType
+{
 
-    @XmlElement(required = true)
-    protected String name;
-    @XmlElement(required = true)
-    protected DbReferenceType dbReference;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
+  @XmlElement(required = true)
+  protected String name;
 
-    /**
-     * Gets the value of the name property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getName() {
-        return name;
-    }
+  @XmlElement(required = true)
+  protected DbReferenceType dbReference;
 
-    /**
-     * Sets the value of the name property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setName(String value) {
-        this.name = value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Gets the value of the dbReference property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DbReferenceType }
-     *     
-     */
-    public DbReferenceType getDbReference() {
-        return dbReference;
-    }
+  /**
+   * Gets the value of the name property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getName()
+  {
+    return name;
+  }
 
-    /**
-     * Sets the value of the dbReference property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DbReferenceType }
-     *     
-     */
-    public void setDbReference(DbReferenceType value) {
-        this.dbReference = value;
-    }
+  /**
+   * Sets the value of the name property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setName(String value)
+  {
+    this.name = value;
+  }
+
+  /**
+   * Gets the value of the dbReference property.
+   * 
+   * @return possible object is {@link DbReferenceType }
+   * 
+   */
+  public DbReferenceType getDbReference()
+  {
+    return dbReference;
+  }
+
+  /**
+   * Sets the value of the dbReference property.
+   * 
+   * @param value
+   *          allowed object is {@link DbReferenceType }
+   * 
+   */
+  public void setDbReference(DbReferenceType value)
+  {
+    this.dbReference = value;
+  }
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
 
 }
index e0692c9..0477736 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -17,14 +16,16 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes different types of general annotations.
- *             Equivalent to the flat file CC-line.
+ * Describes different types of general annotations. Equivalent to the flat file
+ * CC-line.
  * 
- * <p>Java class for commentType complex type.
+ * <p>
+ * Java class for commentType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="commentType">
@@ -173,1619 +174,1673 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "commentType", propOrder = {
-    "molecule",
-    "absorption",
-    "kinetics",
-    "phDependence",
-    "redoxPotential",
-    "temperatureDependence",
-    "reaction",
-    "physiologicalReaction",
-    "cofactor",
-    "subcellularLocation",
-    "conflict",
-    "link",
-    "event",
-    "isoform",
-    "interactant",
-    "organismsDiffer",
-    "experiments",
-    "disease",
-    "location",
-    "text"
-})
-public class CommentType {
-
-    protected MoleculeType molecule;
-    protected CommentType.Absorption absorption;
-    protected CommentType.Kinetics kinetics;
-    protected CommentType.PhDependence phDependence;
-    protected CommentType.RedoxPotential redoxPotential;
-    protected CommentType.TemperatureDependence temperatureDependence;
-    protected ReactionType reaction;
-    protected List<PhysiologicalReactionType> physiologicalReaction;
-    protected List<CofactorType> cofactor;
-    protected List<SubcellularLocationType> subcellularLocation;
-    protected CommentType.Conflict conflict;
-    protected List<CommentType.Link> link;
-    protected List<EventType> event;
-    protected List<IsoformType> isoform;
-    protected List<InteractantType> interactant;
-    @XmlElement(defaultValue = "false")
-    protected Boolean organismsDiffer;
-    protected Integer experiments;
-    protected CommentType.Disease disease;
-    protected List<LocationType> location;
-    protected List<EvidencedStringType> text;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "locationType")
-    protected String locationType;
-    @XmlAttribute(name = "name")
-    protected String name;
-    @XmlAttribute(name = "mass")
-    protected Float mass;
-    @XmlAttribute(name = "error")
-    protected String error;
-    @XmlAttribute(name = "method")
-    protected String method;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
+@XmlType(
+  name = "commentType",
+  propOrder =
+  { "molecule", "absorption", "kinetics", "phDependence", "redoxPotential",
+      "temperatureDependence", "reaction", "physiologicalReaction",
+      "cofactor", "subcellularLocation", "conflict", "link", "event",
+      "isoform", "interactant", "organismsDiffer", "experiments", "disease",
+      "location", "text" })
+public class CommentType
+{
 
-    /**
-     * Gets the value of the molecule property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link MoleculeType }
-     *     
-     */
-    public MoleculeType getMolecule() {
-        return molecule;
-    }
+  protected MoleculeType molecule;
 
-    /**
-     * Sets the value of the molecule property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link MoleculeType }
-     *     
-     */
-    public void setMolecule(MoleculeType value) {
-        this.molecule = value;
-    }
+  protected CommentType.Absorption absorption;
 
-    /**
-     * Gets the value of the absorption property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link CommentType.Absorption }
-     *     
-     */
-    public CommentType.Absorption getAbsorption() {
-        return absorption;
-    }
+  protected CommentType.Kinetics kinetics;
 
-    /**
-     * Sets the value of the absorption property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link CommentType.Absorption }
-     *     
-     */
-    public void setAbsorption(CommentType.Absorption value) {
-        this.absorption = value;
-    }
+  protected CommentType.PhDependence phDependence;
 
-    /**
-     * Gets the value of the kinetics property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link CommentType.Kinetics }
-     *     
-     */
-    public CommentType.Kinetics getKinetics() {
-        return kinetics;
-    }
+  protected CommentType.RedoxPotential redoxPotential;
 
-    /**
-     * Sets the value of the kinetics property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link CommentType.Kinetics }
-     *     
-     */
-    public void setKinetics(CommentType.Kinetics value) {
-        this.kinetics = value;
-    }
+  protected CommentType.TemperatureDependence temperatureDependence;
 
-    /**
-     * Gets the value of the phDependence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link CommentType.PhDependence }
-     *     
-     */
-    public CommentType.PhDependence getPhDependence() {
-        return phDependence;
-    }
+  protected ReactionType reaction;
 
-    /**
-     * Sets the value of the phDependence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link CommentType.PhDependence }
-     *     
-     */
-    public void setPhDependence(CommentType.PhDependence value) {
-        this.phDependence = value;
-    }
+  protected List<PhysiologicalReactionType> physiologicalReaction;
 
-    /**
-     * Gets the value of the redoxPotential property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link CommentType.RedoxPotential }
-     *     
-     */
-    public CommentType.RedoxPotential getRedoxPotential() {
-        return redoxPotential;
-    }
+  protected List<CofactorType> cofactor;
 
-    /**
-     * Sets the value of the redoxPotential property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link CommentType.RedoxPotential }
-     *     
-     */
-    public void setRedoxPotential(CommentType.RedoxPotential value) {
-        this.redoxPotential = value;
-    }
+  protected List<SubcellularLocationType> subcellularLocation;
 
-    /**
-     * Gets the value of the temperatureDependence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link CommentType.TemperatureDependence }
-     *     
-     */
-    public CommentType.TemperatureDependence getTemperatureDependence() {
-        return temperatureDependence;
-    }
+  protected CommentType.Conflict conflict;
 
-    /**
-     * Sets the value of the temperatureDependence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link CommentType.TemperatureDependence }
-     *     
-     */
-    public void setTemperatureDependence(CommentType.TemperatureDependence value) {
-        this.temperatureDependence = value;
+  protected List<CommentType.Link> link;
+
+  protected List<EventType> event;
+
+  protected List<IsoformType> isoform;
+
+  protected List<InteractantType> interactant;
+
+  @XmlElement(defaultValue = "false")
+  protected Boolean organismsDiffer;
+
+  protected Integer experiments;
+
+  protected CommentType.Disease disease;
+
+  protected List<LocationType> location;
+
+  protected List<EvidencedStringType> text;
+
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
+
+  @XmlAttribute(name = "locationType")
+  protected String locationType;
+
+  @XmlAttribute(name = "name")
+  protected String name;
+
+  @XmlAttribute(name = "mass")
+  protected Float mass;
+
+  @XmlAttribute(name = "error")
+  protected String error;
+
+  @XmlAttribute(name = "method")
+  protected String method;
+
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
+
+  /**
+   * Gets the value of the molecule property.
+   * 
+   * @return possible object is {@link MoleculeType }
+   * 
+   */
+  public MoleculeType getMolecule()
+  {
+    return molecule;
+  }
+
+  /**
+   * Sets the value of the molecule property.
+   * 
+   * @param value
+   *          allowed object is {@link MoleculeType }
+   * 
+   */
+  public void setMolecule(MoleculeType value)
+  {
+    this.molecule = value;
+  }
+
+  /**
+   * Gets the value of the absorption property.
+   * 
+   * @return possible object is {@link CommentType.Absorption }
+   * 
+   */
+  public CommentType.Absorption getAbsorption()
+  {
+    return absorption;
+  }
+
+  /**
+   * Sets the value of the absorption property.
+   * 
+   * @param value
+   *          allowed object is {@link CommentType.Absorption }
+   * 
+   */
+  public void setAbsorption(CommentType.Absorption value)
+  {
+    this.absorption = value;
+  }
+
+  /**
+   * Gets the value of the kinetics property.
+   * 
+   * @return possible object is {@link CommentType.Kinetics }
+   * 
+   */
+  public CommentType.Kinetics getKinetics()
+  {
+    return kinetics;
+  }
+
+  /**
+   * Sets the value of the kinetics property.
+   * 
+   * @param value
+   *          allowed object is {@link CommentType.Kinetics }
+   * 
+   */
+  public void setKinetics(CommentType.Kinetics value)
+  {
+    this.kinetics = value;
+  }
+
+  /**
+   * Gets the value of the phDependence property.
+   * 
+   * @return possible object is {@link CommentType.PhDependence }
+   * 
+   */
+  public CommentType.PhDependence getPhDependence()
+  {
+    return phDependence;
+  }
+
+  /**
+   * Sets the value of the phDependence property.
+   * 
+   * @param value
+   *          allowed object is {@link CommentType.PhDependence }
+   * 
+   */
+  public void setPhDependence(CommentType.PhDependence value)
+  {
+    this.phDependence = value;
+  }
+
+  /**
+   * Gets the value of the redoxPotential property.
+   * 
+   * @return possible object is {@link CommentType.RedoxPotential }
+   * 
+   */
+  public CommentType.RedoxPotential getRedoxPotential()
+  {
+    return redoxPotential;
+  }
+
+  /**
+   * Sets the value of the redoxPotential property.
+   * 
+   * @param value
+   *          allowed object is {@link CommentType.RedoxPotential }
+   * 
+   */
+  public void setRedoxPotential(CommentType.RedoxPotential value)
+  {
+    this.redoxPotential = value;
+  }
+
+  /**
+   * Gets the value of the temperatureDependence property.
+   * 
+   * @return possible object is {@link CommentType.TemperatureDependence }
+   * 
+   */
+  public CommentType.TemperatureDependence getTemperatureDependence()
+  {
+    return temperatureDependence;
+  }
+
+  /**
+   * Sets the value of the temperatureDependence property.
+   * 
+   * @param value
+   *          allowed object is {@link CommentType.TemperatureDependence }
+   * 
+   */
+  public void setTemperatureDependence(
+          CommentType.TemperatureDependence value)
+  {
+    this.temperatureDependence = value;
+  }
+
+  /**
+   * Gets the value of the reaction property.
+   * 
+   * @return possible object is {@link ReactionType }
+   * 
+   */
+  public ReactionType getReaction()
+  {
+    return reaction;
+  }
+
+  /**
+   * Sets the value of the reaction property.
+   * 
+   * @param value
+   *          allowed object is {@link ReactionType }
+   * 
+   */
+  public void setReaction(ReactionType value)
+  {
+    this.reaction = value;
+  }
+
+  /**
+   * Gets the value of the physiologicalReaction property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the physiologicalReaction property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getPhysiologicalReaction().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link PhysiologicalReactionType }
+   * 
+   * 
+   */
+  public List<PhysiologicalReactionType> getPhysiologicalReaction()
+  {
+    if (physiologicalReaction == null)
+    {
+      physiologicalReaction = new ArrayList<PhysiologicalReactionType>();
+    }
+    return this.physiologicalReaction;
+  }
+
+  /**
+   * Gets the value of the cofactor property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the cofactor property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getCofactor().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link CofactorType }
+   * 
+   * 
+   */
+  public List<CofactorType> getCofactor()
+  {
+    if (cofactor == null)
+    {
+      cofactor = new ArrayList<CofactorType>();
+    }
+    return this.cofactor;
+  }
+
+  /**
+   * Gets the value of the subcellularLocation property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the subcellularLocation property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getSubcellularLocation().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link SubcellularLocationType }
+   * 
+   * 
+   */
+  public List<SubcellularLocationType> getSubcellularLocation()
+  {
+    if (subcellularLocation == null)
+    {
+      subcellularLocation = new ArrayList<SubcellularLocationType>();
+    }
+    return this.subcellularLocation;
+  }
+
+  /**
+   * Gets the value of the conflict property.
+   * 
+   * @return possible object is {@link CommentType.Conflict }
+   * 
+   */
+  public CommentType.Conflict getConflict()
+  {
+    return conflict;
+  }
+
+  /**
+   * Sets the value of the conflict property.
+   * 
+   * @param value
+   *          allowed object is {@link CommentType.Conflict }
+   * 
+   */
+  public void setConflict(CommentType.Conflict value)
+  {
+    this.conflict = value;
+  }
+
+  /**
+   * Gets the value of the link property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the link property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getLink().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link CommentType.Link }
+   * 
+   * 
+   */
+  public List<CommentType.Link> getLink()
+  {
+    if (link == null)
+    {
+      link = new ArrayList<CommentType.Link>();
     }
+    return this.link;
+  }
+
+  /**
+   * Gets the value of the event property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the event property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvent().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link EventType }
+   * 
+   * 
+   */
+  public List<EventType> getEvent()
+  {
+    if (event == null)
+    {
+      event = new ArrayList<EventType>();
+    }
+    return this.event;
+  }
+
+  /**
+   * Gets the value of the isoform property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the isoform property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getIsoform().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link IsoformType
+   * }
+   * 
+   * 
+   */
+  public List<IsoformType> getIsoform()
+  {
+    if (isoform == null)
+    {
+      isoform = new ArrayList<IsoformType>();
+    }
+    return this.isoform;
+  }
+
+  /**
+   * Gets the value of the interactant property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the interactant property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getInteractant().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link InteractantType }
+   * 
+   * 
+   */
+  public List<InteractantType> getInteractant()
+  {
+    if (interactant == null)
+    {
+      interactant = new ArrayList<InteractantType>();
+    }
+    return this.interactant;
+  }
+
+  /**
+   * Gets the value of the organismsDiffer property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public Boolean isOrganismsDiffer()
+  {
+    return organismsDiffer;
+  }
+
+  /**
+   * Sets the value of the organismsDiffer property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setOrganismsDiffer(Boolean value)
+  {
+    this.organismsDiffer = value;
+  }
+
+  /**
+   * Gets the value of the experiments property.
+   * 
+   * @return possible object is {@link Integer }
+   * 
+   */
+  public Integer getExperiments()
+  {
+    return experiments;
+  }
+
+  /**
+   * Sets the value of the experiments property.
+   * 
+   * @param value
+   *          allowed object is {@link Integer }
+   * 
+   */
+  public void setExperiments(Integer value)
+  {
+    this.experiments = value;
+  }
+
+  /**
+   * Gets the value of the disease property.
+   * 
+   * @return possible object is {@link CommentType.Disease }
+   * 
+   */
+  public CommentType.Disease getDisease()
+  {
+    return disease;
+  }
+
+  /**
+   * Sets the value of the disease property.
+   * 
+   * @param value
+   *          allowed object is {@link CommentType.Disease }
+   * 
+   */
+  public void setDisease(CommentType.Disease value)
+  {
+    this.disease = value;
+  }
+
+  /**
+   * Gets the value of the location property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the location property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getLocation().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link LocationType }
+   * 
+   * 
+   */
+  public List<LocationType> getLocation()
+  {
+    if (location == null)
+    {
+      location = new ArrayList<LocationType>();
+    }
+    return this.location;
+  }
+
+  /**
+   * Gets the value of the text property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the text property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getText().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EvidencedStringType }
+   * 
+   * 
+   */
+  public List<EvidencedStringType> getText()
+  {
+    if (text == null)
+    {
+      text = new ArrayList<EvidencedStringType>();
+    }
+    return this.text;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
+
+  /**
+   * Gets the value of the locationType property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getLocationType()
+  {
+    return locationType;
+  }
+
+  /**
+   * Sets the value of the locationType property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setLocationType(String value)
+  {
+    this.locationType = value;
+  }
+
+  /**
+   * Gets the value of the name property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Sets the value of the name property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setName(String value)
+  {
+    this.name = value;
+  }
+
+  /**
+   * Gets the value of the mass property.
+   * 
+   * @return possible object is {@link Float }
+   * 
+   */
+  public Float getMass()
+  {
+    return mass;
+  }
+
+  /**
+   * Sets the value of the mass property.
+   * 
+   * @param value
+   *          allowed object is {@link Float }
+   * 
+   */
+  public void setMass(Float value)
+  {
+    this.mass = value;
+  }
+
+  /**
+   * Gets the value of the error property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getError()
+  {
+    return error;
+  }
+
+  /**
+   * Sets the value of the error property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setError(String value)
+  {
+    this.error = value;
+  }
+
+  /**
+   * Gets the value of the method property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getMethod()
+  {
+    return method;
+  }
+
+  /**
+   * Sets the value of the method property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setMethod(String value)
+  {
+    this.method = value;
+  }
+
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
+    }
+    return this.evidence;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="max" type="{http://uniprot.org/uniprot}evidencedStringType" minOccurs="0"/>
+   *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "max", "text" })
+  public static class Absorption
+  {
+
+    protected EvidencedStringType max;
+
+    protected List<EvidencedStringType> text;
 
     /**
-     * Gets the value of the reaction property.
+     * Gets the value of the max property.
+     * 
+     * @return possible object is {@link EvidencedStringType }
      * 
-     * @return
-     *     possible object is
-     *     {@link ReactionType }
-     *     
      */
-    public ReactionType getReaction() {
-        return reaction;
+    public EvidencedStringType getMax()
+    {
+      return max;
     }
 
     /**
-     * Sets the value of the reaction property.
+     * Sets the value of the max property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link ReactionType }
-     *     
+     *          allowed object is {@link EvidencedStringType }
+     * 
      */
-    public void setReaction(ReactionType value) {
-        this.reaction = value;
+    public void setMax(EvidencedStringType value)
+    {
+      this.max = value;
     }
 
     /**
-     * Gets the value of the physiologicalReaction property.
+     * Gets the value of the text property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the physiologicalReaction property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the text property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getPhysiologicalReaction().add(newItem);
+     * getText().add(newItem);
      * </pre>
      * 
      * 
      * <p>
      * Objects of the following type(s) are allowed in the list
-     * {@link PhysiologicalReactionType }
+     * {@link EvidencedStringType }
      * 
      * 
      */
-    public List<PhysiologicalReactionType> getPhysiologicalReaction() {
-        if (physiologicalReaction == null) {
-            physiologicalReaction = new ArrayList<PhysiologicalReactionType>();
-        }
-        return this.physiologicalReaction;
+    public List<EvidencedStringType> getText()
+    {
+      if (text == null)
+      {
+        text = new ArrayList<EvidencedStringType>();
+      }
+      return this.text;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="sequence" minOccurs="0">
+   *           &lt;complexType>
+   *             &lt;complexContent>
+   *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *                 &lt;attribute name="resource" use="required">
+   *                   &lt;simpleType>
+   *                     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+   *                       &lt;enumeration value="EMBL-CDS"/>
+   *                       &lt;enumeration value="EMBL"/>
+   *                     &lt;/restriction>
+   *                   &lt;/simpleType>
+   *                 &lt;/attribute>
+   *                 &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *                 &lt;attribute name="version" type="{http://www.w3.org/2001/XMLSchema}int" />
+   *               &lt;/restriction>
+   *             &lt;/complexContent>
+   *           &lt;/complexType>
+   *         &lt;/element>
+   *       &lt;/sequence>
+   *       &lt;attribute name="type" use="required">
+   *         &lt;simpleType>
+   *           &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+   *             &lt;enumeration value="frameshift"/>
+   *             &lt;enumeration value="erroneous initiation"/>
+   *             &lt;enumeration value="erroneous termination"/>
+   *             &lt;enumeration value="erroneous gene model prediction"/>
+   *             &lt;enumeration value="erroneous translation"/>
+   *             &lt;enumeration value="miscellaneous discrepancy"/>
+   *           &lt;/restriction>
+   *         &lt;/simpleType>
+   *       &lt;/attribute>
+   *       &lt;attribute name="ref" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "sequence" })
+  public static class Conflict
+  {
+
+    protected CommentType.Conflict.Sequence sequence;
+
+    @XmlAttribute(name = "type", required = true)
+    protected String type;
+
+    @XmlAttribute(name = "ref")
+    protected String ref;
+
     /**
-     * Gets the value of the cofactor property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the cofactor property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getCofactor().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link CofactorType }
+     * Gets the value of the sequence property.
      * 
+     * @return possible object is {@link CommentType.Conflict.Sequence }
      * 
      */
-    public List<CofactorType> getCofactor() {
-        if (cofactor == null) {
-            cofactor = new ArrayList<CofactorType>();
-        }
-        return this.cofactor;
+    public CommentType.Conflict.Sequence getSequence()
+    {
+      return sequence;
     }
 
     /**
-     * Gets the value of the subcellularLocation property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the subcellularLocation property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getSubcellularLocation().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link SubcellularLocationType }
+     * Sets the value of the sequence property.
      * 
+     * @param value
+     *          allowed object is {@link CommentType.Conflict.Sequence }
      * 
      */
-    public List<SubcellularLocationType> getSubcellularLocation() {
-        if (subcellularLocation == null) {
-            subcellularLocation = new ArrayList<SubcellularLocationType>();
-        }
-        return this.subcellularLocation;
+    public void setSequence(CommentType.Conflict.Sequence value)
+    {
+      this.sequence = value;
     }
 
     /**
-     * Gets the value of the conflict property.
+     * Gets the value of the type property.
      * 
-     * @return
-     *     possible object is
-     *     {@link CommentType.Conflict }
-     *     
-     */
-    public CommentType.Conflict getConflict() {
-        return conflict;
-    }
-
-    /**
-     * Sets the value of the conflict property.
+     * @return possible object is {@link String }
      * 
-     * @param value
-     *     allowed object is
-     *     {@link CommentType.Conflict }
-     *     
      */
-    public void setConflict(CommentType.Conflict value) {
-        this.conflict = value;
+    public String getType()
+    {
+      return type;
     }
 
     /**
-     * Gets the value of the link property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the link property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getLink().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link CommentType.Link }
+     * Sets the value of the type property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    public List<CommentType.Link> getLink() {
-        if (link == null) {
-            link = new ArrayList<CommentType.Link>();
-        }
-        return this.link;
+    public void setType(String value)
+    {
+      this.type = value;
     }
 
     /**
-     * Gets the value of the event property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the event property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvent().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EventType }
+     * Gets the value of the ref property.
      * 
+     * @return possible object is {@link String }
      * 
      */
-    public List<EventType> getEvent() {
-        if (event == null) {
-            event = new ArrayList<EventType>();
-        }
-        return this.event;
+    public String getRef()
+    {
+      return ref;
     }
 
     /**
-     * Gets the value of the isoform property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the isoform property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getIsoform().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link IsoformType }
+     * Sets the value of the ref property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    public List<IsoformType> getIsoform() {
-        if (isoform == null) {
-            isoform = new ArrayList<IsoformType>();
-        }
-        return this.isoform;
+    public void setRef(String value)
+    {
+      this.ref = value;
     }
 
     /**
-     * Gets the value of the interactant property.
-     * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the interactant property.
+     * Java class for anonymous complex type.
      * 
      * <p>
-     * For example, to add a new item, do as follows:
+     * The following schema fragment specifies the expected content contained
+     * within this class.
+     * 
      * <pre>
-     *    getInteractant().add(newItem);
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="resource" use="required">
+     *         &lt;simpleType>
+     *           &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+     *             &lt;enumeration value="EMBL-CDS"/>
+     *             &lt;enumeration value="EMBL"/>
+     *           &lt;/restriction>
+     *         &lt;/simpleType>
+     *       &lt;/attribute>
+     *       &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="version" type="{http://www.w3.org/2001/XMLSchema}int" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
      * </pre>
      * 
      * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link InteractantType }
-     * 
-     * 
      */
-    public List<InteractantType> getInteractant() {
-        if (interactant == null) {
-            interactant = new ArrayList<InteractantType>();
-        }
-        return this.interactant;
-    }
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Sequence
+    {
+
+      @XmlAttribute(name = "resource", required = true)
+      protected String resource;
+
+      @XmlAttribute(name = "id", required = true)
+      protected String id;
+
+      @XmlAttribute(name = "version")
+      protected Integer version;
+
+      /**
+       * Gets the value of the resource property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getResource()
+      {
+        return resource;
+      }
+
+      /**
+       * Sets the value of the resource property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setResource(String value)
+      {
+        this.resource = value;
+      }
+
+      /**
+       * Gets the value of the id property.
+       * 
+       * @return possible object is {@link String }
+       * 
+       */
+      public String getId()
+      {
+        return id;
+      }
+
+      /**
+       * Sets the value of the id property.
+       * 
+       * @param value
+       *          allowed object is {@link String }
+       * 
+       */
+      public void setId(String value)
+      {
+        this.id = value;
+      }
+
+      /**
+       * Gets the value of the version property.
+       * 
+       * @return possible object is {@link Integer }
+       * 
+       */
+      public Integer getVersion()
+      {
+        return version;
+      }
+
+      /**
+       * Sets the value of the version property.
+       * 
+       * @param value
+       *          allowed object is {@link Integer }
+       * 
+       */
+      public void setVersion(Integer value)
+      {
+        this.version = value;
+      }
 
-    /**
-     * Gets the value of the organismsDiffer property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
-     */
-    public Boolean isOrganismsDiffer() {
-        return organismsDiffer;
     }
 
-    /**
-     * Sets the value of the organismsDiffer property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setOrganismsDiffer(Boolean value) {
-        this.organismsDiffer = value;
-    }
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
+   *         &lt;element name="acronym" type="{http://www.w3.org/2001/XMLSchema}string"/>
+   *         &lt;element name="description" type="{http://www.w3.org/2001/XMLSchema}string"/>
+   *         &lt;element name="dbReference" type="{http://uniprot.org/uniprot}dbReferenceType"/>
+   *       &lt;/sequence>
+   *       &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(
+    name = "",
+    propOrder =
+    { "name", "acronym", "description", "dbReference" })
+  public static class Disease
+  {
+
+    @XmlElement(required = true)
+    protected String name;
 
-    /**
-     * Gets the value of the experiments property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
-     */
-    public Integer getExperiments() {
-        return experiments;
-    }
+    @XmlElement(required = true)
+    protected String acronym;
 
-    /**
-     * Sets the value of the experiments property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
-     */
-    public void setExperiments(Integer value) {
-        this.experiments = value;
-    }
+    @XmlElement(required = true)
+    protected String description;
 
-    /**
-     * Gets the value of the disease property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link CommentType.Disease }
-     *     
-     */
-    public CommentType.Disease getDisease() {
-        return disease;
-    }
+    @XmlElement(required = true)
+    protected DbReferenceType dbReference;
 
-    /**
-     * Sets the value of the disease property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link CommentType.Disease }
-     *     
-     */
-    public void setDisease(CommentType.Disease value) {
-        this.disease = value;
-    }
+    @XmlAttribute(name = "id", required = true)
+    protected String id;
 
     /**
-     * Gets the value of the location property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the location property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getLocation().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link LocationType }
+     * Gets the value of the name property.
      * 
+     * @return possible object is {@link String }
      * 
      */
-    public List<LocationType> getLocation() {
-        if (location == null) {
-            location = new ArrayList<LocationType>();
-        }
-        return this.location;
+    public String getName()
+    {
+      return name;
     }
 
     /**
-     * Gets the value of the text property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the text property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getText().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EvidencedStringType }
+     * Sets the value of the name property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    public List<EvidencedStringType> getText() {
-        if (text == null) {
-            text = new ArrayList<EvidencedStringType>();
-        }
-        return this.text;
+    public void setName(String value)
+    {
+      this.name = value;
     }
 
     /**
-     * Gets the value of the type property.
+     * Gets the value of the acronym property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getType() {
-        return type;
+    public String getAcronym()
+    {
+      return acronym;
     }
 
     /**
-     * Sets the value of the type property.
+     * Sets the value of the acronym property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
-
-    /**
-     * Gets the value of the locationType property.
+     *          allowed object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getLocationType() {
-        return locationType;
+    public void setAcronym(String value)
+    {
+      this.acronym = value;
     }
 
     /**
-     * Sets the value of the locationType property.
+     * Gets the value of the description property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setLocationType(String value) {
-        this.locationType = value;
-    }
-
-    /**
-     * Gets the value of the name property.
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getName() {
-        return name;
+    public String getDescription()
+    {
+      return description;
     }
 
     /**
-     * Sets the value of the name property.
+     * Sets the value of the description property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setName(String value) {
-        this.name = value;
-    }
-
-    /**
-     * Gets the value of the mass property.
+     *          allowed object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link Float }
-     *     
      */
-    public Float getMass() {
-        return mass;
+    public void setDescription(String value)
+    {
+      this.description = value;
     }
 
     /**
-     * Sets the value of the mass property.
+     * Gets the value of the dbReference property.
      * 
-     * @param value
-     *     allowed object is
-     *     {@link Float }
-     *     
-     */
-    public void setMass(Float value) {
-        this.mass = value;
-    }
-
-    /**
-     * Gets the value of the error property.
+     * @return possible object is {@link DbReferenceType }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getError() {
-        return error;
+    public DbReferenceType getDbReference()
+    {
+      return dbReference;
     }
 
     /**
-     * Sets the value of the error property.
+     * Sets the value of the dbReference property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *          allowed object is {@link DbReferenceType }
+     * 
      */
-    public void setError(String value) {
-        this.error = value;
+    public void setDbReference(DbReferenceType value)
+    {
+      this.dbReference = value;
     }
 
     /**
-     * Gets the value of the method property.
+     * Gets the value of the id property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
      */
-    public String getMethod() {
-        return method;
+    public String getId()
+    {
+      return id;
     }
 
     /**
-     * Sets the value of the method property.
+     * Sets the value of the id property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *          allowed object is {@link String }
+     * 
      */
-    public void setMethod(String value) {
-        this.method = value;
+    public void setId(String value)
+    {
+      this.id = value;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="KM" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="Vmax" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "km", "vmax", "text" })
+  public static class Kinetics
+  {
+
+    @XmlElement(name = "KM")
+    protected List<EvidencedStringType> km;
+
+    @XmlElement(name = "Vmax")
+    protected List<EvidencedStringType> vmax;
+
+    protected List<EvidencedStringType> text;
+
     /**
-     * Gets the value of the evidence property.
+     * Gets the value of the km property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the km property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getEvidence().add(newItem);
+     * getKM().add(newItem);
      * </pre>
      * 
      * 
      * <p>
      * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
+     * {@link EvidencedStringType }
      * 
      * 
      */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
+    public List<EvidencedStringType> getKM()
+    {
+      if (km == null)
+      {
+        km = new ArrayList<EvidencedStringType>();
+      }
+      return this.km;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the vmax property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the vmax property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="max" type="{http://uniprot.org/uniprot}evidencedStringType" minOccurs="0"/>
-     *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getVmax().add(newItem);
      * </pre>
      * 
      * 
-     */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "max",
-        "text"
-    })
-    public static class Absorption {
-
-        protected EvidencedStringType max;
-        protected List<EvidencedStringType> text;
-
-        /**
-         * Gets the value of the max property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public EvidencedStringType getMax() {
-            return max;
-        }
-
-        /**
-         * Sets the value of the max property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public void setMax(EvidencedStringType value) {
-            this.max = value;
-        }
-
-        /**
-         * Gets the value of the text property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the text property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getText().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getText() {
-            if (text == null) {
-                text = new ArrayList<EvidencedStringType>();
-            }
-            return this.text;
-        }
-
-    }
-
-
-    /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="sequence" minOccurs="0">
-     *           &lt;complexType>
-     *             &lt;complexContent>
-     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *                 &lt;attribute name="resource" use="required">
-     *                   &lt;simpleType>
-     *                     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
-     *                       &lt;enumeration value="EMBL-CDS"/>
-     *                       &lt;enumeration value="EMBL"/>
-     *                     &lt;/restriction>
-     *                   &lt;/simpleType>
-     *                 &lt;/attribute>
-     *                 &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *                 &lt;attribute name="version" type="{http://www.w3.org/2001/XMLSchema}int" />
-     *               &lt;/restriction>
-     *             &lt;/complexContent>
-     *           &lt;/complexType>
-     *         &lt;/element>
-     *       &lt;/sequence>
-     *       &lt;attribute name="type" use="required">
-     *         &lt;simpleType>
-     *           &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
-     *             &lt;enumeration value="frameshift"/>
-     *             &lt;enumeration value="erroneous initiation"/>
-     *             &lt;enumeration value="erroneous termination"/>
-     *             &lt;enumeration value="erroneous gene model prediction"/>
-     *             &lt;enumeration value="erroneous translation"/>
-     *             &lt;enumeration value="miscellaneous discrepancy"/>
-     *           &lt;/restriction>
-     *         &lt;/simpleType>
-     *       &lt;/attribute>
-     *       &lt;attribute name="ref" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
      * 
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "sequence"
-    })
-    public static class Conflict {
-
-        protected CommentType.Conflict.Sequence sequence;
-        @XmlAttribute(name = "type", required = true)
-        protected String type;
-        @XmlAttribute(name = "ref")
-        protected String ref;
-
-        /**
-         * Gets the value of the sequence property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link CommentType.Conflict.Sequence }
-         *     
-         */
-        public CommentType.Conflict.Sequence getSequence() {
-            return sequence;
-        }
-
-        /**
-         * Sets the value of the sequence property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link CommentType.Conflict.Sequence }
-         *     
-         */
-        public void setSequence(CommentType.Conflict.Sequence value) {
-            this.sequence = value;
-        }
-
-        /**
-         * Gets the value of the type property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getType() {
-            return type;
-        }
-
-        /**
-         * Sets the value of the type property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setType(String value) {
-            this.type = value;
-        }
-
-        /**
-         * Gets the value of the ref property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getRef() {
-            return ref;
-        }
-
-        /**
-         * Sets the value of the ref property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setRef(String value) {
-            this.ref = value;
-        }
-
-
-        /**
-         * <p>Java class for anonymous complex type.
-         * 
-         * <p>The following schema fragment specifies the expected content contained within this class.
-         * 
-         * <pre>
-         * &lt;complexType>
-         *   &lt;complexContent>
-         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-         *       &lt;attribute name="resource" use="required">
-         *         &lt;simpleType>
-         *           &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
-         *             &lt;enumeration value="EMBL-CDS"/>
-         *             &lt;enumeration value="EMBL"/>
-         *           &lt;/restriction>
-         *         &lt;/simpleType>
-         *       &lt;/attribute>
-         *       &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-         *       &lt;attribute name="version" type="{http://www.w3.org/2001/XMLSchema}int" />
-         *     &lt;/restriction>
-         *   &lt;/complexContent>
-         * &lt;/complexType>
-         * </pre>
-         * 
-         * 
-         */
-        @XmlAccessorType(XmlAccessType.FIELD)
-        @XmlType(name = "")
-        public static class Sequence {
-
-            @XmlAttribute(name = "resource", required = true)
-            protected String resource;
-            @XmlAttribute(name = "id", required = true)
-            protected String id;
-            @XmlAttribute(name = "version")
-            protected Integer version;
-
-            /**
-             * Gets the value of the resource property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getResource() {
-                return resource;
-            }
-
-            /**
-             * Sets the value of the resource property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setResource(String value) {
-                this.resource = value;
-            }
-
-            /**
-             * Gets the value of the id property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link String }
-             *     
-             */
-            public String getId() {
-                return id;
-            }
-
-            /**
-             * Sets the value of the id property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link String }
-             *     
-             */
-            public void setId(String value) {
-                this.id = value;
-            }
-
-            /**
-             * Gets the value of the version property.
-             * 
-             * @return
-             *     possible object is
-             *     {@link Integer }
-             *     
-             */
-            public Integer getVersion() {
-                return version;
-            }
-
-            /**
-             * Sets the value of the version property.
-             * 
-             * @param value
-             *     allowed object is
-             *     {@link Integer }
-             *     
-             */
-            public void setVersion(Integer value) {
-                this.version = value;
-            }
-
-        }
-
+    public List<EvidencedStringType> getVmax()
+    {
+      if (vmax == null)
+      {
+        vmax = new ArrayList<EvidencedStringType>();
+      }
+      return this.vmax;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the text property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the text property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
-     *         &lt;element name="acronym" type="{http://www.w3.org/2001/XMLSchema}string"/>
-     *         &lt;element name="description" type="{http://www.w3.org/2001/XMLSchema}string"/>
-     *         &lt;element name="dbReference" type="{http://uniprot.org/uniprot}dbReferenceType"/>
-     *       &lt;/sequence>
-     *       &lt;attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getText().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "name",
-        "acronym",
-        "description",
-        "dbReference"
-    })
-    public static class Disease {
-
-        @XmlElement(required = true)
-        protected String name;
-        @XmlElement(required = true)
-        protected String acronym;
-        @XmlElement(required = true)
-        protected String description;
-        @XmlElement(required = true)
-        protected DbReferenceType dbReference;
-        @XmlAttribute(name = "id", required = true)
-        protected String id;
-
-        /**
-         * Gets the value of the name property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Sets the value of the name property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setName(String value) {
-            this.name = value;
-        }
-
-        /**
-         * Gets the value of the acronym property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getAcronym() {
-            return acronym;
-        }
-
-        /**
-         * Sets the value of the acronym property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setAcronym(String value) {
-            this.acronym = value;
-        }
-
-        /**
-         * Gets the value of the description property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getDescription() {
-            return description;
-        }
-
-        /**
-         * Sets the value of the description property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setDescription(String value) {
-            this.description = value;
-        }
-
-        /**
-         * Gets the value of the dbReference property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link DbReferenceType }
-         *     
-         */
-        public DbReferenceType getDbReference() {
-            return dbReference;
-        }
-
-        /**
-         * Sets the value of the dbReference property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link DbReferenceType }
-         *     
-         */
-        public void setDbReference(DbReferenceType value) {
-            this.dbReference = value;
-        }
-
-        /**
-         * Gets the value of the id property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getId() {
-            return id;
-        }
-
-        /**
-         * Sets the value of the id property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setId(String value) {
-            this.id = value;
-        }
-
+    public List<EvidencedStringType> getText()
+    {
+      if (text == null)
+      {
+        text = new ArrayList<EvidencedStringType>();
+      }
+      return this.text;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="uri" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class Link
+  {
+
+    @XmlAttribute(name = "uri", required = true)
+    @XmlSchemaType(name = "anyURI")
+    protected String uri;
 
     /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="KM" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="Vmax" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     * Gets the value of the uri property.
      * 
+     * @return possible object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "km",
-        "vmax",
-        "text"
-    })
-    public static class Kinetics {
-
-        @XmlElement(name = "KM")
-        protected List<EvidencedStringType> km;
-        @XmlElement(name = "Vmax")
-        protected List<EvidencedStringType> vmax;
-        protected List<EvidencedStringType> text;
-
-        /**
-         * Gets the value of the km property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the km property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getKM().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getKM() {
-            if (km == null) {
-                km = new ArrayList<EvidencedStringType>();
-            }
-            return this.km;
-        }
-
-        /**
-         * Gets the value of the vmax property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the vmax property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getVmax().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getVmax() {
-            if (vmax == null) {
-                vmax = new ArrayList<EvidencedStringType>();
-            }
-            return this.vmax;
-        }
-
-        /**
-         * Gets the value of the text property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the text property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getText().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getText() {
-            if (text == null) {
-                text = new ArrayList<EvidencedStringType>();
-            }
-            return this.text;
-        }
-
+    public String getUri()
+    {
+      return uri;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="uri" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     * Sets the value of the uri property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class Link {
-
-        @XmlAttribute(name = "uri", required = true)
-        @XmlSchemaType(name = "anyURI")
-        protected String uri;
-
-        /**
-         * Gets the value of the uri property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getUri() {
-            return uri;
-        }
-
-        /**
-         * Sets the value of the uri property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setUri(String value) {
-            this.uri = value;
-        }
-
+    public void setUri(String value)
+    {
+      this.uri = value;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "text" })
+  public static class PhDependence
+  {
+
+    @XmlElement(required = true)
+    protected List<EvidencedStringType> text;
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the text property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the text property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getText().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "text"
-    })
-    public static class PhDependence {
-
-        @XmlElement(required = true)
-        protected List<EvidencedStringType> text;
-
-        /**
-         * Gets the value of the text property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the text property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getText().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getText() {
-            if (text == null) {
-                text = new ArrayList<EvidencedStringType>();
-            }
-            return this.text;
-        }
-
+    public List<EvidencedStringType> getText()
+    {
+      if (text == null)
+      {
+        text = new ArrayList<EvidencedStringType>();
+      }
+      return this.text;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "text" })
+  public static class RedoxPotential
+  {
+
+    @XmlElement(required = true)
+    protected List<EvidencedStringType> text;
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the text property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the text property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getText().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "text"
-    })
-    public static class RedoxPotential {
-
-        @XmlElement(required = true)
-        protected List<EvidencedStringType> text;
-
-        /**
-         * Gets the value of the text property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the text property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getText().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getText() {
-            if (text == null) {
-                text = new ArrayList<EvidencedStringType>();
-            }
-            return this.text;
-        }
-
+    public List<EvidencedStringType> getText()
+    {
+      if (text == null)
+      {
+        text = new ArrayList<EvidencedStringType>();
+      }
+      return this.text;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "text" })
+  public static class TemperatureDependence
+  {
+
+    @XmlElement(required = true)
+    protected List<EvidencedStringType> text;
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the text property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the text property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="text" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getText().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "text"
-    })
-    public static class TemperatureDependence {
-
-        @XmlElement(required = true)
-        protected List<EvidencedStringType> text;
-
-        /**
-         * Gets the value of the text property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the text property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getText().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getText() {
-            if (text == null) {
-                text = new ArrayList<EvidencedStringType>();
-            }
-            return this.text;
-        }
-
+    public List<EvidencedStringType> getText()
+    {
+      if (text == null)
+      {
+        text = new ArrayList<EvidencedStringType>();
+      }
+      return this.text;
     }
 
+  }
+
 }
index 71db504..719344b 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,14 +12,16 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes the authors of a citation when these are represented by a consortium.
- *             Equivalent to the flat file RG-line.
+ * Describes the authors of a citation when these are represented by a
+ * consortium. Equivalent to the flat file RG-line.
  * 
- * <p>Java class for consortiumType complex type.
+ * <p>
+ * Java class for consortiumType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="consortiumType">
@@ -36,33 +37,33 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "consortiumType")
-public class ConsortiumType {
+public class ConsortiumType
+{
 
-    @XmlAttribute(name = "name", required = true)
-    protected String name;
+  @XmlAttribute(name = "name", required = true)
+  protected String name;
 
-    /**
-     * Gets the value of the name property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getName() {
-        return name;
-    }
+  /**
+   * Gets the value of the name property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getName()
+  {
+    return name;
+  }
 
-    /**
-     * Sets the value of the name property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setName(String value) {
-        this.name = value;
-    }
+  /**
+   * Sets the value of the name property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setName(String value)
+  {
+    this.name = value;
+  }
 
 }
index 73ccfa8..184f424 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -15,15 +14,16 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes a database cross-reference.
- *             Equivalent to the flat file DR-line.
- *             
+ * Describes a database cross-reference. Equivalent to the flat file DR-line.
  * 
- * <p>Java class for dbReferenceType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * Java class for dbReferenceType complex type.
+ * 
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="dbReferenceType">
@@ -44,149 +44,153 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "dbReferenceType", propOrder = {
-    "molecule",
-    "property"
-})
-public class DbReferenceType {
-
-    protected MoleculeType molecule;
-    protected List<PropertyType> property;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "id", required = true)
-    protected String id;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
-
-    /**
-     * Gets the value of the molecule property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link MoleculeType }
-     *     
-     */
-    public MoleculeType getMolecule() {
-        return molecule;
-    }
+@XmlType(name = "dbReferenceType", propOrder = { "molecule", "property" })
+public class DbReferenceType
+{
 
-    /**
-     * Sets the value of the molecule property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link MoleculeType }
-     *     
-     */
-    public void setMolecule(MoleculeType value) {
-        this.molecule = value;
-    }
+  protected MoleculeType molecule;
 
-    /**
-     * Gets the value of the property property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the property property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getProperty().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link PropertyType }
-     * 
-     * 
-     */
-    public List<PropertyType> getProperty() {
-        if (property == null) {
-            property = new ArrayList<PropertyType>();
-        }
-        return this.property;
-    }
+  protected List<PropertyType> property;
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
+  @XmlAttribute(name = "id", required = true)
+  protected String id;
 
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
+
+  /**
+   * Gets the value of the molecule property.
+   * 
+   * @return possible object is {@link MoleculeType }
+   * 
+   */
+  public MoleculeType getMolecule()
+  {
+    return molecule;
+  }
 
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
+  /**
+   * Sets the value of the molecule property.
+   * 
+   * @param value
+   *          allowed object is {@link MoleculeType }
+   * 
+   */
+  public void setMolecule(MoleculeType value)
+  {
+    this.molecule = value;
+  }
+
+  /**
+   * Gets the value of the property property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the property property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getProperty().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link PropertyType }
+   * 
+   * 
+   */
+  public List<PropertyType> getProperty()
+  {
+    if (property == null)
+    {
+      property = new ArrayList<PropertyType>();
     }
+    return this.property;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
+
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
+
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
 
 }
index 21963a8..72de883 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -19,11 +18,13 @@ import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.datatype.XMLGregorianCalendar;
 
-
 /**
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -65,561 +66,594 @@ import javax.xml.datatype.XMLGregorianCalendar;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "accession",
-    "name",
-    "protein",
-    "gene",
-    "organism",
-    "organismHost",
-    "geneLocation",
-    "reference",
-    "comment",
-    "dbReference",
-    "proteinExistence",
-    "keyword",
-    "feature",
-    "evidence",
-    "sequence"
-})
+@XmlType(
+  name = "",
+  propOrder =
+  { "accession", "name", "protein", "gene", "organism", "organismHost",
+      "geneLocation", "reference", "comment", "dbReference",
+      "proteinExistence", "keyword", "feature", "evidence", "sequence" })
 @XmlRootElement(name = "entry")
-public class Entry {
-
-    @XmlElement(required = true)
-    protected List<String> accession;
-    @XmlElement(required = true)
-    protected List<String> name;
-    @XmlElement(required = true)
-    protected ProteinType protein;
-    protected List<GeneType> gene;
-    @XmlElement(required = true)
-    protected OrganismType organism;
-    protected List<OrganismType> organismHost;
-    protected List<GeneLocationType> geneLocation;
-    @XmlElement(required = true)
-    protected List<ReferenceType> reference;
-    @XmlElement(nillable = true)
-    protected List<CommentType> comment;
-    protected List<DbReferenceType> dbReference;
-    @XmlElement(required = true)
-    protected ProteinExistenceType proteinExistence;
-    protected List<KeywordType> keyword;
-    protected List<FeatureType> feature;
-    protected List<EvidenceType> evidence;
-    @XmlElement(required = true)
-    protected SequenceType sequence;
-    @XmlAttribute(name = "dataset", required = true)
-    protected String dataset;
-    @XmlAttribute(name = "created", required = true)
-    @XmlSchemaType(name = "date")
-    protected XMLGregorianCalendar created;
-    @XmlAttribute(name = "modified", required = true)
-    @XmlSchemaType(name = "date")
-    protected XMLGregorianCalendar modified;
-    @XmlAttribute(name = "version", required = true)
-    protected int version;
-
-    /**
-     * Gets the value of the accession property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the accession property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getAccession().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getAccession() {
-        if (accession == null) {
-            accession = new ArrayList<String>();
-        }
-        return this.accession;
-    }
+public class Entry
+{
 
-    /**
-     * Gets the value of the name property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the name property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getName().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getName() {
-        if (name == null) {
-            name = new ArrayList<String>();
-        }
-        return this.name;
-    }
+  @XmlElement(required = true)
+  protected List<String> accession;
 
-    /**
-     * Gets the value of the protein property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link ProteinType }
-     *     
-     */
-    public ProteinType getProtein() {
-        return protein;
-    }
+  @XmlElement(required = true)
+  protected List<String> name;
 
-    /**
-     * Sets the value of the protein property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link ProteinType }
-     *     
-     */
-    public void setProtein(ProteinType value) {
-        this.protein = value;
-    }
+  @XmlElement(required = true)
+  protected ProteinType protein;
 
-    /**
-     * Gets the value of the gene property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the gene property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getGene().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link GeneType }
-     * 
-     * 
-     */
-    public List<GeneType> getGene() {
-        if (gene == null) {
-            gene = new ArrayList<GeneType>();
-        }
-        return this.gene;
-    }
+  protected List<GeneType> gene;
 
-    /**
-     * Gets the value of the organism property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link OrganismType }
-     *     
-     */
-    public OrganismType getOrganism() {
-        return organism;
-    }
+  @XmlElement(required = true)
+  protected OrganismType organism;
 
-    /**
-     * Sets the value of the organism property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link OrganismType }
-     *     
-     */
-    public void setOrganism(OrganismType value) {
-        this.organism = value;
-    }
+  protected List<OrganismType> organismHost;
 
-    /**
-     * Gets the value of the organismHost property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the organismHost property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getOrganismHost().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link OrganismType }
-     * 
-     * 
-     */
-    public List<OrganismType> getOrganismHost() {
-        if (organismHost == null) {
-            organismHost = new ArrayList<OrganismType>();
-        }
-        return this.organismHost;
-    }
+  protected List<GeneLocationType> geneLocation;
 
-    /**
-     * Gets the value of the geneLocation property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the geneLocation property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getGeneLocation().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link GeneLocationType }
-     * 
-     * 
-     */
-    public List<GeneLocationType> getGeneLocation() {
-        if (geneLocation == null) {
-            geneLocation = new ArrayList<GeneLocationType>();
-        }
-        return this.geneLocation;
-    }
+  @XmlElement(required = true)
+  protected List<ReferenceType> reference;
 
-    /**
-     * Gets the value of the reference property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the reference property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getReference().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link ReferenceType }
-     * 
-     * 
-     */
-    public List<ReferenceType> getReference() {
-        if (reference == null) {
-            reference = new ArrayList<ReferenceType>();
-        }
-        return this.reference;
-    }
+  @XmlElement(nillable = true)
+  protected List<CommentType> comment;
 
-    /**
-     * Gets the value of the comment property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the comment property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getComment().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link CommentType }
-     * 
-     * 
-     */
-    public List<CommentType> getComment() {
-        if (comment == null) {
-            comment = new ArrayList<CommentType>();
-        }
-        return this.comment;
-    }
+  protected List<DbReferenceType> dbReference;
 
-    /**
-     * Gets the value of the dbReference property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the dbReference property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getDbReference().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link DbReferenceType }
-     * 
-     * 
-     */
-    public List<DbReferenceType> getDbReference() {
-        if (dbReference == null) {
-            dbReference = new ArrayList<DbReferenceType>();
-        }
-        return this.dbReference;
-    }
+  @XmlElement(required = true)
+  protected ProteinExistenceType proteinExistence;
 
-    /**
-     * Gets the value of the proteinExistence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link ProteinExistenceType }
-     *     
-     */
-    public ProteinExistenceType getProteinExistence() {
-        return proteinExistence;
-    }
+  protected List<KeywordType> keyword;
 
-    /**
-     * Sets the value of the proteinExistence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link ProteinExistenceType }
-     *     
-     */
-    public void setProteinExistence(ProteinExistenceType value) {
-        this.proteinExistence = value;
-    }
+  protected List<FeatureType> feature;
 
-    /**
-     * Gets the value of the keyword property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the keyword property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getKeyword().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link KeywordType }
-     * 
-     * 
-     */
-    public List<KeywordType> getKeyword() {
-        if (keyword == null) {
-            keyword = new ArrayList<KeywordType>();
-        }
-        return this.keyword;
-    }
+  protected List<EvidenceType> evidence;
 
-    /**
-     * Gets the value of the feature property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the feature property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getFeature().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link FeatureType }
-     * 
-     * 
-     */
-    public List<FeatureType> getFeature() {
-        if (feature == null) {
-            feature = new ArrayList<FeatureType>();
-        }
-        return this.feature;
-    }
+  @XmlElement(required = true)
+  protected SequenceType sequence;
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EvidenceType }
-     * 
-     * 
-     */
-    public List<EvidenceType> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<EvidenceType>();
-        }
-        return this.evidence;
-    }
+  @XmlAttribute(name = "dataset", required = true)
+  protected String dataset;
 
-    /**
-     * Gets the value of the sequence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link SequenceType }
-     *     
-     */
-    public SequenceType getSequence() {
-        return sequence;
-    }
+  @XmlAttribute(name = "created", required = true)
+  @XmlSchemaType(name = "date")
+  protected XMLGregorianCalendar created;
 
-    /**
-     * Sets the value of the sequence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link SequenceType }
-     *     
-     */
-    public void setSequence(SequenceType value) {
-        this.sequence = value;
-    }
+  @XmlAttribute(name = "modified", required = true)
+  @XmlSchemaType(name = "date")
+  protected XMLGregorianCalendar modified;
 
-    /**
-     * Gets the value of the dataset property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDataset() {
-        return dataset;
-    }
+  @XmlAttribute(name = "version", required = true)
+  protected int version;
 
-    /**
-     * Sets the value of the dataset property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDataset(String value) {
-        this.dataset = value;
+  /**
+   * Gets the value of the accession property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the accession property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getAccession().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getAccession()
+  {
+    if (accession == null)
+    {
+      accession = new ArrayList<String>();
     }
-
-    /**
-     * Gets the value of the created property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public XMLGregorianCalendar getCreated() {
-        return created;
+    return this.accession;
+  }
+
+  /**
+   * Gets the value of the name property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the name property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getName()
+  {
+    if (name == null)
+    {
+      name = new ArrayList<String>();
     }
-
-    /**
-     * Sets the value of the created property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public void setCreated(XMLGregorianCalendar value) {
-        this.created = value;
+    return this.name;
+  }
+
+  /**
+   * Gets the value of the protein property.
+   * 
+   * @return possible object is {@link ProteinType }
+   * 
+   */
+  public ProteinType getProtein()
+  {
+    return protein;
+  }
+
+  /**
+   * Sets the value of the protein property.
+   * 
+   * @param value
+   *          allowed object is {@link ProteinType }
+   * 
+   */
+  public void setProtein(ProteinType value)
+  {
+    this.protein = value;
+  }
+
+  /**
+   * Gets the value of the gene property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the gene property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getGene().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link GeneType }
+   * 
+   * 
+   */
+  public List<GeneType> getGene()
+  {
+    if (gene == null)
+    {
+      gene = new ArrayList<GeneType>();
     }
-
-    /**
-     * Gets the value of the modified property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public XMLGregorianCalendar getModified() {
-        return modified;
+    return this.gene;
+  }
+
+  /**
+   * Gets the value of the organism property.
+   * 
+   * @return possible object is {@link OrganismType }
+   * 
+   */
+  public OrganismType getOrganism()
+  {
+    return organism;
+  }
+
+  /**
+   * Sets the value of the organism property.
+   * 
+   * @param value
+   *          allowed object is {@link OrganismType }
+   * 
+   */
+  public void setOrganism(OrganismType value)
+  {
+    this.organism = value;
+  }
+
+  /**
+   * Gets the value of the organismHost property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the organismHost property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getOrganismHost().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link OrganismType }
+   * 
+   * 
+   */
+  public List<OrganismType> getOrganismHost()
+  {
+    if (organismHost == null)
+    {
+      organismHost = new ArrayList<OrganismType>();
     }
-
-    /**
-     * Sets the value of the modified property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public void setModified(XMLGregorianCalendar value) {
-        this.modified = value;
+    return this.organismHost;
+  }
+
+  /**
+   * Gets the value of the geneLocation property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the geneLocation property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getGeneLocation().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link GeneLocationType }
+   * 
+   * 
+   */
+  public List<GeneLocationType> getGeneLocation()
+  {
+    if (geneLocation == null)
+    {
+      geneLocation = new ArrayList<GeneLocationType>();
     }
-
-    /**
-     * Gets the value of the version property.
-     * 
-     */
-    public int getVersion() {
-        return version;
+    return this.geneLocation;
+  }
+
+  /**
+   * Gets the value of the reference property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the reference property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getReference().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link ReferenceType }
+   * 
+   * 
+   */
+  public List<ReferenceType> getReference()
+  {
+    if (reference == null)
+    {
+      reference = new ArrayList<ReferenceType>();
     }
-
-    /**
-     * Sets the value of the version property.
-     * 
-     */
-    public void setVersion(int value) {
-        this.version = value;
+    return this.reference;
+  }
+
+  /**
+   * Gets the value of the comment property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the comment property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getComment().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link CommentType
+   * }
+   * 
+   * 
+   */
+  public List<CommentType> getComment()
+  {
+    if (comment == null)
+    {
+      comment = new ArrayList<CommentType>();
+    }
+    return this.comment;
+  }
+
+  /**
+   * Gets the value of the dbReference property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the dbReference property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getDbReference().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link DbReferenceType }
+   * 
+   * 
+   */
+  public List<DbReferenceType> getDbReference()
+  {
+    if (dbReference == null)
+    {
+      dbReference = new ArrayList<DbReferenceType>();
+    }
+    return this.dbReference;
+  }
+
+  /**
+   * Gets the value of the proteinExistence property.
+   * 
+   * @return possible object is {@link ProteinExistenceType }
+   * 
+   */
+  public ProteinExistenceType getProteinExistence()
+  {
+    return proteinExistence;
+  }
+
+  /**
+   * Sets the value of the proteinExistence property.
+   * 
+   * @param value
+   *          allowed object is {@link ProteinExistenceType }
+   * 
+   */
+  public void setProteinExistence(ProteinExistenceType value)
+  {
+    this.proteinExistence = value;
+  }
+
+  /**
+   * Gets the value of the keyword property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the keyword property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getKeyword().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link KeywordType
+   * }
+   * 
+   * 
+   */
+  public List<KeywordType> getKeyword()
+  {
+    if (keyword == null)
+    {
+      keyword = new ArrayList<KeywordType>();
+    }
+    return this.keyword;
+  }
+
+  /**
+   * Gets the value of the feature property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the feature property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getFeature().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link FeatureType
+   * }
+   * 
+   * 
+   */
+  public List<FeatureType> getFeature()
+  {
+    if (feature == null)
+    {
+      feature = new ArrayList<FeatureType>();
+    }
+    return this.feature;
+  }
+
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EvidenceType }
+   * 
+   * 
+   */
+  public List<EvidenceType> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<EvidenceType>();
     }
+    return this.evidence;
+  }
+
+  /**
+   * Gets the value of the sequence property.
+   * 
+   * @return possible object is {@link SequenceType }
+   * 
+   */
+  public SequenceType getSequence()
+  {
+    return sequence;
+  }
+
+  /**
+   * Sets the value of the sequence property.
+   * 
+   * @param value
+   *          allowed object is {@link SequenceType }
+   * 
+   */
+  public void setSequence(SequenceType value)
+  {
+    this.sequence = value;
+  }
+
+  /**
+   * Gets the value of the dataset property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDataset()
+  {
+    return dataset;
+  }
+
+  /**
+   * Sets the value of the dataset property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDataset(String value)
+  {
+    this.dataset = value;
+  }
+
+  /**
+   * Gets the value of the created property.
+   * 
+   * @return possible object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public XMLGregorianCalendar getCreated()
+  {
+    return created;
+  }
+
+  /**
+   * Sets the value of the created property.
+   * 
+   * @param value
+   *          allowed object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public void setCreated(XMLGregorianCalendar value)
+  {
+    this.created = value;
+  }
+
+  /**
+   * Gets the value of the modified property.
+   * 
+   * @return possible object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public XMLGregorianCalendar getModified()
+  {
+    return modified;
+  }
+
+  /**
+   * Sets the value of the modified property.
+   * 
+   * @param value
+   *          allowed object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public void setModified(XMLGregorianCalendar value)
+  {
+    this.modified = value;
+  }
+
+  /**
+   * Gets the value of the version property.
+   * 
+   */
+  public int getVersion()
+  {
+    return version;
+  }
+
+  /**
+   * Sets the value of the version property.
+   * 
+   */
+  public void setVersion(int value)
+  {
+    this.version = value;
+  }
 
 }
index 0b4d4bd..ec9fdcd 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,13 +12,15 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * Describes the type of events that cause alternative products.
  * 
- * <p>Java class for eventType complex type.
+ * <p>
+ * Java class for eventType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="eventType">
@@ -44,33 +45,33 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "eventType")
-public class EventType {
+public class EventType
+{
 
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
 
 }
index 59c9857..d40163d 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.math.BigInteger;
@@ -14,14 +13,15 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes the evidence for an annotation.
- *             No flat file equivalent.
+ * Describes the evidence for an annotation. No flat file equivalent.
  * 
- * <p>Java class for evidenceType complex type.
+ * <p>
+ * Java class for evidenceType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="evidenceType">
@@ -41,113 +41,110 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "evidenceType", propOrder = {
-    "source",
-    "importedFrom"
-})
-public class EvidenceType {
-
-    protected SourceType source;
-    protected ImportedFromType importedFrom;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "key", required = true)
-    protected BigInteger key;
-
-    /**
-     * Gets the value of the source property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link SourceType }
-     *     
-     */
-    public SourceType getSource() {
-        return source;
-    }
-
-    /**
-     * Sets the value of the source property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link SourceType }
-     *     
-     */
-    public void setSource(SourceType value) {
-        this.source = value;
-    }
-
-    /**
-     * Gets the value of the importedFrom property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link ImportedFromType }
-     *     
-     */
-    public ImportedFromType getImportedFrom() {
-        return importedFrom;
-    }
-
-    /**
-     * Sets the value of the importedFrom property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link ImportedFromType }
-     *     
-     */
-    public void setImportedFrom(ImportedFromType value) {
-        this.importedFrom = value;
-    }
-
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
-
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
-
-    /**
-     * Gets the value of the key property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
-     */
-    public BigInteger getKey() {
-        return key;
-    }
-
-    /**
-     * Sets the value of the key property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setKey(BigInteger value) {
-        this.key = value;
-    }
+@XmlType(name = "evidenceType", propOrder = { "source", "importedFrom" })
+public class EvidenceType
+{
+
+  protected SourceType source;
+
+  protected ImportedFromType importedFrom;
+
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
+
+  @XmlAttribute(name = "key", required = true)
+  protected BigInteger key;
+
+  /**
+   * Gets the value of the source property.
+   * 
+   * @return possible object is {@link SourceType }
+   * 
+   */
+  public SourceType getSource()
+  {
+    return source;
+  }
+
+  /**
+   * Sets the value of the source property.
+   * 
+   * @param value
+   *          allowed object is {@link SourceType }
+   * 
+   */
+  public void setSource(SourceType value)
+  {
+    this.source = value;
+  }
+
+  /**
+   * Gets the value of the importedFrom property.
+   * 
+   * @return possible object is {@link ImportedFromType }
+   * 
+   */
+  public ImportedFromType getImportedFrom()
+  {
+    return importedFrom;
+  }
+
+  /**
+   * Sets the value of the importedFrom property.
+   * 
+   * @param value
+   *          allowed object is {@link ImportedFromType }
+   * 
+   */
+  public void setImportedFrom(ImportedFromType value)
+  {
+    this.importedFrom = value;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
+
+  /**
+   * Gets the value of the key property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getKey()
+  {
+    return key;
+  }
+
+  /**
+   * Sets the value of the key property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setKey(BigInteger value)
+  {
+    this.key = value;
+  }
 
 }
index 0fa25a6..4b4c3a2 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-
 /**
- * <p>Java class for evidencedStringType complex type.
+ * <p>
+ * Java class for evidencedStringType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="evidencedStringType">
@@ -44,93 +45,94 @@ import javax.xml.bind.annotation.XmlValue;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "evidencedStringType", propOrder = {
-    "value"
-})
-public class EvidencedStringType {
+@XmlType(name = "evidencedStringType", propOrder = { "value" })
+public class EvidencedStringType
+{
 
-    @XmlValue
-    protected String value;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
-    @XmlAttribute(name = "status")
-    protected String status;
+  @XmlValue
+  protected String value;
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  @XmlAttribute(name = "status")
+  protected String status;
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
 
-    /**
-     * Gets the value of the status property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getStatus() {
-        return status;
-    }
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
 
-    /**
-     * Sets the value of the status property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setStatus(String value) {
-        this.status = value;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
+
+  /**
+   * Gets the value of the status property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getStatus()
+  {
+    return status;
+  }
+
+  /**
+   * Sets the value of the status property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setStatus(String value)
+  {
+    this.status = value;
+  }
 
 }
index f818e2e..791aa0e 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,14 +15,16 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes different types of sequence annotations.
- *             Equivalent to the flat file FT-line.
+ * Describes different types of sequence annotations. Equivalent to the flat
+ * file FT-line.
  * 
- * <p>Java class for featureType complex type.
+ * <p>
+ * Java class for featureType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="featureType">
@@ -100,254 +101,259 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "featureType", propOrder = {
-    "original",
-    "variation",
-    "location"
-})
-public class FeatureType {
+@XmlType(
+  name = "featureType",
+  propOrder =
+  { "original", "variation", "location" })
+public class FeatureType
+{
 
-    protected String original;
-    protected List<String> variation;
-    @XmlElement(required = true)
-    protected LocationType location;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "status")
-    protected String status;
-    @XmlAttribute(name = "id")
-    protected String id;
-    @XmlAttribute(name = "description")
-    protected String description;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
-    @XmlAttribute(name = "ref")
-    protected String ref;
+  protected String original;
 
-    /**
-     * Gets the value of the original property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getOriginal() {
-        return original;
-    }
+  protected List<String> variation;
 
-    /**
-     * Sets the value of the original property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setOriginal(String value) {
-        this.original = value;
-    }
+  @XmlElement(required = true)
+  protected LocationType location;
 
-    /**
-     * Gets the value of the variation property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the variation property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getVariation().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getVariation() {
-        if (variation == null) {
-            variation = new ArrayList<String>();
-        }
-        return this.variation;
-    }
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    /**
-     * Gets the value of the location property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link LocationType }
-     *     
-     */
-    public LocationType getLocation() {
-        return location;
-    }
+  @XmlAttribute(name = "status")
+  protected String status;
 
-    /**
-     * Sets the value of the location property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link LocationType }
-     *     
-     */
-    public void setLocation(LocationType value) {
-        this.location = value;
-    }
+  @XmlAttribute(name = "id")
+  protected String id;
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  @XmlAttribute(name = "description")
+  protected String description;
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Gets the value of the status property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getStatus() {
-        return status;
-    }
+  @XmlAttribute(name = "ref")
+  protected String ref;
 
-    /**
-     * Sets the value of the status property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setStatus(String value) {
-        this.status = value;
-    }
+  /**
+   * Gets the value of the original property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getOriginal()
+  {
+    return original;
+  }
 
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
-    }
+  /**
+   * Sets the value of the original property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setOriginal(String value)
+  {
+    this.original = value;
+  }
 
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
+  /**
+   * Gets the value of the variation property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the variation property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getVariation().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getVariation()
+  {
+    if (variation == null)
+    {
+      variation = new ArrayList<String>();
     }
+    return this.variation;
+  }
 
-    /**
-     * Gets the value of the description property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDescription() {
-        return description;
-    }
+  /**
+   * Gets the value of the location property.
+   * 
+   * @return possible object is {@link LocationType }
+   * 
+   */
+  public LocationType getLocation()
+  {
+    return location;
+  }
 
-    /**
-     * Sets the value of the description property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDescription(String value) {
-        this.description = value;
-    }
+  /**
+   * Sets the value of the location property.
+   * 
+   * @param value
+   *          allowed object is {@link LocationType }
+   * 
+   */
+  public void setLocation(LocationType value)
+  {
+    this.location = value;
+  }
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
-    }
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
 
-    /**
-     * Gets the value of the ref property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getRef() {
-        return ref;
-    }
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
+
+  /**
+   * Gets the value of the status property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getStatus()
+  {
+    return status;
+  }
+
+  /**
+   * Sets the value of the status property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setStatus(String value)
+  {
+    this.status = value;
+  }
 
-    /**
-     * Sets the value of the ref property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setRef(String value) {
-        this.ref = value;
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
+
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
+
+  /**
+   * Gets the value of the description property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /**
+   * Sets the value of the description property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDescription(String value)
+  {
+    this.description = value;
+  }
+
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
+
+  /**
+   * Gets the value of the ref property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getRef()
+  {
+    return ref;
+  }
+
+  /**
+   * Sets the value of the ref property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setRef(String value)
+  {
+    this.ref = value;
+  }
 
 }
index f2d5638..f3d2973 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -15,14 +14,16 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes non-nuclear gene locations (organelles and plasmids).
- *             Equivalent to the flat file OG-line.
+ * Describes non-nuclear gene locations (organelles and plasmids). Equivalent to
+ * the flat file OG-line.
  * 
- * <p>Java class for geneLocationType complex type.
+ * <p>
+ * Java class for geneLocationType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="geneLocationType">
@@ -56,97 +57,102 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "geneLocationType", propOrder = {
-    "name"
-})
-public class GeneLocationType {
+@XmlType(name = "geneLocationType", propOrder = { "name" })
+public class GeneLocationType
+{
 
-    protected List<StatusType> name;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
+  protected List<StatusType> name;
 
-    /**
-     * Gets the value of the name property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the name property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getName().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link StatusType }
-     * 
-     * 
-     */
-    public List<StatusType> getName() {
-        if (name == null) {
-            name = new ArrayList<StatusType>();
-        }
-        return this.name;
-    }
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
+  /**
+   * Gets the value of the name property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the name property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link StatusType
+   * }
+   * 
+   * 
+   */
+  public List<StatusType> getName()
+  {
+    if (name == null)
+    {
+      name = new ArrayList<StatusType>();
     }
+    return this.name;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
 
 }
index 71af71f..b8cec80 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,14 +15,16 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-
 /**
- * Describes different types of gene designations.
- *             Equivalent to the flat file GN-line.
+ * Describes different types of gene designations. Equivalent to the flat file
+ * GN-line.
  * 
- * <p>Java class for geneNameType complex type.
+ * <p>
+ * Java class for geneNameType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="geneNameType">
@@ -48,93 +49,94 @@ import javax.xml.bind.annotation.XmlValue;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "geneNameType", propOrder = {
-    "value"
-})
-public class GeneNameType {
+@XmlType(name = "geneNameType", propOrder = { "value" })
+public class GeneNameType
+{
 
-    @XmlValue
-    protected String value;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
+  @XmlValue
+  protected String value;
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
+
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
 
 }
index 5fa628e..3b2300b 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -15,14 +14,15 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes a gene.
- *             Equivalent to the flat file GN-line.
+ * Describes a gene. Equivalent to the flat file GN-line.
  * 
- * <p>Java class for geneType complex type.
+ * <p>
+ * Java class for geneType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="geneType">
@@ -39,41 +39,43 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "geneType", propOrder = {
-    "name"
-})
-public class GeneType {
+@XmlType(name = "geneType", propOrder = { "name" })
+public class GeneType
+{
 
-    @XmlElement(required = true)
-    protected List<GeneNameType> name;
+  @XmlElement(required = true)
+  protected List<GeneNameType> name;
 
-    /**
-     * Gets the value of the name property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the name property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getName().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link GeneNameType }
-     * 
-     * 
-     */
-    public List<GeneNameType> getName() {
-        if (name == null) {
-            name = new ArrayList<GeneNameType>();
-        }
-        return this.name;
+  /**
+   * Gets the value of the name property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the name property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link GeneNameType }
+   * 
+   * 
+   */
+  public List<GeneNameType> getName()
+  {
+    if (name == null)
+    {
+      name = new ArrayList<GeneNameType>();
     }
+    return this.name;
+  }
 
 }
index 3d6c308..f22b4c8 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,13 +12,16 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes the source of the evidence, when it is not assigned by UniProt, but imported from an external database.
+ * Describes the source of the evidence, when it is not assigned by UniProt, but
+ * imported from an external database.
  * 
- * <p>Java class for importedFromType complex type.
+ * <p>
+ * Java class for importedFromType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="importedFromType">
@@ -36,36 +38,34 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "importedFromType", propOrder = {
-    "dbReference"
-})
-public class ImportedFromType {
+@XmlType(name = "importedFromType", propOrder = { "dbReference" })
+public class ImportedFromType
+{
 
-    @XmlElement(required = true)
-    protected DbReferenceType dbReference;
+  @XmlElement(required = true)
+  protected DbReferenceType dbReference;
 
-    /**
-     * Gets the value of the dbReference property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DbReferenceType }
-     *     
-     */
-    public DbReferenceType getDbReference() {
-        return dbReference;
-    }
+  /**
+   * Gets the value of the dbReference property.
+   * 
+   * @return possible object is {@link DbReferenceType }
+   * 
+   */
+  public DbReferenceType getDbReference()
+  {
+    return dbReference;
+  }
 
-    /**
-     * Sets the value of the dbReference property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DbReferenceType }
-     *     
-     */
-    public void setDbReference(DbReferenceType value) {
-        this.dbReference = value;
-    }
+  /**
+   * Sets the value of the dbReference property.
+   * 
+   * @param value
+   *          allowed object is {@link DbReferenceType }
+   * 
+   */
+  public void setDbReference(DbReferenceType value)
+  {
+    this.dbReference = value;
+  }
 
 }
index c9cadc2..8902f68 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,11 +12,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for interactantType complex type.
+ * <p>
+ * Java class for interactantType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="interactantType">
@@ -33,87 +34,84 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "interactantType", propOrder = {
-    "id",
-    "label"
-})
-public class InteractantType {
+@XmlType(name = "interactantType", propOrder = { "id", "label" })
+public class InteractantType
+{
+
+  protected String id;
+
+  protected String label;
 
-    protected String id;
-    protected String label;
-    @XmlAttribute(name = "intactId", required = true)
-    protected String intactId;
+  @XmlAttribute(name = "intactId", required = true)
+  protected String intactId;
 
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
-    }
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
 
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
-    }
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
 
-    /**
-     * Gets the value of the label property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getLabel() {
-        return label;
-    }
+  /**
+   * Gets the value of the label property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getLabel()
+  {
+    return label;
+  }
 
-    /**
-     * Sets the value of the label property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setLabel(String value) {
-        this.label = value;
-    }
+  /**
+   * Sets the value of the label property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setLabel(String value)
+  {
+    this.label = value;
+  }
 
-    /**
-     * Gets the value of the intactId property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getIntactId() {
-        return intactId;
-    }
+  /**
+   * Gets the value of the intactId property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getIntactId()
+  {
+    return intactId;
+  }
 
-    /**
-     * Sets the value of the intactId property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setIntactId(String value) {
-        this.intactId = value;
-    }
+  /**
+   * Sets the value of the intactId property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setIntactId(String value)
+  {
+    this.intactId = value;
+  }
 
 }
index ea55664..c3f1d0a 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -17,13 +16,15 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-
 /**
  * Describes isoforms in 'alternative products' annotations.
  * 
- * <p>Java class for isoformType complex type.
+ * <p>
+ * Java class for isoformType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="isoformType">
@@ -69,302 +70,316 @@ import javax.xml.bind.annotation.XmlValue;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "isoformType", propOrder = {
-    "id",
-    "name",
-    "sequence",
-    "text"
-})
-public class IsoformType {
+@XmlType(
+  name = "isoformType",
+  propOrder =
+  { "id", "name", "sequence", "text" })
+public class IsoformType
+{
 
-    @XmlElement(required = true)
-    protected List<String> id;
-    @XmlElement(required = true)
-    protected List<IsoformType.Name> name;
-    @XmlElement(required = true)
-    protected IsoformType.Sequence sequence;
-    protected List<EvidencedStringType> text;
+  @XmlElement(required = true)
+  protected List<String> id;
 
-    /**
-     * Gets the value of the id property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the id property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getId().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getId() {
-        if (id == null) {
-            id = new ArrayList<String>();
-        }
-        return this.id;
+  @XmlElement(required = true)
+  protected List<IsoformType.Name> name;
+
+  @XmlElement(required = true)
+  protected IsoformType.Sequence sequence;
+
+  protected List<EvidencedStringType> text;
+
+  /**
+   * Gets the value of the id property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the id property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getId().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getId()
+  {
+    if (id == null)
+    {
+      id = new ArrayList<String>();
     }
+    return this.id;
+  }
 
-    /**
-     * Gets the value of the name property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the name property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getName().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link IsoformType.Name }
-     * 
-     * 
-     */
-    public List<IsoformType.Name> getName() {
-        if (name == null) {
-            name = new ArrayList<IsoformType.Name>();
-        }
-        return this.name;
+  /**
+   * Gets the value of the name property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the name property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link IsoformType.Name }
+   * 
+   * 
+   */
+  public List<IsoformType.Name> getName()
+  {
+    if (name == null)
+    {
+      name = new ArrayList<IsoformType.Name>();
+    }
+    return this.name;
+  }
+
+  /**
+   * Gets the value of the sequence property.
+   * 
+   * @return possible object is {@link IsoformType.Sequence }
+   * 
+   */
+  public IsoformType.Sequence getSequence()
+  {
+    return sequence;
+  }
+
+  /**
+   * Sets the value of the sequence property.
+   * 
+   * @param value
+   *          allowed object is {@link IsoformType.Sequence }
+   * 
+   */
+  public void setSequence(IsoformType.Sequence value)
+  {
+    this.sequence = value;
+  }
+
+  /**
+   * Gets the value of the text property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the text property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getText().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EvidencedStringType }
+   * 
+   * 
+   */
+  public List<EvidencedStringType> getText()
+  {
+    if (text == null)
+    {
+      text = new ArrayList<EvidencedStringType>();
     }
+    return this.text;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;simpleContent>
+   *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+   *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
+   *     &lt;/extension>
+   *   &lt;/simpleContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "value" })
+  public static class Name
+  {
+
+    @XmlValue
+    protected String value;
+
+    @XmlAttribute(name = "evidence")
+    protected List<Integer> evidence;
 
     /**
-     * Gets the value of the sequence property.
+     * Gets the value of the value property.
+     * 
+     * @return possible object is {@link String }
      * 
-     * @return
-     *     possible object is
-     *     {@link IsoformType.Sequence }
-     *     
      */
-    public IsoformType.Sequence getSequence() {
-        return sequence;
+    public String getValue()
+    {
+      return value;
     }
 
     /**
-     * Sets the value of the sequence property.
+     * Sets the value of the value property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link IsoformType.Sequence }
-     *     
+     *          allowed object is {@link String }
+     * 
      */
-    public void setSequence(IsoformType.Sequence value) {
-        this.sequence = value;
+    public void setValue(String value)
+    {
+      this.value = value;
     }
 
     /**
-     * Gets the value of the text property.
+     * Gets the value of the evidence property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the text property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the evidence property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getText().add(newItem);
+     * getEvidence().add(newItem);
      * </pre>
      * 
      * 
      * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EvidencedStringType }
+     * Objects of the following type(s) are allowed in the list {@link Integer }
      * 
      * 
      */
-    public List<EvidencedStringType> getText() {
-        if (text == null) {
-            text = new ArrayList<EvidencedStringType>();
-        }
-        return this.text;
+    public List<Integer> getEvidence()
+    {
+      if (evidence == null)
+      {
+        evidence = new ArrayList<Integer>();
+      }
+      return this.evidence;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;attribute name="type" use="required">
+   *         &lt;simpleType>
+   *           &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+   *             &lt;enumeration value="not described"/>
+   *             &lt;enumeration value="described"/>
+   *             &lt;enumeration value="displayed"/>
+   *             &lt;enumeration value="external"/>
+   *           &lt;/restriction>
+   *         &lt;/simpleType>
+   *       &lt;/attribute>
+   *       &lt;attribute name="ref" type="{http://www.w3.org/2001/XMLSchema}string" />
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "")
+  public static class Sequence
+  {
+
+    @XmlAttribute(name = "type", required = true)
+    protected String type;
+
+    @XmlAttribute(name = "ref")
+    protected String ref;
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the type property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @return possible object is {@link String }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;simpleContent>
-     *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
-     *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
-     *     &lt;/extension>
-     *   &lt;/simpleContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public String getType()
+    {
+      return type;
+    }
+
+    /**
+     * Sets the value of the type property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "value"
-    })
-    public static class Name {
-
-        @XmlValue
-        protected String value;
-        @XmlAttribute(name = "evidence")
-        protected List<Integer> evidence;
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-
-        /**
-         * Gets the value of the evidence property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the evidence property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getEvidence().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link Integer }
-         * 
-         * 
-         */
-        public List<Integer> getEvidence() {
-            if (evidence == null) {
-                evidence = new ArrayList<Integer>();
-            }
-            return this.evidence;
-        }
-
+    public void setType(String value)
+    {
+      this.type = value;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the ref property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @return possible object is {@link String }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;attribute name="type" use="required">
-     *         &lt;simpleType>
-     *           &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
-     *             &lt;enumeration value="not described"/>
-     *             &lt;enumeration value="described"/>
-     *             &lt;enumeration value="displayed"/>
-     *             &lt;enumeration value="external"/>
-     *           &lt;/restriction>
-     *         &lt;/simpleType>
-     *       &lt;/attribute>
-     *       &lt;attribute name="ref" type="{http://www.w3.org/2001/XMLSchema}string" />
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public String getRef()
+    {
+      return ref;
+    }
+
+    /**
+     * Sets the value of the ref property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "")
-    public static class Sequence {
-
-        @XmlAttribute(name = "type", required = true)
-        protected String type;
-        @XmlAttribute(name = "ref")
-        protected String ref;
-
-        /**
-         * Gets the value of the type property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getType() {
-            return type;
-        }
-
-        /**
-         * Sets the value of the type property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setType(String value) {
-            this.type = value;
-        }
-
-        /**
-         * Gets the value of the ref property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getRef() {
-            return ref;
-        }
-
-        /**
-         * Sets the value of the ref property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setRef(String value) {
-            this.ref = value;
-        }
-
+    public void setRef(String value)
+    {
+      this.ref = value;
     }
 
+  }
+
 }
index f6409ee..0c10761 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-
 /**
- * <p>Java class for keywordType complex type.
+ * <p>
+ * Java class for keywordType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="keywordType">
@@ -36,93 +37,94 @@ import javax.xml.bind.annotation.XmlValue;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "keywordType", propOrder = {
-    "value"
-})
-public class KeywordType {
+@XmlType(name = "keywordType", propOrder = { "value" })
+public class KeywordType
+{
 
-    @XmlValue
-    protected String value;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
-    @XmlAttribute(name = "id", required = true)
-    protected String id;
+  @XmlValue
+  protected String value;
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  @XmlAttribute(name = "id", required = true)
+  protected String id;
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
 
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
-    }
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
 
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
+
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
+
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
 
 }
index 62e9999..1aa1925 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,13 +12,17 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes a sequence location as either a range with a begin and end or as a position. The 'sequence' attribute is only used when the location is not on the canonical sequence displayed in the current entry.
+ * Describes a sequence location as either a range with a begin and end or as a
+ * position. The 'sequence' attribute is only used when the location is not on
+ * the canonical sequence displayed in the current entry.
  * 
- * <p>Java class for locationType complex type.
+ * <p>
+ * Java class for locationType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="locationType">
@@ -41,113 +44,109 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "locationType", propOrder = {
-    "begin",
-    "end",
-    "position"
-})
-public class LocationType {
-
-    protected PositionType begin;
-    protected PositionType end;
-    protected PositionType position;
-    @XmlAttribute(name = "sequence")
-    protected String sequence;
-
-    /**
-     * Gets the value of the begin property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link PositionType }
-     *     
-     */
-    public PositionType getBegin() {
-        return begin;
-    }
-
-    /**
-     * Sets the value of the begin property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link PositionType }
-     *     
-     */
-    public void setBegin(PositionType value) {
-        this.begin = value;
-    }
-
-    /**
-     * Gets the value of the end property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link PositionType }
-     *     
-     */
-    public PositionType getEnd() {
-        return end;
-    }
-
-    /**
-     * Sets the value of the end property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link PositionType }
-     *     
-     */
-    public void setEnd(PositionType value) {
-        this.end = value;
-    }
-
-    /**
-     * Gets the value of the position property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link PositionType }
-     *     
-     */
-    public PositionType getPosition() {
-        return position;
-    }
-
-    /**
-     * Sets the value of the position property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link PositionType }
-     *     
-     */
-    public void setPosition(PositionType value) {
-        this.position = value;
-    }
-
-    /**
-     * Gets the value of the sequence property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getSequence() {
-        return sequence;
-    }
-
-    /**
-     * Sets the value of the sequence property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setSequence(String value) {
-        this.sequence = value;
-    }
+@XmlType(name = "locationType", propOrder = { "begin", "end", "position" })
+public class LocationType
+{
+
+  protected PositionType begin;
+
+  protected PositionType end;
+
+  protected PositionType position;
+
+  @XmlAttribute(name = "sequence")
+  protected String sequence;
+
+  /**
+   * Gets the value of the begin property.
+   * 
+   * @return possible object is {@link PositionType }
+   * 
+   */
+  public PositionType getBegin()
+  {
+    return begin;
+  }
+
+  /**
+   * Sets the value of the begin property.
+   * 
+   * @param value
+   *          allowed object is {@link PositionType }
+   * 
+   */
+  public void setBegin(PositionType value)
+  {
+    this.begin = value;
+  }
+
+  /**
+   * Gets the value of the end property.
+   * 
+   * @return possible object is {@link PositionType }
+   * 
+   */
+  public PositionType getEnd()
+  {
+    return end;
+  }
+
+  /**
+   * Sets the value of the end property.
+   * 
+   * @param value
+   *          allowed object is {@link PositionType }
+   * 
+   */
+  public void setEnd(PositionType value)
+  {
+    this.end = value;
+  }
+
+  /**
+   * Gets the value of the position property.
+   * 
+   * @return possible object is {@link PositionType }
+   * 
+   */
+  public PositionType getPosition()
+  {
+    return position;
+  }
+
+  /**
+   * Sets the value of the position property.
+   * 
+   * @param value
+   *          allowed object is {@link PositionType }
+   * 
+   */
+  public void setPosition(PositionType value)
+  {
+    this.position = value;
+  }
+
+  /**
+   * Gets the value of the sequence property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getSequence()
+  {
+    return sequence;
+  }
+
+  /**
+   * Sets the value of the sequence property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setSequence(String value)
+  {
+    this.sequence = value;
+  }
 
 }
index 8b52523..3b6d294 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -14,13 +13,15 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-
 /**
  * Describes a molecule by name or unique identifier.
  * 
- * <p>Java class for moleculeType complex type.
+ * <p>
+ * Java class for moleculeType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="moleculeType">
@@ -35,62 +36,60 @@ import javax.xml.bind.annotation.XmlValue;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "moleculeType", propOrder = {
-    "value"
-})
-public class MoleculeType {
+@XmlType(name = "moleculeType", propOrder = { "value" })
+public class MoleculeType
+{
+
+  @XmlValue
+  protected String value;
 
-    @XmlValue
-    protected String value;
-    @XmlAttribute(name = "id")
-    protected String id;
+  @XmlAttribute(name = "id")
+  protected String id;
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
 
-    /**
-     * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getId() {
-        return id;
-    }
+  /**
+   * Gets the value of the id property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getId()
+  {
+    return id;
+  }
 
-    /**
-     * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setId(String value) {
-        this.id = value;
-    }
+  /**
+   * Sets the value of the id property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setId(String value)
+  {
+    this.id = value;
+  }
 
 }
index be68867..89496ec 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElements;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for nameListType complex type.
+ * <p>
+ * Java class for nameListType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="nameListType">
@@ -38,45 +39,45 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "nameListType", propOrder = {
-    "consortiumOrPerson"
-})
-public class NameListType {
+@XmlType(name = "nameListType", propOrder = { "consortiumOrPerson" })
+public class NameListType
+{
 
-    @XmlElements({
-        @XmlElement(name = "consortium", type = ConsortiumType.class),
-        @XmlElement(name = "person", type = PersonType.class)
-    })
-    protected List<Object> consortiumOrPerson;
+  @XmlElements({
+      @XmlElement(name = "consortium", type = ConsortiumType.class),
+      @XmlElement(name = "person", type = PersonType.class) })
+  protected List<Object> consortiumOrPerson;
 
-    /**
-     * Gets the value of the consortiumOrPerson property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the consortiumOrPerson property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getConsortiumOrPerson().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link ConsortiumType }
-     * {@link PersonType }
-     * 
-     * 
-     */
-    public List<Object> getConsortiumOrPerson() {
-        if (consortiumOrPerson == null) {
-            consortiumOrPerson = new ArrayList<Object>();
-        }
-        return this.consortiumOrPerson;
+  /**
+   * Gets the value of the consortiumOrPerson property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the consortiumOrPerson property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getConsortiumOrPerson().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link ConsortiumType } {@link PersonType }
+   * 
+   * 
+   */
+  public List<Object> getConsortiumOrPerson()
+  {
+    if (consortiumOrPerson == null)
+    {
+      consortiumOrPerson = new ArrayList<Object>();
     }
+    return this.consortiumOrPerson;
+  }
 
 }
index e2bb255..07967eb 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.JAXBElement;
@@ -13,496 +12,558 @@ import javax.xml.bind.annotation.XmlElementDecl;
 import javax.xml.bind.annotation.XmlRegistry;
 import javax.xml.namespace.QName;
 
-
 /**
- * This object contains factory methods for each 
- * Java content interface and Java element interface 
- * generated in the jalview.xml.binding.uniprot package. 
- * <p>An ObjectFactory allows you to programatically 
- * construct new instances of the Java representation 
- * for XML content. The Java representation of XML 
- * content can consist of schema derived interfaces 
- * and classes representing the binding of schema 
- * type definitions, element declarations and model 
- * groups.  Factory methods for each of these are 
- * provided in this class.
+ * This object contains factory methods for each Java content interface and Java
+ * element interface generated in the jalview.xml.binding.uniprot package.
+ * <p>
+ * An ObjectFactory allows you to programatically construct new instances of the
+ * Java representation for XML content. The Java representation of XML content
+ * can consist of schema derived interfaces and classes representing the binding
+ * of schema type definitions, element declarations and model groups. Factory
+ * methods for each of these are provided in this class.
  * 
  */
 @XmlRegistry
-public class ObjectFactory {
-
-    private final static QName _Copyright_QNAME = new QName("http://uniprot.org/uniprot", "copyright");
-
-    /**
-     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: jalview.xml.binding.uniprot
-     * 
-     */
-    public ObjectFactory() {
-    }
-
-    /**
-     * Create an instance of {@link SourceDataType }
-     * 
-     */
-    public SourceDataType createSourceDataType() {
-        return new SourceDataType();
-    }
-
-    /**
-     * Create an instance of {@link IsoformType }
-     * 
-     */
-    public IsoformType createIsoformType() {
-        return new IsoformType();
-    }
-
-    /**
-     * Create an instance of {@link CommentType }
-     * 
-     */
-    public CommentType createCommentType() {
-        return new CommentType();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.Conflict }
-     * 
-     */
-    public CommentType.Conflict createCommentTypeConflict() {
-        return new CommentType.Conflict();
-    }
-
-    /**
-     * Create an instance of {@link OrganismType }
-     * 
-     */
-    public OrganismType createOrganismType() {
-        return new OrganismType();
-    }
-
-    /**
-     * Create an instance of {@link ProteinType }
-     * 
-     */
-    public ProteinType createProteinType() {
-        return new ProteinType();
-    }
-
-    /**
-     * Create an instance of {@link Entry }
-     * 
-     */
-    public Entry createEntry() {
-        return new Entry();
-    }
-
-    /**
-     * Create an instance of {@link GeneType }
-     * 
-     */
-    public GeneType createGeneType() {
-        return new GeneType();
-    }
-
-    /**
-     * Create an instance of {@link GeneLocationType }
-     * 
-     */
-    public GeneLocationType createGeneLocationType() {
-        return new GeneLocationType();
-    }
-
-    /**
-     * Create an instance of {@link ReferenceType }
-     * 
-     */
-    public ReferenceType createReferenceType() {
-        return new ReferenceType();
-    }
-
-    /**
-     * Create an instance of {@link DbReferenceType }
-     * 
-     */
-    public DbReferenceType createDbReferenceType() {
-        return new DbReferenceType();
-    }
-
-    /**
-     * Create an instance of {@link ProteinExistenceType }
-     * 
-     */
-    public ProteinExistenceType createProteinExistenceType() {
-        return new ProteinExistenceType();
-    }
-
-    /**
-     * Create an instance of {@link KeywordType }
-     * 
-     */
-    public KeywordType createKeywordType() {
-        return new KeywordType();
-    }
-
-    /**
-     * Create an instance of {@link FeatureType }
-     * 
-     */
-    public FeatureType createFeatureType() {
-        return new FeatureType();
-    }
-
-    /**
-     * Create an instance of {@link EvidenceType }
-     * 
-     */
-    public EvidenceType createEvidenceType() {
-        return new EvidenceType();
-    }
-
-    /**
-     * Create an instance of {@link SequenceType }
-     * 
-     */
-    public SequenceType createSequenceType() {
-        return new SequenceType();
-    }
-
-    /**
-     * Create an instance of {@link Uniprot }
-     * 
-     */
-    public Uniprot createUniprot() {
-        return new Uniprot();
-    }
-
-    /**
-     * Create an instance of {@link StatusType }
-     * 
-     */
-    public StatusType createStatusType() {
-        return new StatusType();
-    }
-
-    /**
-     * Create an instance of {@link PositionType }
-     * 
-     */
-    public PositionType createPositionType() {
-        return new PositionType();
-    }
-
-    /**
-     * Create an instance of {@link ConsortiumType }
-     * 
-     */
-    public ConsortiumType createConsortiumType() {
-        return new ConsortiumType();
-    }
-
-    /**
-     * Create an instance of {@link GeneNameType }
-     * 
-     */
-    public GeneNameType createGeneNameType() {
-        return new GeneNameType();
-    }
-
-    /**
-     * Create an instance of {@link LocationType }
-     * 
-     */
-    public LocationType createLocationType() {
-        return new LocationType();
-    }
-
-    /**
-     * Create an instance of {@link CitationType }
-     * 
-     */
-    public CitationType createCitationType() {
-        return new CitationType();
-    }
-
-    /**
-     * Create an instance of {@link PropertyType }
-     * 
-     */
-    public PropertyType createPropertyType() {
-        return new PropertyType();
-    }
-
-    /**
-     * Create an instance of {@link PhysiologicalReactionType }
-     * 
-     */
-    public PhysiologicalReactionType createPhysiologicalReactionType() {
-        return new PhysiologicalReactionType();
-    }
-
-    /**
-     * Create an instance of {@link CofactorType }
-     * 
-     */
-    public CofactorType createCofactorType() {
-        return new CofactorType();
-    }
-
-    /**
-     * Create an instance of {@link EvidencedStringType }
-     * 
-     */
-    public EvidencedStringType createEvidencedStringType() {
-        return new EvidencedStringType();
-    }
-
-    /**
-     * Create an instance of {@link PersonType }
-     * 
-     */
-    public PersonType createPersonType() {
-        return new PersonType();
-    }
-
-    /**
-     * Create an instance of {@link ImportedFromType }
-     * 
-     */
-    public ImportedFromType createImportedFromType() {
-        return new ImportedFromType();
-    }
-
-    /**
-     * Create an instance of {@link EventType }
-     * 
-     */
-    public EventType createEventType() {
-        return new EventType();
-    }
-
-    /**
-     * Create an instance of {@link InteractantType }
-     * 
-     */
-    public InteractantType createInteractantType() {
-        return new InteractantType();
-    }
-
-    /**
-     * Create an instance of {@link NameListType }
-     * 
-     */
-    public NameListType createNameListType() {
-        return new NameListType();
-    }
-
-    /**
-     * Create an instance of {@link ReactionType }
-     * 
-     */
-    public ReactionType createReactionType() {
-        return new ReactionType();
-    }
-
-    /**
-     * Create an instance of {@link SourceType }
-     * 
-     */
-    public SourceType createSourceType() {
-        return new SourceType();
-    }
-
-    /**
-     * Create an instance of {@link MoleculeType }
-     * 
-     */
-    public MoleculeType createMoleculeType() {
-        return new MoleculeType();
-    }
-
-    /**
-     * Create an instance of {@link OrganismNameType }
-     * 
-     */
-    public OrganismNameType createOrganismNameType() {
-        return new OrganismNameType();
-    }
-
-    /**
-     * Create an instance of {@link SubcellularLocationType }
-     * 
-     */
-    public SubcellularLocationType createSubcellularLocationType() {
-        return new SubcellularLocationType();
-    }
-
-    /**
-     * Create an instance of {@link SourceDataType.Strain }
-     * 
-     */
-    public SourceDataType.Strain createSourceDataTypeStrain() {
-        return new SourceDataType.Strain();
-    }
-
-    /**
-     * Create an instance of {@link SourceDataType.Plasmid }
-     * 
-     */
-    public SourceDataType.Plasmid createSourceDataTypePlasmid() {
-        return new SourceDataType.Plasmid();
-    }
-
-    /**
-     * Create an instance of {@link SourceDataType.Transposon }
-     * 
-     */
-    public SourceDataType.Transposon createSourceDataTypeTransposon() {
-        return new SourceDataType.Transposon();
-    }
-
-    /**
-     * Create an instance of {@link SourceDataType.Tissue }
-     * 
-     */
-    public SourceDataType.Tissue createSourceDataTypeTissue() {
-        return new SourceDataType.Tissue();
-    }
-
-    /**
-     * Create an instance of {@link IsoformType.Name }
-     * 
-     */
-    public IsoformType.Name createIsoformTypeName() {
-        return new IsoformType.Name();
-    }
-
-    /**
-     * Create an instance of {@link IsoformType.Sequence }
-     * 
-     */
-    public IsoformType.Sequence createIsoformTypeSequence() {
-        return new IsoformType.Sequence();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.Absorption }
-     * 
-     */
-    public CommentType.Absorption createCommentTypeAbsorption() {
-        return new CommentType.Absorption();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.Kinetics }
-     * 
-     */
-    public CommentType.Kinetics createCommentTypeKinetics() {
-        return new CommentType.Kinetics();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.PhDependence }
-     * 
-     */
-    public CommentType.PhDependence createCommentTypePhDependence() {
-        return new CommentType.PhDependence();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.RedoxPotential }
-     * 
-     */
-    public CommentType.RedoxPotential createCommentTypeRedoxPotential() {
-        return new CommentType.RedoxPotential();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.TemperatureDependence }
-     * 
-     */
-    public CommentType.TemperatureDependence createCommentTypeTemperatureDependence() {
-        return new CommentType.TemperatureDependence();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.Link }
-     * 
-     */
-    public CommentType.Link createCommentTypeLink() {
-        return new CommentType.Link();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.Disease }
-     * 
-     */
-    public CommentType.Disease createCommentTypeDisease() {
-        return new CommentType.Disease();
-    }
-
-    /**
-     * Create an instance of {@link CommentType.Conflict.Sequence }
-     * 
-     */
-    public CommentType.Conflict.Sequence createCommentTypeConflictSequence() {
-        return new CommentType.Conflict.Sequence();
-    }
-
-    /**
-     * Create an instance of {@link OrganismType.Lineage }
-     * 
-     */
-    public OrganismType.Lineage createOrganismTypeLineage() {
-        return new OrganismType.Lineage();
-    }
-
-    /**
-     * Create an instance of {@link ProteinType.RecommendedName }
-     * 
-     */
-    public ProteinType.RecommendedName createProteinTypeRecommendedName() {
-        return new ProteinType.RecommendedName();
-    }
-
-    /**
-     * Create an instance of {@link ProteinType.AlternativeName }
-     * 
-     */
-    public ProteinType.AlternativeName createProteinTypeAlternativeName() {
-        return new ProteinType.AlternativeName();
-    }
-
-    /**
-     * Create an instance of {@link ProteinType.SubmittedName }
-     * 
-     */
-    public ProteinType.SubmittedName createProteinTypeSubmittedName() {
-        return new ProteinType.SubmittedName();
-    }
-
-    /**
-     * Create an instance of {@link ProteinType.Domain }
-     * 
-     */
-    public ProteinType.Domain createProteinTypeDomain() {
-        return new ProteinType.Domain();
-    }
-
-    /**
-     * Create an instance of {@link ProteinType.Component }
-     * 
-     */
-    public ProteinType.Component createProteinTypeComponent() {
-        return new ProteinType.Component();
-    }
-
-    /**
-     * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}}
-     * 
-     */
-    @XmlElementDecl(namespace = "http://uniprot.org/uniprot", name = "copyright")
-    public JAXBElement<String> createCopyright(String value) {
-        return new JAXBElement<String>(_Copyright_QNAME, String.class, null, value);
-    }
+public class ObjectFactory
+{
+
+  private final static QName _Copyright_QNAME = new QName(
+          "http://uniprot.org/uniprot", "copyright");
+
+  /**
+   * Create a new ObjectFactory that can be used to create new instances of
+   * schema derived classes for package: jalview.xml.binding.uniprot
+   * 
+   */
+  public ObjectFactory()
+  {
+  }
+
+  /**
+   * Create an instance of {@link SourceDataType }
+   * 
+   */
+  public SourceDataType createSourceDataType()
+  {
+    return new SourceDataType();
+  }
+
+  /**
+   * Create an instance of {@link IsoformType }
+   * 
+   */
+  public IsoformType createIsoformType()
+  {
+    return new IsoformType();
+  }
+
+  /**
+   * Create an instance of {@link CommentType }
+   * 
+   */
+  public CommentType createCommentType()
+  {
+    return new CommentType();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.Conflict }
+   * 
+   */
+  public CommentType.Conflict createCommentTypeConflict()
+  {
+    return new CommentType.Conflict();
+  }
+
+  /**
+   * Create an instance of {@link OrganismType }
+   * 
+   */
+  public OrganismType createOrganismType()
+  {
+    return new OrganismType();
+  }
+
+  /**
+   * Create an instance of {@link ProteinType }
+   * 
+   */
+  public ProteinType createProteinType()
+  {
+    return new ProteinType();
+  }
+
+  /**
+   * Create an instance of {@link Entry }
+   * 
+   */
+  public Entry createEntry()
+  {
+    return new Entry();
+  }
+
+  /**
+   * Create an instance of {@link GeneType }
+   * 
+   */
+  public GeneType createGeneType()
+  {
+    return new GeneType();
+  }
+
+  /**
+   * Create an instance of {@link GeneLocationType }
+   * 
+   */
+  public GeneLocationType createGeneLocationType()
+  {
+    return new GeneLocationType();
+  }
+
+  /**
+   * Create an instance of {@link ReferenceType }
+   * 
+   */
+  public ReferenceType createReferenceType()
+  {
+    return new ReferenceType();
+  }
+
+  /**
+   * Create an instance of {@link DbReferenceType }
+   * 
+   */
+  public DbReferenceType createDbReferenceType()
+  {
+    return new DbReferenceType();
+  }
+
+  /**
+   * Create an instance of {@link ProteinExistenceType }
+   * 
+   */
+  public ProteinExistenceType createProteinExistenceType()
+  {
+    return new ProteinExistenceType();
+  }
+
+  /**
+   * Create an instance of {@link KeywordType }
+   * 
+   */
+  public KeywordType createKeywordType()
+  {
+    return new KeywordType();
+  }
+
+  /**
+   * Create an instance of {@link FeatureType }
+   * 
+   */
+  public FeatureType createFeatureType()
+  {
+    return new FeatureType();
+  }
+
+  /**
+   * Create an instance of {@link EvidenceType }
+   * 
+   */
+  public EvidenceType createEvidenceType()
+  {
+    return new EvidenceType();
+  }
+
+  /**
+   * Create an instance of {@link SequenceType }
+   * 
+   */
+  public SequenceType createSequenceType()
+  {
+    return new SequenceType();
+  }
+
+  /**
+   * Create an instance of {@link Uniprot }
+   * 
+   */
+  public Uniprot createUniprot()
+  {
+    return new Uniprot();
+  }
+
+  /**
+   * Create an instance of {@link StatusType }
+   * 
+   */
+  public StatusType createStatusType()
+  {
+    return new StatusType();
+  }
+
+  /**
+   * Create an instance of {@link PositionType }
+   * 
+   */
+  public PositionType createPositionType()
+  {
+    return new PositionType();
+  }
+
+  /**
+   * Create an instance of {@link ConsortiumType }
+   * 
+   */
+  public ConsortiumType createConsortiumType()
+  {
+    return new ConsortiumType();
+  }
+
+  /**
+   * Create an instance of {@link GeneNameType }
+   * 
+   */
+  public GeneNameType createGeneNameType()
+  {
+    return new GeneNameType();
+  }
+
+  /**
+   * Create an instance of {@link LocationType }
+   * 
+   */
+  public LocationType createLocationType()
+  {
+    return new LocationType();
+  }
+
+  /**
+   * Create an instance of {@link CitationType }
+   * 
+   */
+  public CitationType createCitationType()
+  {
+    return new CitationType();
+  }
+
+  /**
+   * Create an instance of {@link PropertyType }
+   * 
+   */
+  public PropertyType createPropertyType()
+  {
+    return new PropertyType();
+  }
+
+  /**
+   * Create an instance of {@link PhysiologicalReactionType }
+   * 
+   */
+  public PhysiologicalReactionType createPhysiologicalReactionType()
+  {
+    return new PhysiologicalReactionType();
+  }
+
+  /**
+   * Create an instance of {@link CofactorType }
+   * 
+   */
+  public CofactorType createCofactorType()
+  {
+    return new CofactorType();
+  }
+
+  /**
+   * Create an instance of {@link EvidencedStringType }
+   * 
+   */
+  public EvidencedStringType createEvidencedStringType()
+  {
+    return new EvidencedStringType();
+  }
+
+  /**
+   * Create an instance of {@link PersonType }
+   * 
+   */
+  public PersonType createPersonType()
+  {
+    return new PersonType();
+  }
+
+  /**
+   * Create an instance of {@link ImportedFromType }
+   * 
+   */
+  public ImportedFromType createImportedFromType()
+  {
+    return new ImportedFromType();
+  }
+
+  /**
+   * Create an instance of {@link EventType }
+   * 
+   */
+  public EventType createEventType()
+  {
+    return new EventType();
+  }
+
+  /**
+   * Create an instance of {@link InteractantType }
+   * 
+   */
+  public InteractantType createInteractantType()
+  {
+    return new InteractantType();
+  }
+
+  /**
+   * Create an instance of {@link NameListType }
+   * 
+   */
+  public NameListType createNameListType()
+  {
+    return new NameListType();
+  }
+
+  /**
+   * Create an instance of {@link ReactionType }
+   * 
+   */
+  public ReactionType createReactionType()
+  {
+    return new ReactionType();
+  }
+
+  /**
+   * Create an instance of {@link SourceType }
+   * 
+   */
+  public SourceType createSourceType()
+  {
+    return new SourceType();
+  }
+
+  /**
+   * Create an instance of {@link MoleculeType }
+   * 
+   */
+  public MoleculeType createMoleculeType()
+  {
+    return new MoleculeType();
+  }
+
+  /**
+   * Create an instance of {@link OrganismNameType }
+   * 
+   */
+  public OrganismNameType createOrganismNameType()
+  {
+    return new OrganismNameType();
+  }
+
+  /**
+   * Create an instance of {@link SubcellularLocationType }
+   * 
+   */
+  public SubcellularLocationType createSubcellularLocationType()
+  {
+    return new SubcellularLocationType();
+  }
+
+  /**
+   * Create an instance of {@link SourceDataType.Strain }
+   * 
+   */
+  public SourceDataType.Strain createSourceDataTypeStrain()
+  {
+    return new SourceDataType.Strain();
+  }
+
+  /**
+   * Create an instance of {@link SourceDataType.Plasmid }
+   * 
+   */
+  public SourceDataType.Plasmid createSourceDataTypePlasmid()
+  {
+    return new SourceDataType.Plasmid();
+  }
+
+  /**
+   * Create an instance of {@link SourceDataType.Transposon }
+   * 
+   */
+  public SourceDataType.Transposon createSourceDataTypeTransposon()
+  {
+    return new SourceDataType.Transposon();
+  }
+
+  /**
+   * Create an instance of {@link SourceDataType.Tissue }
+   * 
+   */
+  public SourceDataType.Tissue createSourceDataTypeTissue()
+  {
+    return new SourceDataType.Tissue();
+  }
+
+  /**
+   * Create an instance of {@link IsoformType.Name }
+   * 
+   */
+  public IsoformType.Name createIsoformTypeName()
+  {
+    return new IsoformType.Name();
+  }
+
+  /**
+   * Create an instance of {@link IsoformType.Sequence }
+   * 
+   */
+  public IsoformType.Sequence createIsoformTypeSequence()
+  {
+    return new IsoformType.Sequence();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.Absorption }
+   * 
+   */
+  public CommentType.Absorption createCommentTypeAbsorption()
+  {
+    return new CommentType.Absorption();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.Kinetics }
+   * 
+   */
+  public CommentType.Kinetics createCommentTypeKinetics()
+  {
+    return new CommentType.Kinetics();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.PhDependence }
+   * 
+   */
+  public CommentType.PhDependence createCommentTypePhDependence()
+  {
+    return new CommentType.PhDependence();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.RedoxPotential }
+   * 
+   */
+  public CommentType.RedoxPotential createCommentTypeRedoxPotential()
+  {
+    return new CommentType.RedoxPotential();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.TemperatureDependence }
+   * 
+   */
+  public CommentType.TemperatureDependence createCommentTypeTemperatureDependence()
+  {
+    return new CommentType.TemperatureDependence();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.Link }
+   * 
+   */
+  public CommentType.Link createCommentTypeLink()
+  {
+    return new CommentType.Link();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.Disease }
+   * 
+   */
+  public CommentType.Disease createCommentTypeDisease()
+  {
+    return new CommentType.Disease();
+  }
+
+  /**
+   * Create an instance of {@link CommentType.Conflict.Sequence }
+   * 
+   */
+  public CommentType.Conflict.Sequence createCommentTypeConflictSequence()
+  {
+    return new CommentType.Conflict.Sequence();
+  }
+
+  /**
+   * Create an instance of {@link OrganismType.Lineage }
+   * 
+   */
+  public OrganismType.Lineage createOrganismTypeLineage()
+  {
+    return new OrganismType.Lineage();
+  }
+
+  /**
+   * Create an instance of {@link ProteinType.RecommendedName }
+   * 
+   */
+  public ProteinType.RecommendedName createProteinTypeRecommendedName()
+  {
+    return new ProteinType.RecommendedName();
+  }
+
+  /**
+   * Create an instance of {@link ProteinType.AlternativeName }
+   * 
+   */
+  public ProteinType.AlternativeName createProteinTypeAlternativeName()
+  {
+    return new ProteinType.AlternativeName();
+  }
+
+  /**
+   * Create an instance of {@link ProteinType.SubmittedName }
+   * 
+   */
+  public ProteinType.SubmittedName createProteinTypeSubmittedName()
+  {
+    return new ProteinType.SubmittedName();
+  }
+
+  /**
+   * Create an instance of {@link ProteinType.Domain }
+   * 
+   */
+  public ProteinType.Domain createProteinTypeDomain()
+  {
+    return new ProteinType.Domain();
+  }
+
+  /**
+   * Create an instance of {@link ProteinType.Component }
+   * 
+   */
+  public ProteinType.Component createProteinTypeComponent()
+  {
+    return new ProteinType.Component();
+  }
+
+  /**
+   * Create an instance of {@link JAXBElement }{@code <}{@link String
+   * }{@code >}}
+   * 
+   */
+  @XmlElementDecl(
+    namespace = "http://uniprot.org/uniprot",
+    name = "copyright")
+  public JAXBElement<String> createCopyright(String value)
+  {
+    return new JAXBElement<String>(_Copyright_QNAME, String.class, null,
+            value);
+  }
 
 }
index bc5c8c5..de03ff2 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -14,13 +13,15 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-
 /**
  * Describes different types of source organism names.
  * 
- * <p>Java class for organismNameType complex type.
+ * <p>
+ * Java class for organismNameType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="organismNameType">
@@ -45,62 +46,60 @@ import javax.xml.bind.annotation.XmlValue;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "organismNameType", propOrder = {
-    "value"
-})
-public class OrganismNameType {
+@XmlType(name = "organismNameType", propOrder = { "value" })
+public class OrganismNameType
+{
+
+  @XmlValue
+  protected String value;
 
-    @XmlValue
-    protected String value;
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
 
 }
index bb76add..b053df8 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,13 +15,15 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * Describes the source organism.
  * 
- * <p>Java class for organismType complex type.
+ * <p>
+ * Java class for organismType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="organismType">
@@ -52,190 +53,203 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "organismType", propOrder = {
-    "name",
-    "dbReference",
-    "lineage"
-})
-public class OrganismType {
-
-    @XmlElement(required = true)
-    protected List<OrganismNameType> name;
-    @XmlElement(required = true)
-    protected List<DbReferenceType> dbReference;
-    protected OrganismType.Lineage lineage;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
-
-    /**
-     * Gets the value of the name property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the name property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getName().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link OrganismNameType }
-     * 
-     * 
-     */
-    public List<OrganismNameType> getName() {
-        if (name == null) {
-            name = new ArrayList<OrganismNameType>();
-        }
-        return this.name;
+@XmlType(
+  name = "organismType",
+  propOrder =
+  { "name", "dbReference", "lineage" })
+public class OrganismType
+{
+
+  @XmlElement(required = true)
+  protected List<OrganismNameType> name;
+
+  @XmlElement(required = true)
+  protected List<DbReferenceType> dbReference;
+
+  protected OrganismType.Lineage lineage;
+
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
+
+  /**
+   * Gets the value of the name property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the name property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link OrganismNameType }
+   * 
+   * 
+   */
+  public List<OrganismNameType> getName()
+  {
+    if (name == null)
+    {
+      name = new ArrayList<OrganismNameType>();
     }
-
-    /**
-     * Gets the value of the dbReference property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the dbReference property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getDbReference().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link DbReferenceType }
-     * 
-     * 
-     */
-    public List<DbReferenceType> getDbReference() {
-        if (dbReference == null) {
-            dbReference = new ArrayList<DbReferenceType>();
-        }
-        return this.dbReference;
+    return this.name;
+  }
+
+  /**
+   * Gets the value of the dbReference property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the dbReference property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getDbReference().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link DbReferenceType }
+   * 
+   * 
+   */
+  public List<DbReferenceType> getDbReference()
+  {
+    if (dbReference == null)
+    {
+      dbReference = new ArrayList<DbReferenceType>();
     }
-
-    /**
-     * Gets the value of the lineage property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link OrganismType.Lineage }
-     *     
-     */
-    public OrganismType.Lineage getLineage() {
-        return lineage;
+    return this.dbReference;
+  }
+
+  /**
+   * Gets the value of the lineage property.
+   * 
+   * @return possible object is {@link OrganismType.Lineage }
+   * 
+   */
+  public OrganismType.Lineage getLineage()
+  {
+    return lineage;
+  }
+
+  /**
+   * Sets the value of the lineage property.
+   * 
+   * @param value
+   *          allowed object is {@link OrganismType.Lineage }
+   * 
+   */
+  public void setLineage(OrganismType.Lineage value)
+  {
+    this.lineage = value;
+  }
+
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="taxon" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "taxon" })
+  public static class Lineage
+  {
 
-    /**
-     * Sets the value of the lineage property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link OrganismType.Lineage }
-     *     
-     */
-    public void setLineage(OrganismType.Lineage value) {
-        this.lineage = value;
-    }
+    @XmlElement(required = true)
+    protected List<String> taxon;
 
     /**
-     * Gets the value of the evidence property.
+     * Gets the value of the taxon property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the taxon property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getEvidence().add(newItem);
+     * getTaxon().add(newItem);
      * </pre>
      * 
      * 
      * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
+     * Objects of the following type(s) are allowed in the list {@link String }
      * 
      * 
      */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
+    public List<String> getTaxon()
+    {
+      if (taxon == null)
+      {
+        taxon = new ArrayList<String>();
+      }
+      return this.taxon;
     }
 
-
-    /**
-     * <p>Java class for anonymous complex type.
-     * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
-     * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="taxon" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
-     * 
-     * 
-     */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "taxon"
-    })
-    public static class Lineage {
-
-        @XmlElement(required = true)
-        protected List<String> taxon;
-
-        /**
-         * Gets the value of the taxon property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the taxon property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getTaxon().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link String }
-         * 
-         * 
-         */
-        public List<String> getTaxon() {
-            if (taxon == null) {
-                taxon = new ArrayList<String>();
-            }
-            return this.taxon;
-        }
-
-    }
+  }
 
 }
index 1354092..0887b7b 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,11 +12,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for personType complex type.
+ * <p>
+ * Java class for personType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="personType">
@@ -33,33 +34,33 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "personType")
-public class PersonType {
+public class PersonType
+{
 
-    @XmlAttribute(name = "name", required = true)
-    protected String name;
+  @XmlAttribute(name = "name", required = true)
+  protected String name;
 
-    /**
-     * Gets the value of the name property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getName() {
-        return name;
-    }
+  /**
+   * Gets the value of the name property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getName()
+  {
+    return name;
+  }
 
-    /**
-     * Sets the value of the name property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setName(String value) {
-        this.name = value;
-    }
+  /**
+   * Sets the value of the name property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setName(String value)
+  {
+    this.name = value;
+  }
 
 }
index e674452..e8cea36 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,13 +15,15 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * Describes a physiological reaction.
  * 
- * <p>Java class for physiologicalReactionType complex type.
+ * <p>
+ * Java class for physiologicalReactionType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="physiologicalReactionType">
@@ -48,93 +49,94 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "physiologicalReactionType", propOrder = {
-    "dbReference"
-})
-public class PhysiologicalReactionType {
+@XmlType(name = "physiologicalReactionType", propOrder = { "dbReference" })
+public class PhysiologicalReactionType
+{
 
-    @XmlElement(required = true)
-    protected DbReferenceType dbReference;
-    @XmlAttribute(name = "direction", required = true)
-    protected String direction;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
+  @XmlElement(required = true)
+  protected DbReferenceType dbReference;
 
-    /**
-     * Gets the value of the dbReference property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DbReferenceType }
-     *     
-     */
-    public DbReferenceType getDbReference() {
-        return dbReference;
-    }
+  @XmlAttribute(name = "direction", required = true)
+  protected String direction;
 
-    /**
-     * Sets the value of the dbReference property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DbReferenceType }
-     *     
-     */
-    public void setDbReference(DbReferenceType value) {
-        this.dbReference = value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Gets the value of the direction property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getDirection() {
-        return direction;
-    }
+  /**
+   * Gets the value of the dbReference property.
+   * 
+   * @return possible object is {@link DbReferenceType }
+   * 
+   */
+  public DbReferenceType getDbReference()
+  {
+    return dbReference;
+  }
 
-    /**
-     * Sets the value of the direction property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setDirection(String value) {
-        this.direction = value;
-    }
+  /**
+   * Sets the value of the dbReference property.
+   * 
+   * @param value
+   *          allowed object is {@link DbReferenceType }
+   * 
+   */
+  public void setDbReference(DbReferenceType value)
+  {
+    this.dbReference = value;
+  }
+
+  /**
+   * Gets the value of the direction property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getDirection()
+  {
+    return direction;
+  }
+
+  /**
+   * Sets the value of the direction property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setDirection(String value)
+  {
+    this.direction = value;
+  }
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
 
 }
index a00d698..3383f53 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.math.BigInteger;
@@ -17,11 +16,13 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for positionType complex type.
+ * <p>
+ * Java class for positionType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="positionType">
@@ -49,95 +50,101 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "positionType")
-public class PositionType {
+public class PositionType
+{
 
-    @XmlAttribute(name = "position")
-    @XmlSchemaType(name = "unsignedLong")
-    protected BigInteger position;
-    @XmlAttribute(name = "status")
-    protected String status;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
+  @XmlAttribute(name = "position")
+  @XmlSchemaType(name = "unsignedLong")
+  protected BigInteger position;
 
-    /**
-     * Gets the value of the position property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
-     */
-    public BigInteger getPosition() {
-        return position;
-    }
+  @XmlAttribute(name = "status")
+  protected String status;
 
-    /**
-     * Sets the value of the position property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setPosition(BigInteger value) {
-        this.position = value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Gets the value of the status property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getStatus() {
-        if (status == null) {
-            return "certain";
-        } else {
-            return status;
-        }
-    }
+  /**
+   * Gets the value of the position property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getPosition()
+  {
+    return position;
+  }
+
+  /**
+   * Sets the value of the position property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setPosition(BigInteger value)
+  {
+    this.position = value;
+  }
 
-    /**
-     * Sets the value of the status property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setStatus(String value) {
-        this.status = value;
+  /**
+   * Gets the value of the status property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getStatus()
+  {
+    if (status == null)
+    {
+      return "certain";
     }
+    else
+    {
+      return status;
+    }
+  }
+
+  /**
+   * Sets the value of the status property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setStatus(String value)
+  {
+    this.status = value;
+  }
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
 
 }
index c9f169c..e651a3b 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,11 +12,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for propertyType complex type.
+ * <p>
+ * Java class for propertyType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="propertyType">
@@ -34,59 +35,59 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "propertyType")
-public class PropertyType {
+public class PropertyType
+{
+
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
-    @XmlAttribute(name = "value", required = true)
-    protected String value;
+  @XmlAttribute(name = "value", required = true)
+  protected String value;
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
 
 }
index c34a0f5..f3d61ee 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -13,14 +12,16 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes the evidence for the protein's existence.
- *             Equivalent to the flat file PE-line.
+ * Describes the evidence for the protein's existence. Equivalent to the flat
+ * file PE-line.
  * 
- * <p>Java class for proteinExistenceType complex type.
+ * <p>
+ * Java class for proteinExistenceType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="proteinExistenceType">
@@ -46,33 +47,33 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "proteinExistenceType")
-public class ProteinExistenceType {
+public class ProteinExistenceType
+{
 
-    @XmlAttribute(name = "type", required = true)
-    protected String type;
+  @XmlAttribute(name = "type", required = true)
+  protected String type;
 
-    /**
-     * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getType() {
-        return type;
-    }
+  /**
+   * Gets the value of the type property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getType()
+  {
+    return type;
+  }
 
-    /**
-     * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setType(String value) {
-        this.type = value;
-    }
+  /**
+   * Sets the value of the type property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setType(String value)
+  {
+    this.type = value;
+  }
 
 }
index 7b106fb..13fe5aa 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -15,14 +14,16 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes the names for the protein and parts thereof.
- *             Equivalent to the flat file DE-line.
+ * Describes the names for the protein and parts thereof. Equivalent to the flat
+ * file DE-line.
  * 
- * <p>Java class for proteinType complex type.
+ * <p>
+ * Java class for proteinType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="proteinType">
@@ -57,66 +58,497 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "proteinType", propOrder = {
-    "recommendedName",
-    "alternativeName",
-    "submittedName",
-    "allergenName",
-    "biotechName",
-    "cdAntigenName",
-    "innName",
-    "domain",
-    "component"
-})
-public class ProteinType {
+@XmlType(
+  name = "proteinType",
+  propOrder =
+  { "recommendedName", "alternativeName", "submittedName", "allergenName",
+      "biotechName", "cdAntigenName", "innName", "domain", "component" })
+public class ProteinType
+{
+
+  protected ProteinType.RecommendedName recommendedName;
+
+  protected List<ProteinType.AlternativeName> alternativeName;
+
+  protected List<ProteinType.SubmittedName> submittedName;
+
+  protected EvidencedStringType allergenName;
+
+  protected EvidencedStringType biotechName;
+
+  protected List<EvidencedStringType> cdAntigenName;
+
+  protected List<EvidencedStringType> innName;
+
+  protected List<ProteinType.Domain> domain;
+
+  protected List<ProteinType.Component> component;
+
+  /**
+   * Gets the value of the recommendedName property.
+   * 
+   * @return possible object is {@link ProteinType.RecommendedName }
+   * 
+   */
+  public ProteinType.RecommendedName getRecommendedName()
+  {
+    return recommendedName;
+  }
+
+  /**
+   * Sets the value of the recommendedName property.
+   * 
+   * @param value
+   *          allowed object is {@link ProteinType.RecommendedName }
+   * 
+   */
+  public void setRecommendedName(ProteinType.RecommendedName value)
+  {
+    this.recommendedName = value;
+  }
+
+  /**
+   * Gets the value of the alternativeName property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the alternativeName property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getAlternativeName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link ProteinType.AlternativeName }
+   * 
+   * 
+   */
+  public List<ProteinType.AlternativeName> getAlternativeName()
+  {
+    if (alternativeName == null)
+    {
+      alternativeName = new ArrayList<ProteinType.AlternativeName>();
+    }
+    return this.alternativeName;
+  }
+
+  /**
+   * Gets the value of the submittedName property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the submittedName property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getSubmittedName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link ProteinType.SubmittedName }
+   * 
+   * 
+   */
+  public List<ProteinType.SubmittedName> getSubmittedName()
+  {
+    if (submittedName == null)
+    {
+      submittedName = new ArrayList<ProteinType.SubmittedName>();
+    }
+    return this.submittedName;
+  }
+
+  /**
+   * Gets the value of the allergenName property.
+   * 
+   * @return possible object is {@link EvidencedStringType }
+   * 
+   */
+  public EvidencedStringType getAllergenName()
+  {
+    return allergenName;
+  }
+
+  /**
+   * Sets the value of the allergenName property.
+   * 
+   * @param value
+   *          allowed object is {@link EvidencedStringType }
+   * 
+   */
+  public void setAllergenName(EvidencedStringType value)
+  {
+    this.allergenName = value;
+  }
+
+  /**
+   * Gets the value of the biotechName property.
+   * 
+   * @return possible object is {@link EvidencedStringType }
+   * 
+   */
+  public EvidencedStringType getBiotechName()
+  {
+    return biotechName;
+  }
+
+  /**
+   * Sets the value of the biotechName property.
+   * 
+   * @param value
+   *          allowed object is {@link EvidencedStringType }
+   * 
+   */
+  public void setBiotechName(EvidencedStringType value)
+  {
+    this.biotechName = value;
+  }
+
+  /**
+   * Gets the value of the cdAntigenName property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the cdAntigenName property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getCdAntigenName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EvidencedStringType }
+   * 
+   * 
+   */
+  public List<EvidencedStringType> getCdAntigenName()
+  {
+    if (cdAntigenName == null)
+    {
+      cdAntigenName = new ArrayList<EvidencedStringType>();
+    }
+    return this.cdAntigenName;
+  }
+
+  /**
+   * Gets the value of the innName property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the innName property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getInnName().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EvidencedStringType }
+   * 
+   * 
+   */
+  public List<EvidencedStringType> getInnName()
+  {
+    if (innName == null)
+    {
+      innName = new ArrayList<EvidencedStringType>();
+    }
+    return this.innName;
+  }
+
+  /**
+   * Gets the value of the domain property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the domain property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getDomain().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link ProteinType.Domain }
+   * 
+   * 
+   */
+  public List<ProteinType.Domain> getDomain()
+  {
+    if (domain == null)
+    {
+      domain = new ArrayList<ProteinType.Domain>();
+    }
+    return this.domain;
+  }
+
+  /**
+   * Gets the value of the component property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the component property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getComponent().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link ProteinType.Component }
+   * 
+   * 
+   */
+  public List<ProteinType.Component> getComponent()
+  {
+    if (component == null)
+    {
+      component = new ArrayList<ProteinType.Component>();
+    }
+    return this.component;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="fullName" type="{http://uniprot.org/uniprot}evidencedStringType" minOccurs="0"/>
+   *         &lt;element name="shortName" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="ecNumber" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "fullName", "shortName", "ecNumber" })
+  public static class AlternativeName
+  {
+
+    protected EvidencedStringType fullName;
+
+    protected List<EvidencedStringType> shortName;
+
+    protected List<EvidencedStringType> ecNumber;
+
+    /**
+     * Gets the value of the fullName property.
+     * 
+     * @return possible object is {@link EvidencedStringType }
+     * 
+     */
+    public EvidencedStringType getFullName()
+    {
+      return fullName;
+    }
+
+    /**
+     * Sets the value of the fullName property.
+     * 
+     * @param value
+     *          allowed object is {@link EvidencedStringType }
+     * 
+     */
+    public void setFullName(EvidencedStringType value)
+    {
+      this.fullName = value;
+    }
+
+    /**
+     * Gets the value of the shortName property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the shortName property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getShortName().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
+     */
+    public List<EvidencedStringType> getShortName()
+    {
+      if (shortName == null)
+      {
+        shortName = new ArrayList<EvidencedStringType>();
+      }
+      return this.shortName;
+    }
+
+    /**
+     * Gets the value of the ecNumber property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the ecNumber property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getEcNumber().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
+     */
+    public List<EvidencedStringType> getEcNumber()
+    {
+      if (ecNumber == null)
+      {
+        ecNumber = new ArrayList<EvidencedStringType>();
+      }
+      return this.ecNumber;
+    }
+
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;group ref="{http://uniprot.org/uniprot}proteinNameGroup"/>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(
+    name = "",
+    propOrder =
+    { "recommendedName", "alternativeName", "submittedName", "allergenName",
+        "biotechName", "cdAntigenName", "innName" })
+  public static class Component
+  {
 
     protected ProteinType.RecommendedName recommendedName;
+
     protected List<ProteinType.AlternativeName> alternativeName;
+
     protected List<ProteinType.SubmittedName> submittedName;
+
     protected EvidencedStringType allergenName;
+
     protected EvidencedStringType biotechName;
+
     protected List<EvidencedStringType> cdAntigenName;
+
     protected List<EvidencedStringType> innName;
-    protected List<ProteinType.Domain> domain;
-    protected List<ProteinType.Component> component;
 
     /**
      * Gets the value of the recommendedName property.
      * 
-     * @return
-     *     possible object is
-     *     {@link ProteinType.RecommendedName }
-     *     
+     * @return possible object is {@link ProteinType.RecommendedName }
+     * 
      */
-    public ProteinType.RecommendedName getRecommendedName() {
-        return recommendedName;
+    public ProteinType.RecommendedName getRecommendedName()
+    {
+      return recommendedName;
     }
 
     /**
      * Sets the value of the recommendedName property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link ProteinType.RecommendedName }
-     *     
+     *          allowed object is {@link ProteinType.RecommendedName }
+     * 
      */
-    public void setRecommendedName(ProteinType.RecommendedName value) {
-        this.recommendedName = value;
+    public void setRecommendedName(ProteinType.RecommendedName value)
+    {
+      this.recommendedName = value;
     }
 
     /**
      * Gets the value of the alternativeName property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the alternativeName property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the alternativeName property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getAlternativeName().add(newItem);
+     * getAlternativeName().add(newItem);
      * </pre>
      * 
      * 
@@ -126,26 +558,29 @@ public class ProteinType {
      * 
      * 
      */
-    public List<ProteinType.AlternativeName> getAlternativeName() {
-        if (alternativeName == null) {
-            alternativeName = new ArrayList<ProteinType.AlternativeName>();
-        }
-        return this.alternativeName;
+    public List<ProteinType.AlternativeName> getAlternativeName()
+    {
+      if (alternativeName == null)
+      {
+        alternativeName = new ArrayList<ProteinType.AlternativeName>();
+      }
+      return this.alternativeName;
     }
 
     /**
      * Gets the value of the submittedName property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the submittedName property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the submittedName property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getSubmittedName().add(newItem);
+     * getSubmittedName().add(newItem);
      * </pre>
      * 
      * 
@@ -155,74 +590,75 @@ public class ProteinType {
      * 
      * 
      */
-    public List<ProteinType.SubmittedName> getSubmittedName() {
-        if (submittedName == null) {
-            submittedName = new ArrayList<ProteinType.SubmittedName>();
-        }
-        return this.submittedName;
+    public List<ProteinType.SubmittedName> getSubmittedName()
+    {
+      if (submittedName == null)
+      {
+        submittedName = new ArrayList<ProteinType.SubmittedName>();
+      }
+      return this.submittedName;
     }
 
     /**
      * Gets the value of the allergenName property.
      * 
-     * @return
-     *     possible object is
-     *     {@link EvidencedStringType }
-     *     
+     * @return possible object is {@link EvidencedStringType }
+     * 
      */
-    public EvidencedStringType getAllergenName() {
-        return allergenName;
+    public EvidencedStringType getAllergenName()
+    {
+      return allergenName;
     }
 
     /**
      * Sets the value of the allergenName property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link EvidencedStringType }
-     *     
+     *          allowed object is {@link EvidencedStringType }
+     * 
      */
-    public void setAllergenName(EvidencedStringType value) {
-        this.allergenName = value;
+    public void setAllergenName(EvidencedStringType value)
+    {
+      this.allergenName = value;
     }
 
     /**
      * Gets the value of the biotechName property.
      * 
-     * @return
-     *     possible object is
-     *     {@link EvidencedStringType }
-     *     
+     * @return possible object is {@link EvidencedStringType }
+     * 
      */
-    public EvidencedStringType getBiotechName() {
-        return biotechName;
+    public EvidencedStringType getBiotechName()
+    {
+      return biotechName;
     }
 
     /**
      * Sets the value of the biotechName property.
      * 
      * @param value
-     *     allowed object is
-     *     {@link EvidencedStringType }
-     *     
+     *          allowed object is {@link EvidencedStringType }
+     * 
      */
-    public void setBiotechName(EvidencedStringType value) {
-        this.biotechName = value;
+    public void setBiotechName(EvidencedStringType value)
+    {
+      this.biotechName = value;
     }
 
     /**
      * Gets the value of the cdAntigenName property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the cdAntigenName property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the cdAntigenName property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getCdAntigenName().add(newItem);
+     * getCdAntigenName().add(newItem);
      * </pre>
      * 
      * 
@@ -232,26 +668,29 @@ public class ProteinType {
      * 
      * 
      */
-    public List<EvidencedStringType> getCdAntigenName() {
-        if (cdAntigenName == null) {
-            cdAntigenName = new ArrayList<EvidencedStringType>();
-        }
-        return this.cdAntigenName;
+    public List<EvidencedStringType> getCdAntigenName()
+    {
+      if (cdAntigenName == null)
+      {
+        cdAntigenName = new ArrayList<EvidencedStringType>();
+      }
+      return this.cdAntigenName;
     }
 
     /**
      * Gets the value of the innName property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the innName property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the innName property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getInnName().add(newItem);
+     * getInnName().add(newItem);
      * </pre>
      * 
      * 
@@ -261,849 +700,472 @@ public class ProteinType {
      * 
      * 
      */
-    public List<EvidencedStringType> getInnName() {
-        if (innName == null) {
-            innName = new ArrayList<EvidencedStringType>();
-        }
-        return this.innName;
+    public List<EvidencedStringType> getInnName()
+    {
+      if (innName == null)
+      {
+        innName = new ArrayList<EvidencedStringType>();
+      }
+      return this.innName;
+    }
+
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;group ref="{http://uniprot.org/uniprot}proteinNameGroup"/>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(
+    name = "",
+    propOrder =
+    { "recommendedName", "alternativeName", "submittedName", "allergenName",
+        "biotechName", "cdAntigenName", "innName" })
+  public static class Domain
+  {
+
+    protected ProteinType.RecommendedName recommendedName;
+
+    protected List<ProteinType.AlternativeName> alternativeName;
+
+    protected List<ProteinType.SubmittedName> submittedName;
+
+    protected EvidencedStringType allergenName;
+
+    protected EvidencedStringType biotechName;
+
+    protected List<EvidencedStringType> cdAntigenName;
+
+    protected List<EvidencedStringType> innName;
+
+    /**
+     * Gets the value of the recommendedName property.
+     * 
+     * @return possible object is {@link ProteinType.RecommendedName }
+     * 
+     */
+    public ProteinType.RecommendedName getRecommendedName()
+    {
+      return recommendedName;
     }
 
     /**
-     * Gets the value of the domain property.
+     * Sets the value of the recommendedName property.
+     * 
+     * @param value
+     *          allowed object is {@link ProteinType.RecommendedName }
+     * 
+     */
+    public void setRecommendedName(ProteinType.RecommendedName value)
+    {
+      this.recommendedName = value;
+    }
+
+    /**
+     * Gets the value of the alternativeName property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the domain property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the alternativeName property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getDomain().add(newItem);
+     * getAlternativeName().add(newItem);
      * </pre>
      * 
      * 
      * <p>
      * Objects of the following type(s) are allowed in the list
-     * {@link ProteinType.Domain }
+     * {@link ProteinType.AlternativeName }
      * 
      * 
      */
-    public List<ProteinType.Domain> getDomain() {
-        if (domain == null) {
-            domain = new ArrayList<ProteinType.Domain>();
-        }
-        return this.domain;
+    public List<ProteinType.AlternativeName> getAlternativeName()
+    {
+      if (alternativeName == null)
+      {
+        alternativeName = new ArrayList<ProteinType.AlternativeName>();
+      }
+      return this.alternativeName;
     }
 
     /**
-     * Gets the value of the component property.
+     * Gets the value of the submittedName property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the component property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the submittedName property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getComponent().add(newItem);
+     * getSubmittedName().add(newItem);
      * </pre>
      * 
      * 
      * <p>
      * Objects of the following type(s) are allowed in the list
-     * {@link ProteinType.Component }
+     * {@link ProteinType.SubmittedName }
      * 
      * 
      */
-    public List<ProteinType.Component> getComponent() {
-        if (component == null) {
-            component = new ArrayList<ProteinType.Component>();
-        }
-        return this.component;
+    public List<ProteinType.SubmittedName> getSubmittedName()
+    {
+      if (submittedName == null)
+      {
+        submittedName = new ArrayList<ProteinType.SubmittedName>();
+      }
+      return this.submittedName;
     }
 
+    /**
+     * Gets the value of the allergenName property.
+     * 
+     * @return possible object is {@link EvidencedStringType }
+     * 
+     */
+    public EvidencedStringType getAllergenName()
+    {
+      return allergenName;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Sets the value of the allergenName property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @param value
+     *          allowed object is {@link EvidencedStringType }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="fullName" type="{http://uniprot.org/uniprot}evidencedStringType" minOccurs="0"/>
-     *         &lt;element name="shortName" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="ecNumber" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public void setAllergenName(EvidencedStringType value)
+    {
+      this.allergenName = value;
+    }
+
+    /**
+     * Gets the value of the biotechName property.
      * 
+     * @return possible object is {@link EvidencedStringType }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "fullName",
-        "shortName",
-        "ecNumber"
-    })
-    public static class AlternativeName {
-
-        protected EvidencedStringType fullName;
-        protected List<EvidencedStringType> shortName;
-        protected List<EvidencedStringType> ecNumber;
-
-        /**
-         * Gets the value of the fullName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public EvidencedStringType getFullName() {
-            return fullName;
-        }
-
-        /**
-         * Sets the value of the fullName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public void setFullName(EvidencedStringType value) {
-            this.fullName = value;
-        }
-
-        /**
-         * Gets the value of the shortName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the shortName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getShortName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getShortName() {
-            if (shortName == null) {
-                shortName = new ArrayList<EvidencedStringType>();
-            }
-            return this.shortName;
-        }
-
-        /**
-         * Gets the value of the ecNumber property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the ecNumber property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getEcNumber().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getEcNumber() {
-            if (ecNumber == null) {
-                ecNumber = new ArrayList<EvidencedStringType>();
-            }
-            return this.ecNumber;
-        }
+    public EvidencedStringType getBiotechName()
+    {
+      return biotechName;
+    }
 
+    /**
+     * Sets the value of the biotechName property.
+     * 
+     * @param value
+     *          allowed object is {@link EvidencedStringType }
+     * 
+     */
+    public void setBiotechName(EvidencedStringType value)
+    {
+      this.biotechName = value;
     }
 
+    /**
+     * Gets the value of the cdAntigenName property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the cdAntigenName property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * 
+     * <pre>
+     * getCdAntigenName().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
+     */
+    public List<EvidencedStringType> getCdAntigenName()
+    {
+      if (cdAntigenName == null)
+      {
+        cdAntigenName = new ArrayList<EvidencedStringType>();
+      }
+      return this.cdAntigenName;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the innName property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the innName property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;group ref="{http://uniprot.org/uniprot}proteinNameGroup"/>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getInnName().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "recommendedName",
-        "alternativeName",
-        "submittedName",
-        "allergenName",
-        "biotechName",
-        "cdAntigenName",
-        "innName"
-    })
-    public static class Component {
-
-        protected ProteinType.RecommendedName recommendedName;
-        protected List<ProteinType.AlternativeName> alternativeName;
-        protected List<ProteinType.SubmittedName> submittedName;
-        protected EvidencedStringType allergenName;
-        protected EvidencedStringType biotechName;
-        protected List<EvidencedStringType> cdAntigenName;
-        protected List<EvidencedStringType> innName;
-
-        /**
-         * Gets the value of the recommendedName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link ProteinType.RecommendedName }
-         *     
-         */
-        public ProteinType.RecommendedName getRecommendedName() {
-            return recommendedName;
-        }
-
-        /**
-         * Sets the value of the recommendedName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link ProteinType.RecommendedName }
-         *     
-         */
-        public void setRecommendedName(ProteinType.RecommendedName value) {
-            this.recommendedName = value;
-        }
-
-        /**
-         * Gets the value of the alternativeName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the alternativeName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getAlternativeName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link ProteinType.AlternativeName }
-         * 
-         * 
-         */
-        public List<ProteinType.AlternativeName> getAlternativeName() {
-            if (alternativeName == null) {
-                alternativeName = new ArrayList<ProteinType.AlternativeName>();
-            }
-            return this.alternativeName;
-        }
-
-        /**
-         * Gets the value of the submittedName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the submittedName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getSubmittedName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link ProteinType.SubmittedName }
-         * 
-         * 
-         */
-        public List<ProteinType.SubmittedName> getSubmittedName() {
-            if (submittedName == null) {
-                submittedName = new ArrayList<ProteinType.SubmittedName>();
-            }
-            return this.submittedName;
-        }
-
-        /**
-         * Gets the value of the allergenName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public EvidencedStringType getAllergenName() {
-            return allergenName;
-        }
-
-        /**
-         * Sets the value of the allergenName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public void setAllergenName(EvidencedStringType value) {
-            this.allergenName = value;
-        }
-
-        /**
-         * Gets the value of the biotechName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public EvidencedStringType getBiotechName() {
-            return biotechName;
-        }
-
-        /**
-         * Sets the value of the biotechName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public void setBiotechName(EvidencedStringType value) {
-            this.biotechName = value;
-        }
-
-        /**
-         * Gets the value of the cdAntigenName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the cdAntigenName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getCdAntigenName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getCdAntigenName() {
-            if (cdAntigenName == null) {
-                cdAntigenName = new ArrayList<EvidencedStringType>();
-            }
-            return this.cdAntigenName;
-        }
-
-        /**
-         * Gets the value of the innName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the innName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getInnName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getInnName() {
-            if (innName == null) {
-                innName = new ArrayList<EvidencedStringType>();
-            }
-            return this.innName;
-        }
+    public List<EvidencedStringType> getInnName()
+    {
+      if (innName == null)
+      {
+        innName = new ArrayList<EvidencedStringType>();
+      }
+      return this.innName;
+    }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="fullName" type="{http://uniprot.org/uniprot}evidencedStringType"/>
+   *         &lt;element name="shortName" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *         &lt;element name="ecNumber" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "fullName", "shortName", "ecNumber" })
+  public static class RecommendedName
+  {
+
+    @XmlElement(required = true)
+    protected EvidencedStringType fullName;
+
+    protected List<EvidencedStringType> shortName;
+
+    protected List<EvidencedStringType> ecNumber;
+
+    /**
+     * Gets the value of the fullName property.
+     * 
+     * @return possible object is {@link EvidencedStringType }
+     * 
+     */
+    public EvidencedStringType getFullName()
+    {
+      return fullName;
     }
 
+    /**
+     * Sets the value of the fullName property.
+     * 
+     * @param value
+     *          allowed object is {@link EvidencedStringType }
+     * 
+     */
+    public void setFullName(EvidencedStringType value)
+    {
+      this.fullName = value;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the shortName property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the shortName property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;group ref="{http://uniprot.org/uniprot}proteinNameGroup"/>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getShortName().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "recommendedName",
-        "alternativeName",
-        "submittedName",
-        "allergenName",
-        "biotechName",
-        "cdAntigenName",
-        "innName"
-    })
-    public static class Domain {
-
-        protected ProteinType.RecommendedName recommendedName;
-        protected List<ProteinType.AlternativeName> alternativeName;
-        protected List<ProteinType.SubmittedName> submittedName;
-        protected EvidencedStringType allergenName;
-        protected EvidencedStringType biotechName;
-        protected List<EvidencedStringType> cdAntigenName;
-        protected List<EvidencedStringType> innName;
-
-        /**
-         * Gets the value of the recommendedName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link ProteinType.RecommendedName }
-         *     
-         */
-        public ProteinType.RecommendedName getRecommendedName() {
-            return recommendedName;
-        }
-
-        /**
-         * Sets the value of the recommendedName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link ProteinType.RecommendedName }
-         *     
-         */
-        public void setRecommendedName(ProteinType.RecommendedName value) {
-            this.recommendedName = value;
-        }
-
-        /**
-         * Gets the value of the alternativeName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the alternativeName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getAlternativeName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link ProteinType.AlternativeName }
-         * 
-         * 
-         */
-        public List<ProteinType.AlternativeName> getAlternativeName() {
-            if (alternativeName == null) {
-                alternativeName = new ArrayList<ProteinType.AlternativeName>();
-            }
-            return this.alternativeName;
-        }
-
-        /**
-         * Gets the value of the submittedName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the submittedName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getSubmittedName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link ProteinType.SubmittedName }
-         * 
-         * 
-         */
-        public List<ProteinType.SubmittedName> getSubmittedName() {
-            if (submittedName == null) {
-                submittedName = new ArrayList<ProteinType.SubmittedName>();
-            }
-            return this.submittedName;
-        }
-
-        /**
-         * Gets the value of the allergenName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public EvidencedStringType getAllergenName() {
-            return allergenName;
-        }
-
-        /**
-         * Sets the value of the allergenName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public void setAllergenName(EvidencedStringType value) {
-            this.allergenName = value;
-        }
-
-        /**
-         * Gets the value of the biotechName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public EvidencedStringType getBiotechName() {
-            return biotechName;
-        }
-
-        /**
-         * Sets the value of the biotechName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public void setBiotechName(EvidencedStringType value) {
-            this.biotechName = value;
-        }
-
-        /**
-         * Gets the value of the cdAntigenName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the cdAntigenName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getCdAntigenName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getCdAntigenName() {
-            if (cdAntigenName == null) {
-                cdAntigenName = new ArrayList<EvidencedStringType>();
-            }
-            return this.cdAntigenName;
-        }
-
-        /**
-         * Gets the value of the innName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the innName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getInnName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getInnName() {
-            if (innName == null) {
-                innName = new ArrayList<EvidencedStringType>();
-            }
-            return this.innName;
-        }
-
+    public List<EvidencedStringType> getShortName()
+    {
+      if (shortName == null)
+      {
+        shortName = new ArrayList<EvidencedStringType>();
+      }
+      return this.shortName;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the ecNumber property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the ecNumber property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="fullName" type="{http://uniprot.org/uniprot}evidencedStringType"/>
-     *         &lt;element name="shortName" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *         &lt;element name="ecNumber" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getEcNumber().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "fullName",
-        "shortName",
-        "ecNumber"
-    })
-    public static class RecommendedName {
-
-        @XmlElement(required = true)
-        protected EvidencedStringType fullName;
-        protected List<EvidencedStringType> shortName;
-        protected List<EvidencedStringType> ecNumber;
-
-        /**
-         * Gets the value of the fullName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public EvidencedStringType getFullName() {
-            return fullName;
-        }
-
-        /**
-         * Sets the value of the fullName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public void setFullName(EvidencedStringType value) {
-            this.fullName = value;
-        }
-
-        /**
-         * Gets the value of the shortName property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the shortName property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getShortName().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getShortName() {
-            if (shortName == null) {
-                shortName = new ArrayList<EvidencedStringType>();
-            }
-            return this.shortName;
-        }
-
-        /**
-         * Gets the value of the ecNumber property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the ecNumber property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getEcNumber().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getEcNumber() {
-            if (ecNumber == null) {
-                ecNumber = new ArrayList<EvidencedStringType>();
-            }
-            return this.ecNumber;
-        }
+    public List<EvidencedStringType> getEcNumber()
+    {
+      if (ecNumber == null)
+      {
+        ecNumber = new ArrayList<EvidencedStringType>();
+      }
+      return this.ecNumber;
+    }
+
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;complexContent>
+   *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+   *       &lt;sequence>
+   *         &lt;element name="fullName" type="{http://uniprot.org/uniprot}evidencedStringType"/>
+   *         &lt;element name="ecNumber" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
+   *       &lt;/sequence>
+   *     &lt;/restriction>
+   *   &lt;/complexContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "fullName", "ecNumber" })
+  public static class SubmittedName
+  {
+
+    @XmlElement(required = true)
+    protected EvidencedStringType fullName;
+
+    protected List<EvidencedStringType> ecNumber;
 
+    /**
+     * Gets the value of the fullName property.
+     * 
+     * @return possible object is {@link EvidencedStringType }
+     * 
+     */
+    public EvidencedStringType getFullName()
+    {
+      return fullName;
     }
 
+    /**
+     * Sets the value of the fullName property.
+     * 
+     * @param value
+     *          allowed object is {@link EvidencedStringType }
+     * 
+     */
+    public void setFullName(EvidencedStringType value)
+    {
+      this.fullName = value;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the ecNumber property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the ecNumber property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;complexContent>
-     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-     *       &lt;sequence>
-     *         &lt;element name="fullName" type="{http://uniprot.org/uniprot}evidencedStringType"/>
-     *         &lt;element name="ecNumber" type="{http://uniprot.org/uniprot}evidencedStringType" maxOccurs="unbounded" minOccurs="0"/>
-     *       &lt;/sequence>
-     *     &lt;/restriction>
-     *   &lt;/complexContent>
-     * &lt;/complexType>
+     * getEcNumber().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link EvidencedStringType }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "fullName",
-        "ecNumber"
-    })
-    public static class SubmittedName {
-
-        @XmlElement(required = true)
-        protected EvidencedStringType fullName;
-        protected List<EvidencedStringType> ecNumber;
-
-        /**
-         * Gets the value of the fullName property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public EvidencedStringType getFullName() {
-            return fullName;
-        }
-
-        /**
-         * Sets the value of the fullName property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link EvidencedStringType }
-         *     
-         */
-        public void setFullName(EvidencedStringType value) {
-            this.fullName = value;
-        }
-
-        /**
-         * Gets the value of the ecNumber property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the ecNumber property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getEcNumber().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link EvidencedStringType }
-         * 
-         * 
-         */
-        public List<EvidencedStringType> getEcNumber() {
-            if (ecNumber == null) {
-                ecNumber = new ArrayList<EvidencedStringType>();
-            }
-            return this.ecNumber;
-        }
-
+    public List<EvidencedStringType> getEcNumber()
+    {
+      if (ecNumber == null)
+      {
+        ecNumber = new ArrayList<EvidencedStringType>();
+      }
+      return this.ecNumber;
     }
 
+  }
+
 }
index 8d9d51d..9fbb9da 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,13 +15,15 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
  * Describes a chemical reaction.
  * 
- * <p>Java class for reactionType complex type.
+ * <p>
+ * Java class for reactionType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="reactionType">
@@ -41,99 +42,103 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "reactionType", propOrder = {
-    "text",
-    "dbReference"
-})
-public class ReactionType {
+@XmlType(name = "reactionType", propOrder = { "text", "dbReference" })
+public class ReactionType
+{
 
-    @XmlElement(required = true)
-    protected String text;
-    @XmlElement(required = true)
-    protected List<DbReferenceType> dbReference;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
+  @XmlElement(required = true)
+  protected String text;
 
-    /**
-     * Gets the value of the text property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getText() {
-        return text;
-    }
+  @XmlElement(required = true)
+  protected List<DbReferenceType> dbReference;
 
-    /**
-     * Sets the value of the text property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setText(String value) {
-        this.text = value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
+
+  /**
+   * Gets the value of the text property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getText()
+  {
+    return text;
+  }
+
+  /**
+   * Sets the value of the text property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setText(String value)
+  {
+    this.text = value;
+  }
 
-    /**
-     * Gets the value of the dbReference property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the dbReference property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getDbReference().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link DbReferenceType }
-     * 
-     * 
-     */
-    public List<DbReferenceType> getDbReference() {
-        if (dbReference == null) {
-            dbReference = new ArrayList<DbReferenceType>();
-        }
-        return this.dbReference;
+  /**
+   * Gets the value of the dbReference property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the dbReference property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getDbReference().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link DbReferenceType }
+   * 
+   * 
+   */
+  public List<DbReferenceType> getDbReference()
+  {
+    if (dbReference == null)
+    {
+      dbReference = new ArrayList<DbReferenceType>();
     }
+    return this.dbReference;
+  }
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
 
 }
index e5f9fde..d1562a1 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,14 +15,16 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes a citation and a summary of its content.
- *             Equivalent to the flat file RN-, RP-, RC-, RX-, RG-, RA-, RT- and RL-lines.
+ * Describes a citation and a summary of its content. Equivalent to the flat
+ * file RN-, RP-, RC-, RX-, RG-, RA-, RT- and RL-lines.
  * 
- * <p>Java class for referenceType complex type.
+ * <p>
+ * Java class for referenceType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="referenceType">
@@ -43,151 +44,156 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "referenceType", propOrder = {
-    "citation",
-    "scope",
-    "source"
-})
-public class ReferenceType {
-
-    @XmlElement(required = true)
-    protected CitationType citation;
-    @XmlElement(required = true)
-    protected List<String> scope;
-    protected SourceDataType source;
-    @XmlAttribute(name = "evidence")
-    protected List<Integer> evidence;
-    @XmlAttribute(name = "key", required = true)
-    protected String key;
-
-    /**
-     * Gets the value of the citation property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link CitationType }
-     *     
-     */
-    public CitationType getCitation() {
-        return citation;
-    }
+@XmlType(
+  name = "referenceType",
+  propOrder =
+  { "citation", "scope", "source" })
+public class ReferenceType
+{
 
-    /**
-     * Sets the value of the citation property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link CitationType }
-     *     
-     */
-    public void setCitation(CitationType value) {
-        this.citation = value;
-    }
+  @XmlElement(required = true)
+  protected CitationType citation;
 
-    /**
-     * Gets the value of the scope property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the scope property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getScope().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link String }
-     * 
-     * 
-     */
-    public List<String> getScope() {
-        if (scope == null) {
-            scope = new ArrayList<String>();
-        }
-        return this.scope;
-    }
+  @XmlElement(required = true)
+  protected List<String> scope;
 
-    /**
-     * Gets the value of the source property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link SourceDataType }
-     *     
-     */
-    public SourceDataType getSource() {
-        return source;
-    }
+  protected SourceDataType source;
 
-    /**
-     * Sets the value of the source property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link SourceDataType }
-     *     
-     */
-    public void setSource(SourceDataType value) {
-        this.source = value;
-    }
+  @XmlAttribute(name = "evidence")
+  protected List<Integer> evidence;
 
-    /**
-     * Gets the value of the evidence property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the evidence property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEvidence().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Integer }
-     * 
-     * 
-     */
-    public List<Integer> getEvidence() {
-        if (evidence == null) {
-            evidence = new ArrayList<Integer>();
-        }
-        return this.evidence;
-    }
+  @XmlAttribute(name = "key", required = true)
+  protected String key;
+
+  /**
+   * Gets the value of the citation property.
+   * 
+   * @return possible object is {@link CitationType }
+   * 
+   */
+  public CitationType getCitation()
+  {
+    return citation;
+  }
 
-    /**
-     * Gets the value of the key property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getKey() {
-        return key;
+  /**
+   * Sets the value of the citation property.
+   * 
+   * @param value
+   *          allowed object is {@link CitationType }
+   * 
+   */
+  public void setCitation(CitationType value)
+  {
+    this.citation = value;
+  }
+
+  /**
+   * Gets the value of the scope property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the scope property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getScope().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link String }
+   * 
+   * 
+   */
+  public List<String> getScope()
+  {
+    if (scope == null)
+    {
+      scope = new ArrayList<String>();
     }
+    return this.scope;
+  }
+
+  /**
+   * Gets the value of the source property.
+   * 
+   * @return possible object is {@link SourceDataType }
+   * 
+   */
+  public SourceDataType getSource()
+  {
+    return source;
+  }
 
-    /**
-     * Sets the value of the key property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setKey(String value) {
-        this.key = value;
+  /**
+   * Sets the value of the source property.
+   * 
+   * @param value
+   *          allowed object is {@link SourceDataType }
+   * 
+   */
+  public void setSource(SourceDataType value)
+  {
+    this.source = value;
+  }
+
+  /**
+   * Gets the value of the evidence property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the evidence property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEvidence().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Integer }
+   * 
+   * 
+   */
+  public List<Integer> getEvidence()
+  {
+    if (evidence == null)
+    {
+      evidence = new ArrayList<Integer>();
     }
+    return this.evidence;
+  }
+
+  /**
+   * Gets the value of the key property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getKey()
+  {
+    return key;
+  }
+
+  /**
+   * Sets the value of the key property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setKey(String value)
+  {
+    this.key = value;
+  }
 
 }
index 49cd130..f9b4daa 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 import javax.xml.datatype.XMLGregorianCalendar;
 
-
 /**
- * <p>Java class for sequenceType complex type.
+ * <p>
+ * Java class for sequenceType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="sequenceType">
@@ -48,195 +49,202 @@ import javax.xml.datatype.XMLGregorianCalendar;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "sequenceType", propOrder = {
-    "value"
-})
-public class SequenceType {
-
-    @XmlValue
-    protected String value;
-    @XmlAttribute(name = "length", required = true)
-    protected int length;
-    @XmlAttribute(name = "mass", required = true)
-    protected int mass;
-    @XmlAttribute(name = "checksum", required = true)
-    protected String checksum;
-    @XmlAttribute(name = "modified", required = true)
-    @XmlSchemaType(name = "date")
-    protected XMLGregorianCalendar modified;
-    @XmlAttribute(name = "version", required = true)
-    protected int version;
-    @XmlAttribute(name = "precursor")
-    protected Boolean precursor;
-    @XmlAttribute(name = "fragment")
-    protected String fragment;
-
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
-
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-    /**
-     * Gets the value of the length property.
-     * 
-     */
-    public int getLength() {
-        return length;
-    }
-
-    /**
-     * Sets the value of the length property.
-     * 
-     */
-    public void setLength(int value) {
-        this.length = value;
-    }
-
-    /**
-     * Gets the value of the mass property.
-     * 
-     */
-    public int getMass() {
-        return mass;
-    }
-
-    /**
-     * Sets the value of the mass property.
-     * 
-     */
-    public void setMass(int value) {
-        this.mass = value;
-    }
-
-    /**
-     * Gets the value of the checksum property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getChecksum() {
-        return checksum;
-    }
-
-    /**
-     * Sets the value of the checksum property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setChecksum(String value) {
-        this.checksum = value;
-    }
-
-    /**
-     * Gets the value of the modified property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public XMLGregorianCalendar getModified() {
-        return modified;
-    }
-
-    /**
-     * Sets the value of the modified property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link XMLGregorianCalendar }
-     *     
-     */
-    public void setModified(XMLGregorianCalendar value) {
-        this.modified = value;
-    }
-
-    /**
-     * Gets the value of the version property.
-     * 
-     */
-    public int getVersion() {
-        return version;
-    }
-
-    /**
-     * Sets the value of the version property.
-     * 
-     */
-    public void setVersion(int value) {
-        this.version = value;
-    }
-
-    /**
-     * Gets the value of the precursor property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Boolean }
-     *     
-     */
-    public Boolean isPrecursor() {
-        return precursor;
-    }
-
-    /**
-     * Sets the value of the precursor property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Boolean }
-     *     
-     */
-    public void setPrecursor(Boolean value) {
-        this.precursor = value;
-    }
-
-    /**
-     * Gets the value of the fragment property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getFragment() {
-        return fragment;
-    }
-
-    /**
-     * Sets the value of the fragment property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setFragment(String value) {
-        this.fragment = value;
-    }
+@XmlType(name = "sequenceType", propOrder = { "value" })
+public class SequenceType
+{
+
+  @XmlValue
+  protected String value;
+
+  @XmlAttribute(name = "length", required = true)
+  protected int length;
+
+  @XmlAttribute(name = "mass", required = true)
+  protected int mass;
+
+  @XmlAttribute(name = "checksum", required = true)
+  protected String checksum;
+
+  @XmlAttribute(name = "modified", required = true)
+  @XmlSchemaType(name = "date")
+  protected XMLGregorianCalendar modified;
+
+  @XmlAttribute(name = "version", required = true)
+  protected int version;
+
+  @XmlAttribute(name = "precursor")
+  protected Boolean precursor;
+
+  @XmlAttribute(name = "fragment")
+  protected String fragment;
+
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
+
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
+
+  /**
+   * Gets the value of the length property.
+   * 
+   */
+  public int getLength()
+  {
+    return length;
+  }
+
+  /**
+   * Sets the value of the length property.
+   * 
+   */
+  public void setLength(int value)
+  {
+    this.length = value;
+  }
+
+  /**
+   * Gets the value of the mass property.
+   * 
+   */
+  public int getMass()
+  {
+    return mass;
+  }
+
+  /**
+   * Sets the value of the mass property.
+   * 
+   */
+  public void setMass(int value)
+  {
+    this.mass = value;
+  }
+
+  /**
+   * Gets the value of the checksum property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getChecksum()
+  {
+    return checksum;
+  }
+
+  /**
+   * Sets the value of the checksum property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setChecksum(String value)
+  {
+    this.checksum = value;
+  }
+
+  /**
+   * Gets the value of the modified property.
+   * 
+   * @return possible object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public XMLGregorianCalendar getModified()
+  {
+    return modified;
+  }
+
+  /**
+   * Sets the value of the modified property.
+   * 
+   * @param value
+   *          allowed object is {@link XMLGregorianCalendar }
+   * 
+   */
+  public void setModified(XMLGregorianCalendar value)
+  {
+    this.modified = value;
+  }
+
+  /**
+   * Gets the value of the version property.
+   * 
+   */
+  public int getVersion()
+  {
+    return version;
+  }
+
+  /**
+   * Sets the value of the version property.
+   * 
+   */
+  public void setVersion(int value)
+  {
+    this.version = value;
+  }
+
+  /**
+   * Gets the value of the precursor property.
+   * 
+   * @return possible object is {@link Boolean }
+   * 
+   */
+  public Boolean isPrecursor()
+  {
+    return precursor;
+  }
+
+  /**
+   * Sets the value of the precursor property.
+   * 
+   * @param value
+   *          allowed object is {@link Boolean }
+   * 
+   */
+  public void setPrecursor(Boolean value)
+  {
+    this.precursor = value;
+  }
+
+  /**
+   * Gets the value of the fragment property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getFragment()
+  {
+    return fragment;
+  }
+
+  /**
+   * Sets the value of the fragment property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setFragment(String value)
+  {
+    this.fragment = value;
+  }
 
 }
index 9796260..4c92560 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -18,14 +17,16 @@ import javax.xml.bind.annotation.XmlElements;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-
 /**
- * Describes the source of the sequence according to the citation.
- *             Equivalent to the flat file RC-line.
+ * Describes the source of the sequence according to the citation. Equivalent to
+ * the flat file RC-line.
  * 
- * <p>Java class for sourceDataType complex type.
+ * <p>
+ * Java class for sourceDataType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="sourceDataType">
@@ -77,385 +78,401 @@ import javax.xml.bind.annotation.XmlValue;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "sourceDataType", propOrder = {
-    "strainOrPlasmidOrTransposon"
-})
-public class SourceDataType {
-
-    @XmlElements({
-        @XmlElement(name = "strain", type = SourceDataType.Strain.class),
-        @XmlElement(name = "plasmid", type = SourceDataType.Plasmid.class),
-        @XmlElement(name = "transposon", type = SourceDataType.Transposon.class),
-        @XmlElement(name = "tissue", type = SourceDataType.Tissue.class)
-    })
-    protected List<Object> strainOrPlasmidOrTransposon;
+@XmlType(
+  name = "sourceDataType",
+  propOrder =
+  { "strainOrPlasmidOrTransposon" })
+public class SourceDataType
+{
+
+  @XmlElements({
+      @XmlElement(name = "strain", type = SourceDataType.Strain.class),
+      @XmlElement(name = "plasmid", type = SourceDataType.Plasmid.class),
+      @XmlElement(
+        name = "transposon",
+        type = SourceDataType.Transposon.class),
+      @XmlElement(name = "tissue", type = SourceDataType.Tissue.class) })
+  protected List<Object> strainOrPlasmidOrTransposon;
+
+  /**
+   * Gets the value of the strainOrPlasmidOrTransposon property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the strainOrPlasmidOrTransposon property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getStrainOrPlasmidOrTransposon().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link SourceDataType.Strain } {@link SourceDataType.Plasmid }
+   * {@link SourceDataType.Transposon } {@link SourceDataType.Tissue }
+   * 
+   * 
+   */
+  public List<Object> getStrainOrPlasmidOrTransposon()
+  {
+    if (strainOrPlasmidOrTransposon == null)
+    {
+      strainOrPlasmidOrTransposon = new ArrayList<Object>();
+    }
+    return this.strainOrPlasmidOrTransposon;
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;simpleContent>
+   *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+   *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
+   *     &lt;/extension>
+   *   &lt;/simpleContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "value" })
+  public static class Plasmid
+  {
+
+    @XmlValue
+    protected String value;
+
+    @XmlAttribute(name = "evidence")
+    protected List<Integer> evidence;
+
+    /**
+     * Gets the value of the value property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getValue()
+    {
+      return value;
+    }
 
     /**
-     * Gets the value of the strainOrPlasmidOrTransposon property.
+     * Sets the value of the value property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setValue(String value)
+    {
+      this.value = value;
+    }
+
+    /**
+     * Gets the value of the evidence property.
      * 
      * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the strainOrPlasmidOrTransposon property.
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the evidence property.
      * 
      * <p>
      * For example, to add a new item, do as follows:
+     * 
      * <pre>
-     *    getStrainOrPlasmidOrTransposon().add(newItem);
+     * getEvidence().add(newItem);
      * </pre>
      * 
      * 
      * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link SourceDataType.Strain }
-     * {@link SourceDataType.Plasmid }
-     * {@link SourceDataType.Transposon }
-     * {@link SourceDataType.Tissue }
+     * Objects of the following type(s) are allowed in the list {@link Integer }
      * 
      * 
      */
-    public List<Object> getStrainOrPlasmidOrTransposon() {
-        if (strainOrPlasmidOrTransposon == null) {
-            strainOrPlasmidOrTransposon = new ArrayList<Object>();
-        }
-        return this.strainOrPlasmidOrTransposon;
+    public List<Integer> getEvidence()
+    {
+      if (evidence == null)
+      {
+        evidence = new ArrayList<Integer>();
+      }
+      return this.evidence;
     }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;simpleContent>
+   *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+   *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
+   *     &lt;/extension>
+   *   &lt;/simpleContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "value" })
+  public static class Strain
+  {
+
+    @XmlValue
+    protected String value;
+
+    @XmlAttribute(name = "evidence")
+    protected List<Integer> evidence;
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the value property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * @return possible object is {@link String }
      * 
-     * <pre>
-     * &lt;complexType>
-     *   &lt;simpleContent>
-     *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
-     *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
-     *     &lt;/extension>
-     *   &lt;/simpleContent>
-     * &lt;/complexType>
-     * </pre>
+     */
+    public String getValue()
+    {
+      return value;
+    }
+
+    /**
+     * Sets the value of the value property.
      * 
+     * @param value
+     *          allowed object is {@link String }
      * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "value"
-    })
-    public static class Plasmid {
-
-        @XmlValue
-        protected String value;
-        @XmlAttribute(name = "evidence")
-        protected List<Integer> evidence;
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-
-        /**
-         * Gets the value of the evidence property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the evidence property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getEvidence().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link Integer }
-         * 
-         * 
-         */
-        public List<Integer> getEvidence() {
-            if (evidence == null) {
-                evidence = new ArrayList<Integer>();
-            }
-            return this.evidence;
-        }
-
+    public void setValue(String value)
+    {
+      this.value = value;
     }
 
-
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the evidence property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the evidence property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;simpleContent>
-     *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
-     *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
-     *     &lt;/extension>
-     *   &lt;/simpleContent>
-     * &lt;/complexType>
+     * getEvidence().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link Integer }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "value"
-    })
-    public static class Strain {
-
-        @XmlValue
-        protected String value;
-        @XmlAttribute(name = "evidence")
-        protected List<Integer> evidence;
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-
-        /**
-         * Gets the value of the evidence property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the evidence property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getEvidence().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link Integer }
-         * 
-         * 
-         */
-        public List<Integer> getEvidence() {
-            if (evidence == null) {
-                evidence = new ArrayList<Integer>();
-            }
-            return this.evidence;
-        }
+    public List<Integer> getEvidence()
+    {
+      if (evidence == null)
+      {
+        evidence = new ArrayList<Integer>();
+      }
+      return this.evidence;
+    }
+
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;simpleContent>
+   *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+   *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
+   *     &lt;/extension>
+   *   &lt;/simpleContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "value" })
+  public static class Tissue
+  {
+
+    @XmlValue
+    protected String value;
+
+    @XmlAttribute(name = "evidence")
+    protected List<Integer> evidence;
 
+    /**
+     * Gets the value of the value property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getValue()
+    {
+      return value;
     }
 
+    /**
+     * Sets the value of the value property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setValue(String value)
+    {
+      this.value = value;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the evidence property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the evidence property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;simpleContent>
-     *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
-     *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
-     *     &lt;/extension>
-     *   &lt;/simpleContent>
-     * &lt;/complexType>
+     * getEvidence().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link Integer }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "value"
-    })
-    public static class Tissue {
-
-        @XmlValue
-        protected String value;
-        @XmlAttribute(name = "evidence")
-        protected List<Integer> evidence;
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-
-        /**
-         * Gets the value of the evidence property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the evidence property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getEvidence().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link Integer }
-         * 
-         * 
-         */
-        public List<Integer> getEvidence() {
-            if (evidence == null) {
-                evidence = new ArrayList<Integer>();
-            }
-            return this.evidence;
-        }
+    public List<Integer> getEvidence()
+    {
+      if (evidence == null)
+      {
+        evidence = new ArrayList<Integer>();
+      }
+      return this.evidence;
+    }
 
+  }
+
+  /**
+   * <p>
+   * Java class for anonymous complex type.
+   * 
+   * <p>
+   * The following schema fragment specifies the expected content contained
+   * within this class.
+   * 
+   * <pre>
+   * &lt;complexType>
+   *   &lt;simpleContent>
+   *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
+   *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
+   *     &lt;/extension>
+   *   &lt;/simpleContent>
+   * &lt;/complexType>
+   * </pre>
+   * 
+   * 
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  @XmlType(name = "", propOrder = { "value" })
+  public static class Transposon
+  {
+
+    @XmlValue
+    protected String value;
+
+    @XmlAttribute(name = "evidence")
+    protected List<Integer> evidence;
+
+    /**
+     * Gets the value of the value property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getValue()
+    {
+      return value;
     }
 
+    /**
+     * Sets the value of the value property.
+     * 
+     * @param value
+     *          allowed object is {@link String }
+     * 
+     */
+    public void setValue(String value)
+    {
+      this.value = value;
+    }
 
     /**
-     * <p>Java class for anonymous complex type.
+     * Gets the value of the evidence property.
      * 
-     * <p>The following schema fragment specifies the expected content contained within this class.
+     * <p>
+     * This accessor method returns a reference to the live list, not a
+     * snapshot. Therefore any modification you make to the returned list will
+     * be present inside the JAXB object. This is why there is not a
+     * <CODE>set</CODE> method for the evidence property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
      * 
      * <pre>
-     * &lt;complexType>
-     *   &lt;simpleContent>
-     *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
-     *       &lt;attribute name="evidence" type="{http://uniprot.org/uniprot}intListType" />
-     *     &lt;/extension>
-     *   &lt;/simpleContent>
-     * &lt;/complexType>
+     * getEvidence().add(newItem);
      * </pre>
      * 
      * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list {@link Integer }
+     * 
+     * 
      */
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "", propOrder = {
-        "value"
-    })
-    public static class Transposon {
-
-        @XmlValue
-        protected String value;
-        @XmlAttribute(name = "evidence")
-        protected List<Integer> evidence;
-
-        /**
-         * Gets the value of the value property.
-         * 
-         * @return
-         *     possible object is
-         *     {@link String }
-         *     
-         */
-        public String getValue() {
-            return value;
-        }
-
-        /**
-         * Sets the value of the value property.
-         * 
-         * @param value
-         *     allowed object is
-         *     {@link String }
-         *     
-         */
-        public void setValue(String value) {
-            this.value = value;
-        }
-
-        /**
-         * Gets the value of the evidence property.
-         * 
-         * <p>
-         * This accessor method returns a reference to the live list,
-         * not a snapshot. Therefore any modification you make to the
-         * returned list will be present inside the JAXB object.
-         * This is why there is not a <CODE>set</CODE> method for the evidence property.
-         * 
-         * <p>
-         * For example, to add a new item, do as follows:
-         * <pre>
-         *    getEvidence().add(newItem);
-         * </pre>
-         * 
-         * 
-         * <p>
-         * Objects of the following type(s) are allowed in the list
-         * {@link Integer }
-         * 
-         * 
-         */
-        public List<Integer> getEvidence() {
-            if (evidence == null) {
-                evidence = new ArrayList<Integer>();
-            }
-            return this.evidence;
-        }
-
+    public List<Integer> getEvidence()
+    {
+      if (evidence == null)
+      {
+        evidence = new ArrayList<Integer>();
+      }
+      return this.evidence;
     }
 
+  }
+
 }
index 9293a64..2e92ca6 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.math.BigInteger;
@@ -14,13 +13,17 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes the source of the data using a database cross-reference (or a 'ref' attribute when the source cannot be found in a public data source, such as PubMed, and is cited only within the UniProtKB entry).
+ * Describes the source of the data using a database cross-reference (or a 'ref'
+ * attribute when the source cannot be found in a public data source, such as
+ * PubMed, and is cited only within the UniProtKB entry).
  * 
- * <p>Java class for sourceType complex type.
+ * <p>
+ * Java class for sourceType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="sourceType">
@@ -38,61 +41,59 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "sourceType", propOrder = {
-    "dbReference"
-})
-public class SourceType {
+@XmlType(name = "sourceType", propOrder = { "dbReference" })
+public class SourceType
+{
+
+  protected DbReferenceType dbReference;
 
-    protected DbReferenceType dbReference;
-    @XmlAttribute(name = "ref")
-    protected BigInteger ref;
+  @XmlAttribute(name = "ref")
+  protected BigInteger ref;
 
-    /**
-     * Gets the value of the dbReference property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link DbReferenceType }
-     *     
-     */
-    public DbReferenceType getDbReference() {
-        return dbReference;
-    }
+  /**
+   * Gets the value of the dbReference property.
+   * 
+   * @return possible object is {@link DbReferenceType }
+   * 
+   */
+  public DbReferenceType getDbReference()
+  {
+    return dbReference;
+  }
 
-    /**
-     * Sets the value of the dbReference property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link DbReferenceType }
-     *     
-     */
-    public void setDbReference(DbReferenceType value) {
-        this.dbReference = value;
-    }
+  /**
+   * Sets the value of the dbReference property.
+   * 
+   * @param value
+   *          allowed object is {@link DbReferenceType }
+   * 
+   */
+  public void setDbReference(DbReferenceType value)
+  {
+    this.dbReference = value;
+  }
 
-    /**
-     * Gets the value of the ref property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link BigInteger }
-     *     
-     */
-    public BigInteger getRef() {
-        return ref;
-    }
+  /**
+   * Gets the value of the ref property.
+   * 
+   * @return possible object is {@link BigInteger }
+   * 
+   */
+  public BigInteger getRef()
+  {
+    return ref;
+  }
 
-    /**
-     * Sets the value of the ref property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link BigInteger }
-     *     
-     */
-    public void setRef(BigInteger value) {
-        this.ref = value;
-    }
+  /**
+   * Sets the value of the ref property.
+   * 
+   * @param value
+   *          allowed object is {@link BigInteger }
+   * 
+   */
+  public void setRef(BigInteger value)
+  {
+    this.ref = value;
+  }
 
 }
index dd3308b..220c009 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -14,13 +13,15 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlValue;
 
-
 /**
  * Indicates whether the name of a plasmid is known or unknown.
  * 
- * <p>Java class for statusType complex type.
+ * <p>
+ * Java class for statusType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="statusType">
@@ -42,66 +43,67 @@ import javax.xml.bind.annotation.XmlValue;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "statusType", propOrder = {
-    "value"
-})
-public class StatusType {
+@XmlType(name = "statusType", propOrder = { "value" })
+public class StatusType
+{
 
-    @XmlValue
-    protected String value;
-    @XmlAttribute(name = "status")
-    protected String status;
+  @XmlValue
+  protected String value;
 
-    /**
-     * Gets the value of the value property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getValue() {
-        return value;
-    }
+  @XmlAttribute(name = "status")
+  protected String status;
 
-    /**
-     * Sets the value of the value property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setValue(String value) {
-        this.value = value;
-    }
+  /**
+   * Gets the value of the value property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getValue()
+  {
+    return value;
+  }
 
-    /**
-     * Gets the value of the status property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getStatus() {
-        if (status == null) {
-            return "known";
-        } else {
-            return status;
-        }
-    }
+  /**
+   * Sets the value of the value property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setValue(String value)
+  {
+    this.value = value;
+  }
 
-    /**
-     * Sets the value of the status property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setStatus(String value) {
-        this.status = value;
+  /**
+   * Gets the value of the status property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getStatus()
+  {
+    if (status == null)
+    {
+      return "known";
+    }
+    else
+    {
+      return status;
     }
+  }
+
+  /**
+   * Sets the value of the status property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setStatus(String value)
+  {
+    this.status = value;
+  }
 
 }
index 97522e2..f8adfde 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -15,13 +14,16 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * Describes the subcellular location and optionally the topology and orientation of a molecule.
+ * Describes the subcellular location and optionally the topology and
+ * orientation of a molecule.
  * 
- * <p>Java class for subcellularLocationType complex type.
+ * <p>
+ * Java class for subcellularLocationType complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType name="subcellularLocationType">
@@ -40,103 +42,114 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "subcellularLocationType", propOrder = {
-    "location",
-    "topology",
-    "orientation"
-})
-public class SubcellularLocationType {
+@XmlType(
+  name = "subcellularLocationType",
+  propOrder =
+  { "location", "topology", "orientation" })
+public class SubcellularLocationType
+{
+
+  @XmlElement(required = true)
+  protected List<EvidencedStringType> location;
+
+  protected List<EvidencedStringType> topology;
 
-    @XmlElement(required = true)
-    protected List<EvidencedStringType> location;
-    protected List<EvidencedStringType> topology;
-    protected List<EvidencedStringType> orientation;
+  protected List<EvidencedStringType> orientation;
 
-    /**
-     * Gets the value of the location property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the location property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getLocation().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EvidencedStringType }
-     * 
-     * 
-     */
-    public List<EvidencedStringType> getLocation() {
-        if (location == null) {
-            location = new ArrayList<EvidencedStringType>();
-        }
-        return this.location;
+  /**
+   * Gets the value of the location property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the location property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getLocation().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EvidencedStringType }
+   * 
+   * 
+   */
+  public List<EvidencedStringType> getLocation()
+  {
+    if (location == null)
+    {
+      location = new ArrayList<EvidencedStringType>();
     }
+    return this.location;
+  }
 
-    /**
-     * Gets the value of the topology property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the topology property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getTopology().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EvidencedStringType }
-     * 
-     * 
-     */
-    public List<EvidencedStringType> getTopology() {
-        if (topology == null) {
-            topology = new ArrayList<EvidencedStringType>();
-        }
-        return this.topology;
+  /**
+   * Gets the value of the topology property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the topology property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getTopology().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EvidencedStringType }
+   * 
+   * 
+   */
+  public List<EvidencedStringType> getTopology()
+  {
+    if (topology == null)
+    {
+      topology = new ArrayList<EvidencedStringType>();
     }
+    return this.topology;
+  }
 
-    /**
-     * Gets the value of the orientation property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the orientation property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getOrientation().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link EvidencedStringType }
-     * 
-     * 
-     */
-    public List<EvidencedStringType> getOrientation() {
-        if (orientation == null) {
-            orientation = new ArrayList<EvidencedStringType>();
-        }
-        return this.orientation;
+  /**
+   * Gets the value of the orientation property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the orientation property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getOrientation().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list
+   * {@link EvidencedStringType }
+   * 
+   * 
+   */
+  public List<EvidencedStringType> getOrientation()
+  {
+    if (orientation == null)
+    {
+      orientation = new ArrayList<EvidencedStringType>();
     }
+    return this.orientation;
+  }
 
 }
index 14f96df..283ba1f 100644 (file)
@@ -2,10 +2,9 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-
 package jalview.xml.binding.uniprot;
 
 import java.util.ArrayList;
@@ -16,11 +15,13 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
-
 /**
- * <p>Java class for anonymous complex type.
+ * <p>
+ * Java class for anonymous complex type.
  * 
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * The following schema fragment specifies the expected content contained within
+ * this class.
  * 
  * <pre>
  * &lt;complexType>
@@ -38,68 +39,68 @@ import javax.xml.bind.annotation.XmlType;
  * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {
-    "entry",
-    "copyright"
-})
+@XmlType(name = "", propOrder = { "entry", "copyright" })
 @XmlRootElement(name = "uniprot")
-public class Uniprot {
+public class Uniprot
+{
 
-    @XmlElement(required = true)
-    protected List<Entry> entry;
-    protected String copyright;
+  @XmlElement(required = true)
+  protected List<Entry> entry;
 
-    /**
-     * Gets the value of the entry property.
-     * 
-     * <p>
-     * This accessor method returns a reference to the live list,
-     * not a snapshot. Therefore any modification you make to the
-     * returned list will be present inside the JAXB object.
-     * This is why there is not a <CODE>set</CODE> method for the entry property.
-     * 
-     * <p>
-     * For example, to add a new item, do as follows:
-     * <pre>
-     *    getEntry().add(newItem);
-     * </pre>
-     * 
-     * 
-     * <p>
-     * Objects of the following type(s) are allowed in the list
-     * {@link Entry }
-     * 
-     * 
-     */
-    public List<Entry> getEntry() {
-        if (entry == null) {
-            entry = new ArrayList<Entry>();
-        }
-        return this.entry;
-    }
+  protected String copyright;
 
-    /**
-     * Gets the value of the copyright property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
-     */
-    public String getCopyright() {
-        return copyright;
+  /**
+   * Gets the value of the entry property.
+   * 
+   * <p>
+   * This accessor method returns a reference to the live list, not a snapshot.
+   * Therefore any modification you make to the returned list will be present
+   * inside the JAXB object. This is why there is not a <CODE>set</CODE> method
+   * for the entry property.
+   * 
+   * <p>
+   * For example, to add a new item, do as follows:
+   * 
+   * <pre>
+   * getEntry().add(newItem);
+   * </pre>
+   * 
+   * 
+   * <p>
+   * Objects of the following type(s) are allowed in the list {@link Entry }
+   * 
+   * 
+   */
+  public List<Entry> getEntry()
+  {
+    if (entry == null)
+    {
+      entry = new ArrayList<Entry>();
     }
+    return this.entry;
+  }
 
-    /**
-     * Sets the value of the copyright property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
-     */
-    public void setCopyright(String value) {
-        this.copyright = value;
-    }
+  /**
+   * Gets the value of the copyright property.
+   * 
+   * @return possible object is {@link String }
+   * 
+   */
+  public String getCopyright()
+  {
+    return copyright;
+  }
+
+  /**
+   * Sets the value of the copyright property.
+   * 
+   * @param value
+   *          allowed object is {@link String }
+   * 
+   */
+  public void setCopyright(String value)
+  {
+    this.copyright = value;
+  }
 
 }
index a7bc67c..eb7f47a 100644 (file)
@@ -2,8 +2,10 @@
 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
 // Any modifications to this file will be lost upon recompilation of the source schema. 
-// Generated on: 2023.03.17 at 05:31:46 PM GMT 
+// Generated on: 2023.05.13 at 06:58:42 PM BST 
 //
 
-@javax.xml.bind.annotation.XmlSchema(namespace = "http://uniprot.org/uniprot", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+@javax.xml.bind.annotation.XmlSchema(
+  namespace = "http://uniprot.org/uniprot",
+  elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
 package jalview.xml.binding.uniprot;
index 6d02630..2970ccf 100755 (executable)
@@ -39,6 +39,7 @@ import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureMapping;
 import jalview.util.Comparison;
+import jalview.ws.datamodel.MappableContactMatrixI;
 
 public class PDBChain
 {
@@ -700,9 +701,10 @@ public class PDBChain
               ana = new AlignmentAnnotation(ana);
               ana.liftOver(dsq, sqmpping);
               dsq.addAlignmentAnnotation(ana);
-              if (cm != null)
+              if (cm != null && cm instanceof MappableContactMatrixI)
               {
-                dsq.addContactListFor(ana, cm);
+                dsq.addContactListFor(ana, ((MappableContactMatrixI) cm)
+                        .liftOver(dsq, sqmpping));
               }
             }
             else
@@ -717,8 +719,8 @@ public class PDBChain
         // Useful for debugging mappings - adds annotation for mapped position
         float min = -1, max = 0;
         Annotation[] an = new Annotation[sq.getEnd() - sq.getStart() + 1];
-        for (int i = sq.getStart(), j = sq.getEnd(),
-                k = 0; i <= j; i++, k++)
+        for (int i = sq.getStart(), j = sq
+                .getEnd(), k = 0; i <= j; i++, k++)
         {
           int prn = mapping.getPDBResNum(k + 1);
 
index 2a89e61..21d3dcb 100755 (executable)
@@ -26,7 +26,6 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.Vector;
 
-import jalview.bin.Console;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceI;
@@ -52,9 +51,7 @@ public class PDBfile extends StructureFile
           DataSourceType sourceType) throws IOException
   {
     super(false, dataObject, sourceType);
-    Console.debug("***** PDBfile constructor");
     addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
-    Console.debug("***** About to doParse() 1");
     doParse();
   }
 
@@ -63,7 +60,6 @@ public class PDBfile extends StructureFile
   {
     super(false, source);
     addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
-    Console.debug("***** About to doParse() 2");
     doParse();
   }
 
diff --git a/test/files/annotation_label_width/sample.a2m b/test/files/annotation_label_width/sample.a2m
new file mode 100644 (file)
index 0000000..0ca6801
--- /dev/null
@@ -0,0 +1,80 @@
+>101
+P.I...A..Q..I.....H.....I........L.......E........G.......R.......S....D.......E.......Q.....K....E.
+T..LI....RE...V.S.E...A...I......S.......R...S.......L........D....A.....P......L...................
+..........T......S.......V.......R......V...I....I.......T......E.....M........A....K.........G.....
+.H..........F..........G........I..........G........G......E........L....A...SK
+>UPI
+P.Hye.V..S..V.....T.....M........P.......T........G.......Wl......N....T.......V.......R.....K....Q.
+G..MI....DA...V.T.R...A...L......L.......E...A.......I........A....T.....P......F...................
+..........D......Essrfr..V.......R......C...L....I.......P......E.....I........P....D.........G.....
+.N..........W..........G........S..........G........Gya....L........P....L...S-
+>SRR
+P.H...V..A..V.....K.....L........Y.......P........G.......R.......T....E.......Q.......Q.....K....E.
+Q..LA....RA...I.A.D...D...V......M.......R...I.......L........G....S.....S......E...................
+..........A......S.......V.......S......V...S....I.......E......E.....V........D....A.........A.....
+.D..........W..........A........EkvyrplivegG........G......T........L....Y...KK
+>SRR
+P.H...V..I..V.....K.....L........W.......P........G.......R.......S....E.......P.......Q.....K....Q.
+K..LV....ES...V.T.K...A...V......T.......T...S.......L........G....Y.....S......D...................
+..........E......A.......V.......S......V...S....L.......Q......E.....V........P....S.........D.....
+.Q..........WtekvyrpdilG........T..........A........G......R........L....Y...KK
+>MGY
+P.I...V..R..I.....T.....M........F.......E........G.......R.......T....K.......E.......Q.....K....Q.
+E..LA....RV...I.T.E...A...V......V.......N...I.......A........K....T.....T......P...................
+..........D......A.......T.......E......VkdqI....L.......Q......K.....VllvrslrlP....PppasrrqvsG.....
+.A..........W..........S........A..........D........G......K........P....T...SE
+>446
+P.H...V..I..V.....K.....L........W.......P........G.......K.......S....E.......R.......E.....E....T.
+Q..LA....EA...I.T.K...S...V......T.......E...T.......L........N....F.....G......P...................
+..........E......S.......V.......S......V...A....F.......E......E.....I........P....A.........K.....
+.D..........W..........AskvyhadiI..........Gne......G......K........L....Y...KK
+>SRR
+P.L...V..R..I.....T.....Y........P.......R........Ga......L.......S....P.......E.......H.....K....T.
+R..IA....RA...L.T.E...I...V......L.......D...Vevdaa..T........D....A.....G......R...................
+..........M......V.......T.......V......V...H....F.......N......E.....A........A....P.........D.....
+.D..........W..........A........V..........G........G......Eirs.....T....A...AE
+>SRR
+P.L...V..R..I.....T.....Y........P.......R........Ga......L.......S....P.......D.......H.....K....R.
+R..IA....RE...L.T.E...I...V......L.......D...Vevdaa..T........D....A.....G......R...................
+..........M......V.......T.......V......I...H....F.......N......E.....A........A....A.........D.....
+.D..........W..........A........V..........G........G......Eirs.....T....A...AE
+>SRR
+P.R...Y..R..Vip...T.....V........P.......E........G.......Qy......S....N.......E.......S.....R....K.
+A..LV....KD...V.T.E...A...V......V.......R...A.......D........G....G.....K......Y...................
+..........E......Dvapr...V.......W......V...F....P.......T......E.....I........P....D.........G.....
+.Q..........W..........G........S..........R........Gvi....R........P....L...PE
+>SRR
+P.R...Y..R..Iip...T.....V........P.......E........G.......Qy......S....N.......E.......S.....R....K.
+A..LV....KD...V.T.E...A...V......V.......R...A.......D........G....G.....K......Y...................
+..........E......Dvapr...V.......W......V...F....P.......T......E.....I........P....D.........G.....
+.Q..........W..........G........S..........R........Gvi....R........P....L...PE
+>SRR
+P.V...I..E..M.....F.....V........P.......E........G.......La......D....A.......E.......A.....K....R.
+A..LH....DR...V.S.R...Q...V......L.......E...V.......E........G....AtydesP......L...................
+..........A......Qsi.....T.......W......M...L....I.......Q......E.....V........L....E.........C.....
+.G..........W..........S........V..........G........S......K........Avw..A...SE
+>SRR
+P.I...I..E..M.....H.....V........Q.......E........Gv......L.......D....E.......E.......T.....K....R.
+T..LH....ER...V.G.R...Q...V......L.......E...I.......E........G....Any...D......E...................
+..........N......D.......Varllt..F......M...F....I.......R......E.....H........P....E.........G.....
+.G..........F..........S........I..........G........G......E........M....It..SE
+>SRR
+P.Lyr.V..D..V.....T.....V........P.......E........Gsmihg..Q.......G....Pwal....S.......R.....R....R.
+A..IV....RE...V.T.E...I...V......L.......E...A.......E........G....S.....D......P...................
+..........Slgeaw.R.......V.......W......V...V....L.......R......E.....V........G....D.........A.....
+.F..........W..........G........A..........A........G......E........L....-...--
+>SRR
+P.Lyr.V..Q..I.....T.....V........P.......E........Gsmlhg..Q.......G....Pwai....E.......R.....R....R.
+E..LV....RA...V.S.K...A...V......L.......D...A.......E........G....Teyn..P......A...................
+..........Saw....R.......V.......W......V...L....M.......S......E.....I........S....E.........T.....
+.H..........W..........G........A..........A........G......E........-....-...--
+>SRR
+P.L...V..E..M.....S.....F........P.......V........Gv......L.......T....L.......D.......Q.....K....A.
+A..MI....KS...V.T.D...V...V......R.......G...A.......M........K....L.....P......P...................
+..........Dpar...K.......L.......F......V...E....I.......F......E.....T........P....G.........G.....
+.G..........F..........G........Vtakvvvvp..G........Gky....R........P....A...P-
+>SRR
+P.L...V..E..I.....D.....L........L.......E........A.......W.......A....P.......D.......Q.....I....D.
+A..IA....DA...I.H.E...A...M......V.......E...T.......L........G....V.....P......Eraagrdsatkqhfysrfaa
+llaeratvqsA......D.......L.......T......A...V....L.......V......E.....N........S....R.........D.....
+.D..........W..........S........F..........Gm.......G......Q........-....-...--
diff --git a/test/files/annotation_label_width/test_fab41_nostructureviewers.txt b/test/files/annotation_label_width/test_fab41_nostructureviewers.txt
new file mode 100644 (file)
index 0000000..b40c4e2
--- /dev/null
@@ -0,0 +1,15 @@
+--nonews
+--nosplash
+--open=./test/files/annotation_label_width/sample.a2m
+--colour=gecos:flower
+--gui
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb
+--paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb
+--paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4_scores.json
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb
+--paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2_scores.json
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5.pdb
+--paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5_scores.json
+--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1.pdb
+--paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1_scores.json
index 4baa384..f017662 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.analysis;
 
+import static org.testng.Assert.assertNotEquals;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertNotNull;
@@ -54,6 +55,7 @@ import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SeqDistanceContactMatrix;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.gui.JvOptionPane;
 import jalview.io.AppletFormatAdapter;
@@ -62,6 +64,7 @@ import jalview.io.FileFormat;
 import jalview.io.FileFormatI;
 import jalview.io.FormatAdapter;
 import jalview.io.gff.SequenceOntologyI;
+import jalview.util.Comparison;
 import jalview.util.MapList;
 import jalview.util.MappingUtils;
 
@@ -2603,6 +2606,98 @@ public class AlignmentUtilsTests
   }
 
   @Test(groups = "Functional")
+  public void testAddReferenceAnnotations()
+  {
+    SequenceI longseq = new Sequence("longA", "ASDASDASDASDAASDASDASDASDA");
+    Annotation[] aa = new Annotation[longseq.getLength()];
+
+    for (int p = 0; p < aa.length; p++)
+    {
+      aa[p] = new Annotation("P", "pos " + (p + 1), (char) 0,
+              (float) p + 1);
+    }
+    AlignmentAnnotation refAnnot = new AlignmentAnnotation("LongSeqAnnot",
+            "Annotations", aa);
+    refAnnot.setCalcId("Test");
+    longseq.addAlignmentAnnotation(refAnnot);
+    verifyExpectedSequenceAnnotation(refAnnot);
+
+    Alignment ourAl = new Alignment(
+            new SequenceI[]
+            { longseq.getSubSequence(5, 10),
+                longseq.getSubSequence(7, 12) });
+    ourAl.createDatasetAlignment();
+
+    // transfer annotation
+    SortedMap<String, String> tipEntries = new TreeMap<>();
+    Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
+
+    AlignmentUtils.findAddableReferenceAnnotations(ourAl.getSequences(),
+            tipEntries, candidates, ourAl);
+    AlignmentUtils.addReferenceAnnotations(candidates, ourAl, null);
+
+    assertNotNull(ourAl.getAlignmentAnnotation());
+    assertEquals(ourAl.getAlignmentAnnotation().length, 2);
+
+    for (AlignmentAnnotation alan : ourAl.getAlignmentAnnotation())
+    {
+      verifyExpectedSequenceAnnotation(alan);
+    }
+    // Everything above works for 2.11.3 and 2.11.2.x.
+    // now simulate copy/paste to new alignment
+    SequenceI[] newSeqAl = new SequenceI[2];
+    // copy sequences but no annotation
+    newSeqAl[0] = new Sequence(ourAl.getSequenceAt(0),
+            ourAl.getSequenceAt(0).getAnnotation());
+    newSeqAl[1] = new Sequence(ourAl.getSequenceAt(1),
+            ourAl.getSequenceAt(1).getAnnotation());
+
+    Alignment newAl = new Alignment(newSeqAl);
+    // delete annotation
+    for (SequenceI sq : newAl.getSequences())
+    {
+      sq.setAlignmentAnnotation(new AlignmentAnnotation[0]);
+    }
+    // JAL-4182 scenario test
+    SequenceGroup sg = new SequenceGroup(Arrays.asList(newSeqAl));
+    sg.setStartRes(0);
+    sg.setEndRes(newAl.getWidth());
+    AlignmentUtils.addReferenceAnnotationTo(newAl, newSeqAl[0],
+            newSeqAl[0].getDatasetSequence().getAnnotation()[0], sg);
+    AlignmentUtils.addReferenceAnnotationTo(newAl, newSeqAl[1],
+            newSeqAl[1].getDatasetSequence().getAnnotation()[0], sg);
+    for (AlignmentAnnotation alan : newAl.getAlignmentAnnotation())
+    {
+      verifyExpectedSequenceAnnotation(alan);
+    }
+  }
+
+  /**
+   * helper - tests annotation is mapped to position it was originally created
+   * for
+   * 
+   * @param alan
+   */
+  private void verifyExpectedSequenceAnnotation(AlignmentAnnotation alan)
+  {
+    for (int c = 0; c < alan.annotations.length; c++)
+    {
+      Annotation a = alan.annotations[c];
+      if (a != null)
+      {
+        assertEquals("Misaligned annotation at " + c,
+                (float) alan.sequenceRef.findPosition(c), a.value);
+      }
+      else
+      {
+        assertTrue("Unexpected Null at position " + c,
+                c >= alan.sequenceRef.getLength()
+                        || Comparison.isGap(alan.sequenceRef.getCharAt(c)));
+      }
+    }
+  }
+
+  @Test(groups = "Functional")
   public void testAddReferenceContactMap()
   {
     SequenceI sq = new Sequence("a", "SSSQ");
@@ -2626,11 +2721,18 @@ public class AlignmentUtilsTests
                     && al.getAlignmentAnnotation().length == 1);
     AlignmentAnnotation alan = al.findAnnotations(sq, null, cm_aan.label)
             .iterator().next();
+    ContactMatrixI t_cm = al.getContactMatrixFor(alan);
+    assertNotNull("No contact map for the transferred annotation row.",
+            t_cm);
+    assertTrue(t_cm instanceof SeqDistanceContactMatrix);
+    assertTrue(((SeqDistanceContactMatrix) t_cm).hasReferenceSeq());
+
     ContactListI cl = al.getContactListFor(alan, 1);
     assertNotNull(
             "No contact matrix recovered after reference annotation transfer",
             cl);
-    // semantics of sequence associated contact list is slightly tricky - column 3 in alignment should have data
+    // semantics of sequence associated contact list is slightly tricky - column
+    // 3 in alignment should have data
     cl = al.getContactListFor(alan, 3);
     assertNotNull(
             "Contact matrix should have data for last position in sequence",
index 6d9ab50..760e0ba 100644 (file)
@@ -32,66 +32,77 @@ import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 public class AverageDistanceEngineTest
 {
 
-    @BeforeClass(alwaysRun = true)
-    public void setUpJvOptionPane()
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @BeforeMethod(alwaysRun = true)
+  public void loadProperties()
+  {
+    Cache.loadProperties("test/jalview/bin/TestProps.jvprops");
+  }
+
+  @Test(groups = { "Functional" })
+  public void testUPGMAEngine() throws Exception
+  {
+    AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
+            "examples/test_fab41.result/sample.a3m", DataSourceType.FILE);
+    AlignmentI seqs = af.getViewport().getAlignment();
+    SequenceI target = seqs.getSequenceAt(0);
+    File testPAE = new File(
+            "examples/test_fab41.result/test_fab41_predicted_aligned_error_v1.json");
+    List<Object> pae_obj = (List<Object>) Platform
+            .parseJSON(new FileInputStream(testPAE));
+    if (pae_obj == null)
     {
-      JvOptionPane.setInteractiveMode(false);
-      JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+      Assert.fail("JSON PAE file did not parse properly.");
     }
+    ContactMatrixI matrix = new PAEContactMatrix(target,
+            (Map<String, Object>) pae_obj.get(0));
+    AlignmentAnnotation aa = target.addContactList(matrix);
+    System.out.println("Matrix has max=" + matrix.getMax() + " and min="
+            + matrix.getMin());
+    long start = System.currentTimeMillis();
+    AverageDistanceEngine clusterer = new AverageDistanceEngine(
+            af.getViewport(), null, matrix, false);
+    System.out.println("built a tree in "
+            + (System.currentTimeMillis() - start) * 0.001 + " seconds.");
+    StringBuffer sb = new StringBuffer();
+    System.out.println("Newick string\n"
+            + new jalview.io.NewickFile(clusterer.getTopNode(), true, true)
+                    .print());
 
-    @BeforeMethod(alwaysRun = true)
-    public void loadProperties()
+    double height = clusterer.findHeight(clusterer.getTopNode());
+    // compute height fraction to cut
+    // PAE matrixes are absolute measure in angstrom, so
+    // cluster all regions within threshold (e.g. 2A) - if height above
+    // threshold. Otherwise all nodes are in one cluster
+    double thr = .2;
+    List<BinaryNode> groups;
+    if (height > thr)
     {
-      Cache.loadProperties("test/jalview/bin/TestProps.jvprops");
+      float cut = (float) (thr / height);
+      System.out.println("Threshold " + cut + " for height=" + height);
+      groups = clusterer.groupNodes(cut);
     }
-    @Test
-    public void testUPGMAEngine() throws Exception
+    else
     {
-      AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded("examples/test_fab41.result/sample.a3m",DataSourceType.FILE);
-      AlignmentI seqs = af.getViewport().getAlignment();
-      SequenceI target = seqs.getSequenceAt(0);
-      File testPAE = new File("examples/test_fab41.result/test_fab41_predicted_aligned_error_v1.json");
-      List<Object> pae_obj = (List<Object>) Platform.parseJSON(new FileInputStream(testPAE));
-      if (pae_obj == null)
-      {
-        Assert.fail("JSON PAE file did not parse properly.");
-      }
-      ContactMatrixI matrix = new PAEContactMatrix(target,
-              (Map<String, Object>) pae_obj.get(0));
-      AlignmentAnnotation aa = target.addContactList(matrix);
-      System.out.println("Matrix has max="+matrix.getMax()+" and min="+matrix.getMin());
-      long start = System.currentTimeMillis();
-      AverageDistanceEngine clusterer = new AverageDistanceEngine(af.getViewport(), null, matrix);
-      System.out.println("built a tree in "+(System.currentTimeMillis()-start)*0.001+" seconds.");
-      StringBuffer sb = new StringBuffer(); 
-      System.out.println("Newick string\n"+      new jalview.io.NewickFile(clusterer.getTopNode(),true,true).print());
-      
-      double height = clusterer.findHeight(clusterer.getTopNode());
-      // compute height fraction to cut 
-      // PAE matrixes are absolute measure in angstrom, so 
-      // cluster all regions within threshold (e.g. 2A) - if height above threshold. Otherwise all nodes are in one cluster
-      double thr=.2;
-      List<BinaryNode> groups;
-      if (height>thr)
-      {
-        float cut = (float) (thr/height);
-        System.out.println("Threshold "+cut+" for height="+height);
-        groups = clusterer.groupNodes(cut);
-      } else{
-        groups=new ArrayList<BinaryNode>();
-        groups.add(clusterer.getTopNode());
-      }
-      int n=1;
-      for (BinaryNode root:groups)
+      groups = new ArrayList<BinaryNode>();
+      groups.add(clusterer.getTopNode());
+    }
+    int n = 1;
+    for (BinaryNode root : groups)
+    {
+      System.out.println("Cluster " + n++);
+      for (BinaryNode leaf : clusterer.findLeaves(root))
       {
-        System.out.println("Cluster "+n++);
-        for (BinaryNode leaf:clusterer.findLeaves(root))
-        {
-          System.out.print(" "+leaf.getName());
-        }
-        System.out.println("\\");
+        System.out.print(" " + leaf.getName());
       }
-      
+      System.out.println("\\");
     }
+  }
 
 }
index 5134511..44bea81 100644 (file)
@@ -29,11 +29,15 @@ import jalview.datamodel.SequenceI;
 import jalview.gui.JvOptionPane;
 
 import java.io.PrintStream;
+import java.nio.charset.Charset;
+import java.util.Locale;
 
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Charsets;
+
 /**
  * Test the alignment -> Mapping routines
  * 
@@ -83,16 +87,44 @@ public class TestAlignSeq
     assertEquals(as.getAStr1(), as.getAStr2());
 
     Mapping s1tos2 = as.getMappingFromS1(false);
+    checkMapping(s1tos2,s1,s2);
+  }
+
+  public void checkMapping(Mapping s1tos2,SequenceI _s1,SequenceI _s2)
+  {
     System.out.println(s1tos2.getMap().toString());
-    for (int i = s2.getStart(); i < s2.getEnd(); i++)
+    for (int i = _s2.getStart(); i < _s2.getEnd(); i++)
     {
-      System.out.println("Position in s2: " + i
-              + " maps to position in s1: " + s1tos2.getPosition(i));
-      // TODO fails: getCharAt doesn't allow for the start position??
-      // assertEquals(String.valueOf(s2.getCharAt(i)),
-      // String.valueOf(s1.getCharAt(s1tos2.getPosition(i))));
+      int p=s1tos2.getPosition(i);
+      char s2c=_s2.getCharAt(i-_s2.getStart());
+      char s1c=_s1.getCharAt(p-_s1.getStart());
+      System.out.println("Position in s2: " + i +s2c 
+      + " maps to position in s1: " +p+s1c);
+      assertEquals(s1c,s2c);
     }
   }
+  @Test(groups = { "Functional" })
+  /**
+   * simple test that mapping from alignment corresponds identical positions.
+   */
+  public void testGetMappingForS1_withLowerCase()
+  {
+    // make one of the sequences lower case
+    SequenceI ns2 = new Sequence(s2);
+    ns2.replace('D', 'd');
+    AlignSeq as = AlignSeq.doGlobalNWAlignment(s1, ns2, AlignSeq.PEP);
+    System.out.println("s1: " + as.getAStr1());
+    System.out.println("s2: " + as.getAStr2());
+
+    // aligned results match
+    assertEquals("ASDFA", as.getAStr1());
+    assertEquals(as.getAStr1(), as.getAStr2().toUpperCase(Locale.ROOT));
+
+    Mapping s1tos2 = as.getMappingFromS1(false);
+    assertEquals("ASdFA",as.getAStr2());
+    // verify mapping is consistent between original all-caps sequences
+    checkMapping(s1tos2,s1,s2);
+  }
 
   @Test(groups = { "Functional" })
   public void testExtractGaps()
index 23db36f..f36b45a 100644 (file)
@@ -25,6 +25,7 @@ import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.bin.ArgsParser;
 import jalview.gui.JvOptionPane;
 
 import org.testng.annotations.BeforeClass;
index 7509ec9..77cbd92 100644 (file)
@@ -34,7 +34,6 @@ import java.util.ArrayList;
 import org.testng.Assert;
 import org.testng.FileAssert;
 import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeTest;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
@@ -54,7 +53,7 @@ public class CommandLineOperations
   }
 
   // Note longer timeout needed on full test run than on individual tests
-  private static final int TEST_TIMEOUT = 13000;
+  private static final int TEST_TIMEOUT = 15000;
 
   private static final int SETUP_TIMEOUT = 9500;
 
@@ -213,33 +212,34 @@ public class CommandLineOperations
     }
   }
 
-  @BeforeTest(alwaysRun = true)
+  @BeforeClass(alwaysRun = true)
   public void initialize()
   {
     new CommandLineOperations();
   }
 
-  @BeforeTest(alwaysRun = true)
+  @BeforeClass(alwaysRun = true)
   public void setUpForHeadlessCommandLineInputOperations()
           throws IOException
   {
-    String cmds = "nodisplay -open examples/uniref50.fa -sortbytree --props=test/jalview/bin/testProps.jvprops -colour zappo "
+    String cmds = "nodisplay -open examples/uniref50.fa -sortbytree -props test/jalview/bin/testProps.jvprops -colour zappo "
             + "-jabaws http://www.compbio.dundee.ac.uk/jabaws -nosortbytree "
             + "-features examples/testdata/plantfdx.features -annotations examples/testdata/plantfdx.annotations -tree examples/testdata/uniref50_test_tree";
     Worker worker = getJalviewDesktopRunner(true, cmds, SETUP_TIMEOUT);
     String ln = null;
     while ((ln = worker.getOutputReader().readLine()) != null)
     {
-      System.out.println(ln);
+      System.out.println("STDOUT: " + ln);
       successfulCMDs.add(ln);
     }
     while ((ln = worker.getErrorReader().readLine()) != null)
     {
-      System.err.println(ln);
+      System.err.println("STDERR: " + ln);
+      successfulCMDs.add(ln);
     }
   }
 
-  @BeforeTest(alwaysRun = true)
+  @BeforeClass(alwaysRun = true)
   public void setUpForCommandLineInputOperations() throws IOException
   {
     String cmds = "-open examples/uniref50.fa -noquestionnaire -nousagestats";
@@ -248,6 +248,7 @@ public class CommandLineOperations
 
     // number of lines expected on STDERR when Jalview starts up normally
     // may need to adjust this if Jalview is excessively noisy ?
+    final int STDOUT_SETUPLINES = 50;
     final int STDERR_SETUPLINES = 50;
 
     // thread monitors stderr - bails after SETUP_TIMEOUT or when
@@ -258,14 +259,24 @@ public class CommandLineOperations
       public void run()
       {
         String ln = null;
-        int count = 0;
+        int stdoutcount = 0;
+        int stderrcount = 0;
         try
         {
-          while ((ln = worker.getErrorReader().readLine()) != null)
+          while ((ln = worker.getOutputReader().readLine()) != null)
           {
             System.out.println(ln);
             successfulCMDs.add(ln);
-            if (++count > STDERR_SETUPLINES)
+            if (++stdoutcount > STDOUT_SETUPLINES)
+            {
+              break;
+            }
+          }
+          while ((ln = worker.getErrorReader().readLine()) != null)
+          {
+            System.err.println(ln);
+            successfulCMDs.add(ln);
+            if (++stderrcount > STDERR_SETUPLINES)
             {
               break;
             }
@@ -341,9 +352,9 @@ public class CommandLineOperations
     return new Object[][] {
         // headless mode input operations
         { "CMD [-colour zappo] executed successfully!",
-            "Failed command : -color zappo" },
+            "Failed command : -colour zappo" },
         { "CMD [-props test/jalview/bin/testProps.jvprops] executed successfully!",
-            "Failed command : --props=File" },
+            "Failed command : -props File" },
         { "CMD [-sortbytree] executed successfully!",
             "Failed command : -sortbytree" },
         { "CMD [-jabaws http://www.compbio.dundee.ac.uk/jabaws] executed successfully!",
@@ -373,9 +384,11 @@ public class CommandLineOperations
     // since it works.
     // https://issues.jalview.org/browse/JAL-1889?focusedCommentId=21609&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-21609
     String workingDir = "test/jalview/bin/";
-    return new Object[][] { { "nodisplay -open examples/uniref50.fa",
-        " -eps", workingDir + "test_uniref50_out.eps", true,
-        MINFILESIZE_BIG, TEST_TIMEOUT },
+    return new Object[][] {
+        //
+        { "nodisplay -open examples/uniref50.fa", " -eps",
+            workingDir + "test_uniref50_out.eps", true, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
         { "nodisplay -open examples/uniref50.fa", " -eps",
             workingDir + "test_uniref50_out.eps", false, MINFILESIZE_BIG,
             TEST_TIMEOUT },
@@ -420,6 +433,8 @@ public class CommandLineOperations
             TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -jalview",
             workingDir + "test_uniref50_out.jvp", true, MINFILESIZE_SMALL,
-            TEST_TIMEOUT }, };
+            TEST_TIMEOUT },
+        //
+    };
   }
 }
diff --git a/test/jalview/bin/CommandLineOperationsNG.java b/test/jalview/bin/CommandLineOperationsNG.java
new file mode 100644 (file)
index 0000000..56d4300
--- /dev/null
@@ -0,0 +1,537 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.bin;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.FileAssert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import io.github.classgraph.ClassGraph;
+import io.github.classgraph.ModuleRef;
+import io.github.classgraph.ScanResult;
+import jalview.gui.JvOptionPane;
+
+public class CommandLineOperationsNG
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  // Note longer timeout needed on full test run than on individual tests
+  private static final int TEST_TIMEOUT = 13000;
+
+  private static final int SETUP_TIMEOUT = 9500;
+
+  private static final int MINFILESIZE_SMALL = 2096;
+
+  private static final int MINFILESIZE_BIG = 4096;
+
+  private List<String> successfulCMDs = new ArrayList<>();
+
+  /***
+   * from
+   * http://stackoverflow.com/questions/808276/how-to-add-a-timeout-value-when
+   * -using-javas-runtime-exec
+   * 
+   * @author jimp
+   * 
+   */
+  private static class Worker extends Thread
+  {
+    private final Process process;
+
+    private BufferedReader outputReader;
+
+    private BufferedReader errorReader;
+
+    private Integer exit;
+
+    private Worker(Process process)
+    {
+      this.process = process;
+    }
+
+    @Override
+    public void run()
+    {
+      try
+      {
+        exit = process.waitFor();
+      } catch (InterruptedException ignore)
+      {
+        return;
+      }
+    }
+
+    public BufferedReader getOutputReader()
+    {
+      return outputReader;
+    }
+
+    public void setOutputReader(BufferedReader outputReader)
+    {
+      this.outputReader = outputReader;
+    }
+
+    public BufferedReader getErrorReader()
+    {
+      return errorReader;
+    }
+
+    public void setErrorReader(BufferedReader errorReader)
+    {
+      this.errorReader = errorReader;
+    }
+  }
+
+  private static ClassGraph scanner = null;
+
+  private static String classpath = null;
+
+  private static String modules = null;
+
+  private static String java_exe = null;
+
+  public synchronized static String getClassPath()
+  {
+    if (scanner == null)
+    {
+      scanner = new ClassGraph();
+      ScanResult scan = scanner.scan();
+      classpath = scan.getClasspath();
+      modules = "";
+      for (ModuleRef mr : scan.getModules())
+      {
+        modules.concat(mr.getName());
+      }
+      java_exe = System.getProperty("java.home") + File.separator + "bin"
+              + File.separator + "java";
+
+    }
+
+    while (classpath == null)
+    {
+      try
+      {
+        Thread.sleep(10);
+      } catch (InterruptedException x)
+      {
+
+      }
+    }
+    return classpath;
+  }
+
+  private Worker getJalviewDesktopRunner(boolean withAwt, String cmd,
+          int timeout)
+  {
+    return getJalviewDesktopRunner(withAwt, cmd, timeout, true);
+  }
+
+  private Worker getJalviewDesktopRunner(boolean withAwt, String cmd,
+          int timeout, boolean testoutput)
+  {
+    /*
+    boolean win = System.getProperty("os.name").indexOf("Win") >= 0;
+    String pwd = "";
+    try
+    {
+      Path currentRelativePath = Paths.get("");
+      pwd = currentRelativePath.toAbsolutePath().toString();
+    } catch (Exception q)
+    {
+      q.printStackTrace();
+    }
+    if (pwd == null || pwd.length() == 0)
+      pwd = ".";
+    String[] classpaths = new String[] { pwd + "/bin/main",
+        pwd + "/j11lib/*", pwd + "/resources", pwd + "/help" };
+    String classpath = String.join(win ? ";" : ":", classpaths);
+    getClassPath();
+    */
+    // Note: JAL-3065 - don't include quotes for lib/* because the arguments are
+    // not expanded by the shell
+    String classpath = getClassPath();
+    String _cmd = java_exe + " "
+            + (withAwt ? "-Djava.awt.headless=true" : "") + " -classpath "
+            + classpath
+            + ((modules != null && modules.length() > 2)
+                    ? "--add-modules=\"" + modules + "\""
+                    : "")
+            + " jalview.bin.Jalview ";
+    Process ls2_proc = null;
+    Worker worker = null;
+    try
+    {
+      cmd = cmd + (testoutput ? " --testoutput " : "");
+      System.out.println("Running '" + _cmd + cmd + "'");
+      ls2_proc = Runtime.getRuntime().exec(_cmd + cmd);
+    } catch (Throwable e1)
+    {
+      e1.printStackTrace();
+    }
+    if (ls2_proc != null)
+    {
+      BufferedReader outputReader = new BufferedReader(
+              new InputStreamReader(ls2_proc.getInputStream()));
+      BufferedReader errorReader = new BufferedReader(
+              new InputStreamReader(ls2_proc.getErrorStream()));
+      worker = new Worker(ls2_proc);
+      worker.start();
+      try
+      {
+        worker.join(timeout);
+      } catch (InterruptedException e)
+      {
+        System.err.println("Thread interrupted");
+      }
+      worker.setOutputReader(outputReader);
+      worker.setErrorReader(errorReader);
+    }
+    return worker;
+  }
+
+  @Test(groups = { "Functional", "testTask1" })
+  public void reportCurrentWorkingDirectory()
+  {
+    try
+    {
+      Path currentRelativePath = Paths.get("");
+      String s = currentRelativePath.toAbsolutePath().toString();
+      System.out.println("Test CWD is " + s);
+    } catch (Exception q)
+    {
+      q.printStackTrace();
+    }
+  }
+
+  @BeforeClass(alwaysRun = true)
+  public void initialize()
+  {
+    new CommandLineOperationsNG();
+  }
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpForHeadlessCommandLineInputOperations()
+          throws IOException
+  {
+    String cmds = "--headless " + "--open examples/uniref50.fa "
+            + "--sortbytree "
+            + "--props test/jalview/bin/testProps.jvprops "
+            + "--colour zappo "
+            + "--jabaws http://www.compbio.dundee.ac.uk/jabaws "
+            + "--features examples/testdata/plantfdx.features "
+            + "--annotations examples/testdata/plantfdx.annotations "
+            + "--tree examples/testdata/uniref50_test_tree "
+            + "--nousagestats ";
+    Worker worker = getJalviewDesktopRunner(true, cmds, SETUP_TIMEOUT);
+    String ln = null;
+    while ((ln = worker.getOutputReader().readLine()) != null)
+    {
+      System.out.println(ln);
+      successfulCMDs.add(ln);
+    }
+    while ((ln = worker.getErrorReader().readLine()) != null)
+    {
+      System.err.println(ln);
+    }
+  }
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpForCommandLineInputOperations() throws IOException
+  {
+    String cmds = "--open examples/uniref50.fa --noquestionnaire --nousagestats";
+    final Worker worker = getJalviewDesktopRunner(false, cmds,
+            SETUP_TIMEOUT);
+
+    // number of lines expected on STDERR when Jalview starts up normally
+    // may need to adjust this if Jalview is excessively noisy ?
+    final int STDERR_SETUPLINES = 50;
+
+    // thread monitors stderr - bails after SETUP_TIMEOUT or when
+    // STDERR_SETUPLINES have been read
+    Thread runner = new Thread(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        String ln = null;
+        int count = 0;
+        try
+        {
+          while ((ln = worker.getOutputReader().readLine()) != null)
+          {
+            System.out.println(ln);
+            successfulCMDs.add(ln);
+            if (++count > STDERR_SETUPLINES)
+            {
+              break;
+            }
+          }
+        } catch (Exception e)
+        {
+          System.err.println(
+                  "Unexpected Exception reading stderr from the Jalview process");
+          e.printStackTrace();
+        }
+      }
+    });
+    long t = System.currentTimeMillis() + SETUP_TIMEOUT;
+    runner.start();
+    while (!runner.isInterrupted() && System.currentTimeMillis() < t)
+    {
+      try
+      {
+        Thread.sleep(500);
+      } catch (InterruptedException e)
+      {
+      }
+    }
+    runner.interrupt();
+    if (worker != null && worker.exit == null)
+    {
+      worker.interrupt();
+      Thread.currentThread().interrupt();
+      worker.process.destroy();
+    }
+  }
+
+  @Test(
+    groups =
+    { "Functional", "testTask1" },
+    dataProvider = "allInputOperationsData")
+  public void testAllInputOperations(String expectedString,
+          String failureMsg)
+  {
+    Assert.assertTrue(successfulCMDs.contains(expectedString),
+            failureMsg + "; was expecting '" + expectedString + "'");
+  }
+
+  @Test(
+    groups =
+    { "Functional", "testTask1" },
+    dataProvider = "headlessModeOutputOperationsData")
+  public void testHeadlessModeOutputOperations(String harg, String type,
+          String fileName, boolean withAWT, int expectedMinFileSize,
+          int timeout)
+  {
+    String cmd = harg + type + " " + fileName;
+    // System.out.println(">>>>>>>>>>>>>>>> Command : " + cmd);
+    File file = new File(fileName);
+    file.deleteOnExit();
+    Worker worker = getJalviewDesktopRunner(withAWT, cmd, timeout);
+    assertNotNull(worker, "worker is null");
+    String msg = "Didn't create an output" + type + " file '" + fileName
+            + "'. [" + cmd + "]";
+    assertTrue(file.exists(), msg);
+    FileAssert.assertFile(file, msg);
+    FileAssert.assertMinLength(file, expectedMinFileSize);
+    if (worker != null && worker.exit == null)
+    {
+      worker.interrupt();
+      Thread.currentThread().interrupt();
+      worker.process.destroy();
+      Assert.fail("Jalview did not exit after " + type
+              + " generation (try running test again to verify - timeout at "
+              + timeout + "ms). [" + harg + "]");
+    }
+    file.delete();
+  }
+
+  @Test(
+    groups =
+    { "Functional", "testTask1" },
+    dataProvider = "headlessModeOutputToStdout")
+  public void testHeadlessModeOutputToStdout(String args,
+          String comparisonFile, int timeout)
+  {
+    String cmd = args;
+    File file = new File(comparisonFile);
+    Worker worker = getJalviewDesktopRunner(true, cmd, timeout, false);
+    int b = -1;
+    StringBuilder sb = new StringBuilder();
+    try
+    {
+      while ((b = worker.getOutputReader().read()) != -1)
+      {
+        sb.append(Character.toChars(b));
+      }
+    } catch (IOException e)
+    {
+      Assert.fail("IOException whilst trying to read from jalview process");
+    }
+
+    String comparisonContent = null;
+    try
+    {
+      comparisonContent = new String(Files.readAllBytes(file.toPath()));
+    } catch (IOException e)
+    {
+      Assert.fail("IOException whilst trying to read comparison file");
+    }
+
+    Assert.assertEquals(sb.toString(), comparisonContent,
+            "STDOUT from jalview command did not match the comparison file");
+  }
+
+  @DataProvider(name = "allInputOperationsData")
+  public Object[][] getHeadlessModeInputParams()
+  {
+    return new Object[][] {
+        // headless mode input operations
+        { "[TESTOUTPUT] arg --colour='zappo' was set",
+            "Failed setting arg --colour" },
+        { "[TESTOUTPUT] arg --props='test/jalview/bin/testProps.jvprops' was set",
+            "Failed setting arg --props" },
+        { "[TESTOUTPUT] arg --sortbytree was set",
+            "Failed setting arg --sortbytree" },
+        { "[TESTOUTPUT] arg --jabaws='http://www.compbio.dundee.ac.uk/jabaws' was set",
+            "Failed setting arg --jabaws" },
+        { "[TESTOUTPUT] arg --open='examples/uniref50.fa' was set",
+            "Failed setting arg --open" },
+        { "[TESTOUTPUT] arg --features='examples/testdata/plantfdx.features' was set",
+            "Failed setting arg --features" },
+        { "[TESTOUTPUT] arg --annotations='examples/testdata/plantfdx.annotations' was set",
+            "Failed setting arg --annotations" },
+        { "[TESTOUTPUT] arg --tree='examples/testdata/uniref50_test_tree' was set",
+            "Failed setting arg --tree" },
+        // non headless mode input operations
+        { "[TESTOUTPUT] arg --nousagestats was set",
+            "Failed setting arg --nousagestats" },
+        { "[TESTOUTPUT] arg --noquestionnaire was set",
+            "Failed setting arg --noquestionnaire" }
+        //
+    };
+  }
+
+  @DataProvider(name = "headlessModeOutputOperationsData")
+  public static Object[][] getHeadlessModeOutputParams()
+  {
+    // JBPNote: I'm not clear why need to specify full path for output file
+    // when running tests on build server, but we will keep this patch for now
+    // since it works.
+    // https://issues.jalview.org/browse/JAL-1889?focusedCommentId=21609&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-21609
+    String workingDir = "test/jalview/bin/";
+    return new Object[][] {
+        //
+        { "--headless --open examples/uniref50.fa", " --image",
+            workingDir + "test_uniref50_out.eps", true, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --image",
+            workingDir + "test_uniref50_out.eps", false, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --image",
+            workingDir + "test_uniref50_out.eps", true, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --image",
+            workingDir + "test_uniref50_out.eps", false, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --image",
+            workingDir + "test_uniref50_out.eps", true, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --image",
+            workingDir + "test_uniref50_out.svg", false, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --image",
+            workingDir + "test_uniref50_out.png", true, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --image",
+            workingDir + "test_uniref50_out.html", true, MINFILESIZE_BIG,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --output",
+            workingDir + "test_uniref50_out.mfa", true, MINFILESIZE_SMALL,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --output",
+            workingDir + "test_uniref50_out.aln", true, MINFILESIZE_SMALL,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --output",
+            workingDir + "test_uniref50_out.msf", true, MINFILESIZE_SMALL,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --output",
+            workingDir + "test_uniref50_out.aln", true, MINFILESIZE_SMALL,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --output",
+            workingDir + "test_uniref50_out.pir", true, MINFILESIZE_SMALL,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --output",
+            workingDir + "test_uniref50_out.pfam", true, MINFILESIZE_SMALL,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --output",
+            workingDir + "test_uniref50_out.blc", true, MINFILESIZE_SMALL,
+            TEST_TIMEOUT },
+        { "--headless --open examples/uniref50.fa", " --output",
+            workingDir + "test_uniref50_out.jvp", true, MINFILESIZE_SMALL,
+            TEST_TIMEOUT },
+        //
+    };
+  }
+
+  @DataProvider(name = "headlessModeOutputToStdout")
+  public static Object[][] getHeadlessModeOutputToStdout()
+  {
+    // JBPNote: I'm not clear why need to specify full path for output file
+    // when running tests on build server, but we will keep this patch for now
+    // since it works.
+    // https://issues.jalview.org/browse/JAL-1889?focusedCommentId=21609&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-21609
+    String workingDir = "test/jalview/bin";
+    return new Object[][] {
+        //
+        { "--open=examples/uniref50.fa --output=-",
+            workingDir + "/uniref50-output.fa", TEST_TIMEOUT },
+        { "--open examples/uniref50.fa --output -",
+            workingDir + "/uniref50-output.fa", TEST_TIMEOUT },
+        { "--open examples/uniref50.fa --output=[format=blc]-",
+            workingDir + "/uniref50-output.blc", TEST_TIMEOUT },
+        { "--open examples/uniref50.fa --output - --format blc",
+            workingDir + "/uniref50-output.blc", TEST_TIMEOUT },
+        { "./examples/uniref50.fa --output=-",
+            workingDir + "/uniref50-output.fa", TEST_TIMEOUT },
+        { "./examples/uniref50.fa --output - --format blc",
+            workingDir + "/uniref50-output.blc", TEST_TIMEOUT },
+        // remember you can't use shell wildcards for filenames in a test
+        { "./test/jalview/bin/argparser/testfiles/test1.fa ./test/jalview/bin/argparser/testfiles/test2.fa ./test/jalview/bin/argparser/testfiles/test3.fa --all --output -",
+            workingDir + "/test1-3.fa", TEST_TIMEOUT },
+        // but you can use java wildcards when using an equals sign
+        { "--open=./test/jalview/bin/argparser/testfiles/test*.fa --all --output -",
+            workingDir + "/test1-3.fa", TEST_TIMEOUT },
+        //
+    };
+  }
+}
diff --git a/test/jalview/bin/CommandsTest.java b/test/jalview/bin/CommandsTest.java
new file mode 100644 (file)
index 0000000..fe40682
--- /dev/null
@@ -0,0 +1,502 @@
+package jalview.bin;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.util.ArrayUtils;
+
+public class CommandsTest
+{
+  private static final String testfiles = "test/jalview/bin/argparser/testfiles";
+
+  @BeforeClass(alwaysRun = true)
+  public static void setUpBeforeClass() throws Exception
+  {
+    Cache.loadProperties("test/jalview/gui/quitProps.jvprops");
+    Date oneHourFromNow = new Date(
+            System.currentTimeMillis() + 3600 * 1000);
+    Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED", oneHourFromNow);
+  }
+
+  @AfterClass(alwaysRun = true)
+  public static void resetProps()
+  {
+    Cache.loadProperties("test/jalview/testProps.jvprops");
+  }
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @AfterMethod(alwaysRun = true)
+  public void tearDown()
+  {
+    Desktop.closeDesktop();
+  }
+
+  public static void callJalviewMain(String[] args)
+  {
+    if (Jalview.getInstance() != null)
+    {
+      Jalview.getInstance().doMain(args);
+    }
+    else
+    {
+      Jalview.main(args);
+    }
+  }
+
+  /* --setprops is currently disabled so this test won't work
+  @Test(groups = "Functional")
+  public void setpropsTest()
+  {
+    final String MOSTLY_HARMLESS = "MOSTLY_HARMLESS";
+    String cmdLine = "--setprop=" + MOSTLY_HARMLESS + "=Earth";
+    String[] args = cmdLine.split("\\s+");
+    Jalview.main(args);
+    Assert.assertEquals(Cache.getDefault(MOSTLY_HARMLESS, "Magrathea"),
+            "Earth");
+  }
+  */
+
+  @Test(groups = "Functional", dataProvider = "cmdLines")
+  public void commandsOpenTest(String cmdLine, boolean cmdArgs,
+          int numFrames, String[] sequences)
+  {
+    try
+    {
+      String[] args = (cmdLine + " --gui").split("\\s+");
+      callJalviewMain(args);
+      Commands cmds = Jalview.getInstance().getCommands();
+      Assert.assertNotNull(cmds);
+      Assert.assertEquals(cmds.commandArgsProvided(), cmdArgs,
+              "Commands were not provided in the args");
+      Assert.assertEquals(cmds.argsWereParsed(), cmdArgs,
+              "Overall command parse and operation is false");
+
+      Assert.assertEquals(Desktop.getAlignFrames().length, numFrames,
+              "Wrong number of AlignFrames");
+
+      if (sequences != null)
+      {
+        Set<String> openedSequenceNames = new HashSet<>();
+        AlignFrame[] afs = Desktop.getAlignFrames();
+        for (AlignFrame af : afs)
+        {
+          openedSequenceNames.addAll(
+                  af.getViewport().getAlignment().getSequenceNames());
+        }
+        for (String sequence : sequences)
+        {
+          Assert.assertTrue(openedSequenceNames.contains(sequence),
+                  "Sequence '" + sequence
+                          + "' was not found in opened alignment files: "
+                          + cmdLine + ".\nOpened sequence names are:\n"
+                          + String.join("\n", openedSequenceNames));
+        }
+      }
+
+      Assert.assertFalse(
+              lookForSequenceName("THIS_SEQUENCE_ID_DOESN'T_EXIST"));
+    } catch (Exception x)
+    {
+      Assert.fail("Unexpected exception during commandsOpenTest", x);
+    } finally
+    {
+      tearDown();
+
+    }
+  }
+
+  @Test(
+    groups =
+    { "Functional", "testTask1" },
+    dataProvider = "structureImageOutputFiles")
+  public void structureImageOutputTest(String cmdLine, String[] filenames)
+          throws IOException
+  {
+    cleanupFiles(filenames);
+    String[] args = (cmdLine + " --gui").split("\\s+");
+    try
+    {
+      callJalviewMain(args);
+      Commands cmds = Jalview.getInstance().getCommands();
+      Assert.assertNotNull(cmds);
+      File lastFile = null;
+      for (String filename : filenames)
+      {
+        File file = new File(filename);
+        Assert.assertTrue(file.exists(), "File '" + filename
+                + "' was not created by '" + cmdLine + "'");
+        Assert.assertTrue(file.isFile(), "File '" + filename
+                + "' is not a file from '" + cmdLine + "'");
+        Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename
+                + "' has no content from '" + cmdLine + "'");
+        // make sure the successive output files get bigger!
+        if (lastFile != null)
+          Assert.assertTrue(Files.size(file.toPath()) > Files
+                  .size(lastFile.toPath()));
+      }
+    } catch (Exception x)
+    {
+      Assert.fail("Unexpected exception during structureImageOutputTest",
+              x);
+    } finally
+    {
+      cleanupFiles(filenames);
+      tearDown();
+    }
+  }
+
+  @Test(groups = "Functional", dataProvider = "argfileOutputFiles")
+  public void argFilesGlobAndSubstitutionsTest(String cmdLine,
+          String[] filenames) throws IOException
+  {
+    cleanupFiles(filenames);
+    String[] args = (cmdLine + " --gui").split("\\s+");
+    try
+    {
+      callJalviewMain(args);
+      Commands cmds = Jalview.getInstance().getCommands();
+      Assert.assertNotNull(cmds);
+      File lastFile = null;
+      for (String filename : filenames)
+      {
+        File file = new File(filename);
+        Assert.assertTrue(file.exists(), "File '" + filename
+                + "' was not created by '" + cmdLine + "'");
+        Assert.assertTrue(file.isFile(), "File '" + filename
+                + "' is not a file from '" + cmdLine + "'");
+        Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename
+                + "' has no content from '" + cmdLine + "'");
+        // make sure the successive output files get bigger!
+        if (lastFile != null)
+          Assert.assertTrue(Files.size(file.toPath()) > Files
+                  .size(lastFile.toPath()));
+      }
+    } catch (Exception x)
+    {
+      Assert.fail(
+              "Unexpected exception during argFilesGlobAndSubstitutions",
+              x);
+    } finally
+    {
+      cleanupFiles(filenames);
+      tearDown();
+    }
+  }
+
+  @DataProvider(name = "structureImageOutputFiles")
+  public Object[][] structureImageOutputFiles()
+  {
+    return new Object[][] {
+        //
+        { "--gui --nonews --nosplash --open=./examples/test_fab41.result/sample.a2m "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
+                + "--structureimage=" + testfiles + "/structureimage1.png "
+                + "--open=./examples/test_fab41.result/sample.a2m "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
+                + "--structureimage=" + testfiles
+                + "/structureimage2.png --structureimagescale=1.5"
+                + "--open=./examples/test_fab41.result/sample.a2m "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
+                + "--structureimage=" + testfiles
+                + "/structureimage3.png --structureimagescale=2.0",
+            new String[]
+            { testfiles + "/structureimage1.png",
+                testfiles + "/structureimage2.png",
+                testfiles + "/structureimage3.png" } },
+        { "--headless --noquit --open=./examples/test_fab41.result/sample.a2m "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
+                + "--structureimage=" + testfiles + "/structureimage1.png "
+                + "--open=./examples/test_fab41.result/sample.a2m "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
+                + "--structureimage=" + testfiles
+                + "/structureimage2.png --structureimagescale=1.5"
+                + "--open=./examples/test_fab41.result/sample.a2m "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
+                + "--structureimage=" + testfiles
+                + "/structureimage3.png --structureimagescale=2.0",
+            new String[]
+            { testfiles + "/structureimage1.png",
+                testfiles + "/structureimage2.png",
+                testfiles + "/structureimage3.png" } },
+        /*
+                */
+        //
+    };
+
+  }
+
+  @DataProvider(name = "argfileOutputFiles")
+  public Object[][] argfileOutputFiles()
+  {
+    return new Object[][] {
+        //
+        { "--gui --argfile=" + testfiles + "/**/*.txt", new String[]
+        { testfiles + "/dir1/test1.png", testfiles + "/dir2/test1.png",
+            testfiles + "/dir3/subdir/test0.png" } },
+        { "--gui --argfile=" + testfiles + "/**/argfile.txt", new String[]
+        { testfiles + "/dir1/test1.png", testfiles + "/dir2/test1.png" } },
+        { "--gui --argfile=" + testfiles + "/dir*/argfile.txt", new String[]
+        { testfiles + "/dir1/test1.png", testfiles + "/dir2/test1.png" } },
+        { "--gui --initsubstitutions --append examples/uniref50.fa --image "
+                + testfiles + "/{basename}.png",
+            new String[]
+            { testfiles + "/uniref50.png" } },
+        { "--gui --append examples/uniref50.fa --nosubstitutions --image "
+                + testfiles + "/{basename}.png",
+            new String[]
+            { testfiles + "/{basename}.png" } }
+        //
+    };
+
+  }
+
+  @DataProvider(name = "cmdLines")
+  public Object[][] cmdLines()
+  {
+    String[] someUniref50Seqs = new String[] { "FER_CAPAA", "FER_CAPAN",
+        "FER1_MAIZE", "FER1_SPIOL", "O80429_MAIZE" };
+    String[] t1 = new String[] { "TEST1" };
+    String[] t2 = new String[] { "TEST2" };
+    String[] t3 = new String[] { "TEST3" };
+    return new Object[][] {
+        /*
+        */
+        { "--append=examples/uniref50.fa", true, 1, someUniref50Seqs },
+        { "--append examples/uniref50.fa", true, 1, someUniref50Seqs },
+        { "--append=examples/uniref50*.fa", true, 1, someUniref50Seqs },
+        // NOTE we cannot use shell expansion in tests, so list all files!
+        { "--append examples/uniref50.fa examples/uniref50_mz.fa", true, 1,
+            someUniref50Seqs },
+        { "--append=[new]examples/uniref50*.fa", true, 2,
+            someUniref50Seqs },
+        { "--open=examples/uniref50*.fa", true, 2, someUniref50Seqs },
+        { "examples/uniref50.fa", true, 1, someUniref50Seqs },
+        { "examples/uniref50.fa " + testfiles + "/test1.fa", true, 2,
+            ArrayUtils.concatArrays(someUniref50Seqs, t1) },
+        { "examples/uniref50.fa " + testfiles + "/test1.fa", true, 2, t1 },
+        { "--gui --argfile=" + testfiles + "/argfile0.txt", true, 1,
+            ArrayUtils.concatArrays(t1, t3) },
+        { "--gui --argfile=" + testfiles + "/argfile*.txt", true, 5,
+            ArrayUtils.concatArrays(t1, t2, t3) },
+        { "--gui --argfile=" + testfiles + "/argfile.autocounter", true, 3,
+            ArrayUtils.concatArrays(t1, t2) } };
+
+  }
+
+  public static boolean lookForSequenceName(String sequenceName)
+  {
+    AlignFrame[] afs = Desktop.getAlignFrames();
+    for (AlignFrame af : afs)
+    {
+      for (String name : af.getViewport().getAlignment().getSequenceNames())
+      {
+        if (sequenceName.equals(name))
+        {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public static void cleanupFiles(String[] filenames)
+  {
+    for (String filename : filenames)
+    {
+      File file = new File(filename);
+      if (file.exists())
+      {
+        file.delete();
+      }
+    }
+  }
+
+  @Test(
+    groups = "Functional",
+    dataProvider = "allLinkedIdsData",
+    singleThreaded = true)
+  public void allLinkedIdsTest(String cmdLine, String[] filenames,
+          String[] nonfilenames)
+  {
+    String[] args = (cmdLine + " --gui").split("\\s+");
+    callJalviewMain(args);
+    Commands cmds = Jalview.getInstance().getCommands();
+    Assert.assertNotNull(cmds);
+    for (String filename : filenames)
+    {
+      Assert.assertTrue(new File(filename).exists(),
+              "File '" + filename + "' was not created");
+    }
+    cleanupFiles(filenames);
+    if (nonfilenames != null)
+    {
+      for (String nonfilename : nonfilenames)
+      {
+        File nonfile = new File(nonfilename);
+        Assert.assertFalse(nonfile.exists(),
+                "File " + nonfilename + " exists when it shouldn't!");
+      }
+    }
+  }
+
+  @DataProvider(name = "allLinkedIdsData")
+  public Object[][] allLinkedIdsData()
+  {
+    return new Object[][] {
+        //
+        /*
+         */
+        { "--gui --open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --output={dirname}/{basename}.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk", },
+            null },
+        { "--gui --open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.png",
+                "test/jalview/bin/argparser/testfiles/test2.png",
+                "test/jalview/bin/argparser/testfiles/test3.png", },
+            null },
+        { "--gui --open=test/jalview/bin/argparser/testfiles/*.fa --all --output={dirname}/{basename}.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", }, },
+        { "--gui --open=test/jalview/bin/argparser/**/*.fa --all --output={dirname}/{basename}.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", },
+            null },
+        { "--gui --open=test/jalview/bin/argparser/**/*.fa --output=*.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", },
+            null },
+        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output=*.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", }, },
+        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output=open*.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", }, },
+        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --opened --output={dirname}/{basename}.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", }, },
+        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --output open*.stk --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output=open*.aln --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.aln",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.aln",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.aln", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk",
+                "test/jalview/bin/argparser/testfiles/test1.aln",
+                "test/jalview/bin/argparser/testfiles/test2.aln",
+                "test/jalview/bin/argparser/testfiles/test3.aln",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.aln",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.aln",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.aln",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.aln",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.aln",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.aln", }, },
+        //
+    };
+  }
+
+}
diff --git a/test/jalview/bin/CommandsTest2.java b/test/jalview/bin/CommandsTest2.java
new file mode 100644 (file)
index 0000000..d6b6f3c
--- /dev/null
@@ -0,0 +1,212 @@
+package jalview.bin;
+
+import java.util.Date;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jalview.api.AlignViewportI;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.gui.StructureViewerBase;
+
+@Test
+public class CommandsTest2
+{
+  @BeforeClass(alwaysRun = true)
+  public static void setUpBeforeClass() throws Exception
+  {
+    Cache.loadProperties("test/jalview/bin/commandsTest.jvprops");
+    Date oneHourFromNow = new Date(
+            System.currentTimeMillis() + 3600 * 1000);
+    Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED", oneHourFromNow);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
+
+  }
+
+  @AfterClass(alwaysRun = true)
+  public static void resetProps()
+  {
+    Cache.loadProperties("test/jalview/testProps.jvprops");
+  }
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @AfterMethod(alwaysRun = true)
+  public void tearDown()
+  {
+    Desktop.closeDesktop();
+  }
+
+  @Test(
+    groups =
+    { "Functional", "testTask1" },
+    dataProvider = "structureOpeningArgsParams",
+    singleThreaded = true)
+  public void structureOpeningArgsTest(String cmdLine, int seqNum,
+          int annNum, int viewerNum)
+  {
+    String[] args = cmdLine.split("\\s+");
+
+    CommandsTest.callJalviewMain(args);
+    while (Desktop.instance!=null && Desktop.instance.operationsAreInProgress())
+    {
+      try
+      {
+        // sleep for slow build server to open annotations and viewer windows
+        Thread.sleep(viewerNum * 50);
+      } catch (InterruptedException e)
+      {
+        e.printStackTrace();
+      }
+    }
+    ;
+
+    AlignFrame[] afs = Desktop.getAlignFrames();
+    Assert.assertNotNull(afs);
+    Assert.assertTrue(afs.length > 0);
+
+    AlignFrame af = afs[0];
+    Assert.assertNotNull(af);
+
+    AlignmentPanel ap = af.alignPanel;
+    Assert.assertNotNull(ap);
+
+    AlignmentI al = ap.getAlignment();
+    Assert.assertNotNull(al);
+
+    List<SequenceI> seqs = al.getSequences();
+    Assert.assertNotNull(seqs);
+
+    Assert.assertEquals(seqs.size(), seqNum, "Wrong number of sequences");
+
+    AlignViewportI av = ap.getAlignViewport();
+    Assert.assertNotNull(av);
+
+    AlignmentAnnotation[] aas = al.getAlignmentAnnotation();
+    int visibleAnn = 0;
+    int dcount = 0;
+    for (AlignmentAnnotation aa : aas)
+    {
+      if (aa.visible)
+        visibleAnn++;
+    }
+
+    Assert.assertEquals(visibleAnn, annNum,
+            "Wrong number of visible annotations");
+
+    if (viewerNum > -1)
+    {
+      List<StructureViewerBase> openViewers = Desktop.instance
+              .getStructureViewers(ap, null);
+      Assert.assertNotNull(openViewers);
+      int count = 0;
+      for (StructureViewerBase svb : openViewers)
+      {
+        if (svb.isVisible())
+          count++;
+      }
+      Assert.assertEquals(count, viewerNum,
+              "Wrong number of structure viewers opened");
+    }
+  }
+
+  @DataProvider(name = "structureOpeningArgsParams")
+  public Object[][] structureOpeningArgsParams()
+  {
+    /*
+      String cmdLine,
+      int seqNum,
+      int annNum,
+      int structureViewerNum,
+     */
+    return new Object[][] {
+        //
+        /*
+         */
+        { "--gui --nonews --nosplash --debug "
+                + "--append=examples/uniref50.fa "
+                + "--colour=gecos-flower "
+                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
+                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
+                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
+            15, 7, 1 },
+        { "--gui --nonews --nosplash --debug "
+                + "--append=examples/uniref50.fa "
+                + "--colour=gecos-flower "
+                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
+                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
+                + "--props=test/jalview/bin/commandsTest2.jvprops2 ",
+            15, 4, 1 },
+        { "--gui --nonews --nosplash --debug "
+                + "--append=examples/uniref50.fa "
+                + "--colour=gecos-flower "
+                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
+                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
+                + "--noshowssannotations "
+                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
+            15, 4, 1 },
+        { "--gui --nonews --nosplash --debug "
+                + "--append=examples/uniref50.fa "
+                + "--colour=gecos-flower "
+                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
+                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
+                + "--noshowannotations "
+                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
+            15, 3, 1 },
+        { "--gui --nonews --nosplash --debug "
+                + "--append=examples/uniref50.fa "
+                + "--colour=gecos-flower "
+                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
+                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
+                + "--noshowannotations " + "--noshowssannotations "
+                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
+            15, 0, 1 },
+        { "--gui --nonews --nosplash --debug "
+                + "--append=examples/uniref50.fa "
+                + "--colour=gecos-flower "
+                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
+                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
+                + "--noshowannotations " + "--noshowssannotations "
+                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
+            15, 0, 1 },
+        { "--gui --nonews --nosplash --debug --nowebservicediscovery --props=test/jalview/bin/commandsTest.jvprops --argfile=test/jalview/bin/commandsTest2.argfile1 ",
+            16, 19, 3 },
+        { "--gui --nonews --nosplash --debug --nowebservicediscovery --props=test/jalview/bin/commandsTest.jvprops --argfile=test/jalview/bin/commandsTest2.argfile2 ",
+            16, 0, 2 },
+        { "--gui --nonews --nosplash --debug --nowebservicediscovery --props=test/jalview/bin/commandsTest.jvprops --open=./examples/test_fab41.result/sample.a2m "
+                + "--allstructures "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
+                + "--structureviewer=none "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb",
+            16, 10, 0 },
+        { "--gui --nonews --nosplash --debug --nowebservicediscovery --props=test/jalview/bin/commandsTest.jvprops --open=./examples/test_fab41.result/sample.a2m "
+                + "--allstructures "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
+                + "--noallstructures " + "--structureviewer=none "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb "
+                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb",
+            16, 10, 2 },
+        /*
+         */
+        //
+    };
+  }
+}
index 137d3e1..49a721f 100644 (file)
@@ -32,6 +32,7 @@ import jalview.gui.Desktop;
 import jalview.gui.JvOptionPane;
 import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
+import jalview.util.Platform;
 
 /*
  * Testing a HiDPI display is difficult without running in a HiDPI display.
@@ -84,7 +85,8 @@ public class HiDPISettingTest1
   @AfterClass(alwaysRun = true)
   public void tearDown()
   {
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" })
@@ -107,20 +109,22 @@ public class HiDPISettingTest1
       setMockScreen(1920, 1080, 96);
       assertEquals(HiDPISetting.getScalePropertyArg(), null);
 
+      // currently HiDPISetting only operates for Linux
+
       // 4K screen -- scale by 2
       setMockScreen(3180, 2160, 80);
       assertEquals(HiDPISetting.getScalePropertyArg(),
-              "-D" + scalePropertyName + "=2");
+              Platform.isLinux() ? "-D" + scalePropertyName + "=2" : null);
 
       // 4K screen with high dpi -- scale by 3
       setMockScreen(3180, 2160, 450);
       assertEquals(HiDPISetting.getScalePropertyArg(),
-              "-D" + scalePropertyName + "=3");
+              Platform.isLinux() ? "-D" + scalePropertyName + "=3" : null);
 
       // stupidly big screen -- scale by 8
       setMockScreen(19200, 10800, 72);
       assertEquals(HiDPISetting.getScalePropertyArg(),
-              "-D" + scalePropertyName + "=8");
+              Platform.isLinux() ? "-D" + scalePropertyName + "=8" : null);
     }
   }
 
diff --git a/test/jalview/bin/argparser/ArgParserTest.java b/test/jalview/bin/argparser/ArgParserTest.java
new file mode 100644 (file)
index 0000000..9beba17
--- /dev/null
@@ -0,0 +1,417 @@
+package jalview.bin.argparser;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jalview.bin.Cache;
+import jalview.gui.Desktop;
+
+@Test(singleThreaded = true)
+public class ArgParserTest
+{
+  @AfterClass(alwaysRun = true)
+  public static void resetProps()
+  {
+    Cache.loadProperties("test/jalview/testProps.jvprops");
+  }
+
+  @AfterMethod(alwaysRun = true)
+  public void tearDown()
+  {
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
+  }
+
+  @Test(groups = "Functional", dataProvider = "argLines")
+  public void parseArgsTest(String commandLineArgs, Arg a, String other)
+  {
+    String[] args = commandLineArgs.split("\\s+");
+    ArgParser argparser = new ArgParser(args);
+  }
+
+  @Test(groups = "Functional", dataProvider = "argSubValsAndLinkedIds")
+  public void parseSubValsAndLinkedIdsTest(String commandLineArgs,
+          String linkedId, Arg a, String subvalKey, String value,
+          boolean trueOrFalse)
+  {
+    String[] args = commandLineArgs.split("\\s+");
+    ArgParser argparser = new ArgParser(args);
+    ArgValuesMap avm = argparser.getLinkedArgs(linkedId);
+    ArgValue av = avm.getArgValue(a);
+    SubVals sv = av.getSubVals();
+    String testString = null;
+    if (subvalKey.equals("GETINDEX"))
+    {
+      testString = String.valueOf(sv.getIndex());
+    }
+    else
+    {
+      testString = sv.get(subvalKey);
+    }
+    if (trueOrFalse)
+    {
+      Assert.assertEquals(testString, value);
+    }
+    else
+    {
+      Assert.assertNotEquals(testString, value);
+    }
+  }
+
+  @Test(
+    groups = "Functional",
+    dataProvider = "argAutoIndexAndSubstitutions")
+  public void parseAutoIndexAndSubstitutionsTest(String commandLineArgs,
+          String linkedId, Arg a, String filename)
+  {
+    // { "--append=filename0 --new --append=filename1", "JALVIEW:1",
+    // Arg.OPEN, "filename1" },
+    String[] args = commandLineArgs.split("\\s+");
+    ArgParser argparser = new ArgParser(args);
+    ArgValuesMap avm = argparser.getLinkedArgs(linkedId);
+    ArgValue av = avm.getArgValue(a);
+    Assert.assertEquals(av.getValue(), filename);
+  }
+
+  @Test(groups = "Functional", dataProvider = "argLines")
+  public void bootstrapArgsTest(String commandLineArgs, Arg a, String other)
+  {
+    String[] args = commandLineArgs.split("\\s+");
+    BootstrapArgs b = BootstrapArgs.getBootstrapArgs(args);
+
+    Assert.assertTrue(b.contains(a));
+    if (a == Arg.PROPS)
+    {
+      Properties bP = Cache.bootstrapProperties(b.getValue(Arg.PROPS));
+      Assert.assertNotNull(bP);
+      Assert.assertTrue(other.equals(bP.get(Cache.BOOTSTRAP_TEST)));
+      Assert.assertFalse(bP.contains("NOT" + Cache.BOOTSTRAP_TEST));
+    }
+    else if (a == Arg.ARGFILE)
+    {
+      List<String> filenames = b.getValueList(a);
+      boolean found = false;
+      for (String s : filenames)
+      {
+        File f = new File(s);
+        File fo = new File(other);
+        try
+        {
+          if (fo.getCanonicalPath().equals(f.getCanonicalPath()))
+          {
+            found = true;
+            break;
+          }
+        } catch (IOException e)
+        {
+        }
+      }
+      Assert.assertTrue(found,
+              "File '" + other + "' not found in shell expanded glob '"
+                      + commandLineArgs + "'");
+    }
+  }
+
+  @Test(groups = "Functional", dataProvider = "argFiles")
+  public void argFilesTest(String commandLineArgs, Arg a, String other)
+  {
+    String[] args = commandLineArgs.split("\\s+");
+    BootstrapArgs b = BootstrapArgs.getBootstrapArgs(args);
+
+    Assert.assertTrue(b.contains(a));
+    Assert.assertFalse(b.contains(Arg.APPEND));
+    if (a == Arg.PROPS)
+    {
+      Properties bP = Cache.bootstrapProperties(b.getValue(Arg.PROPS));
+      Assert.assertTrue("true".equals(bP.get(Cache.BOOTSTRAP_TEST)));
+    }
+  }
+
+  @DataProvider(name = "argLinesNotworking")
+  public Object[][] argLinesTest()
+  {
+    return new Object[][] {
+        // can't use this one yet as it doesn't get shell glob expanded by the
+        // test
+        { "--argfile test/jalview/bin/argparser/testfiles/argfile*.txt",
+            Arg.ARGFILE,
+            "test/jalview/bin/argparser/testfiles/argfile0.txt" }, };
+  }
+
+  @DataProvider(name = "argLines")
+  public Object[][] argLines()
+  {
+    return new Object[][] { {
+        "--append=test/jalview/bin/argparser/testfiles/test1.fa --props=test/jalview/bin/argparser/testfiles/testProps.jvprops",
+        Arg.PROPS, "true" },
+        { "--debug --append=test/jalview/bin/argparser/testfiles/test1.fa",
+            Arg.DEBUG, null },
+        { "--append=test/jalview/bin/argparser/testfiles/test1.fa --headless",
+            Arg.HEADLESS, null },
+
+        { "--argfile test/jalview/bin/argparser/testfiles/argfile0.txt",
+            Arg.ARGFILE,
+            "test/jalview/bin/argparser/testfiles/argfile0.txt" },
+        // these next three are what a shell glob expansion would look like
+        { "--argfile test/jalview/bin/argparser/testfiles/argfile0.txt test/jalview/bin/argparser/testfiles/argfile1.txt test/jalview/bin/argparser/testfiles/argfile2.txt",
+            Arg.ARGFILE,
+            "test/jalview/bin/argparser/testfiles/argfile0.txt" },
+        { "--argfile test/jalview/bin/argparser/testfiles/argfile0.txt test/jalview/bin/argparser/testfiles/argfile1.txt test/jalview/bin/argparser/testfiles/argfile2.txt",
+            Arg.ARGFILE,
+            "test/jalview/bin/argparser/testfiles/argfile1.txt" },
+        { "--argfile test/jalview/bin/argparser/testfiles/argfile0.txt test/jalview/bin/argparser/testfiles/argfile1.txt test/jalview/bin/argparser/testfiles/argfile2.txt",
+            Arg.ARGFILE,
+            "test/jalview/bin/argparser/testfiles/argfile2.txt" },
+        { "--argfile=test/jalview/bin/argparser/testfiles/argfile*.txt",
+            Arg.ARGFILE,
+            "test/jalview/bin/argparser/testfiles/argfile0.txt" },
+        { "--argfile=test/jalview/bin/argparser/testfiles/argfile*.txt",
+            Arg.ARGFILE,
+            "test/jalview/bin/argparser/testfiles/argfile1.txt" },
+        { "--argfile=test/jalview/bin/argparser/testfiles/argfile*.txt",
+            Arg.ARGFILE,
+            "test/jalview/bin/argparser/testfiles/argfile2.txt" } };
+  }
+
+  @DataProvider(name = "argSubValsAndLinkedIds")
+  public Object[][] argSubValsAndLinkedIds()
+  {
+    return new Object[][] {
+        //
+        /*
+         */
+        { "--debug --append=[hi]test/jalview/bin/argparser/testfiles/test1.fa",
+            "JALVIEW:0", Arg.APPEND, "hi", "true", true },
+        { "--append[linkedId1]=[new,hello=world,1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
+            "linkedId1", Arg.APPEND, "new", "true", true },
+        { "--append[linkedId2]=[new,hello=world,1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
+            "linkedId2", Arg.APPEND, "hello", "world", true },
+        { "--append[linkedId3]=[new,hello=world,1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
+            "linkedId3", Arg.APPEND, "GETINDEX", "1", true },
+        { "--append[linkedId4]=[new,hello=world,1]test/jalview/bin/argparser/testfiles/test1.fa --append[linkedId5]=[notnew;hello=world;1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
+            "linkedId5", Arg.APPEND, "new", "true", false },
+        { "--append[linkedId5]=[new,hello=worlddomination,1]test/jalview/bin/argparser/testfiles/test1.fa --append[linkedId2]=[new;hello=world;1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
+            "linkedId5", Arg.APPEND, "hello", "world", false },
+        { "--append[linkedId6]=[new,hello=world,0]test/jalview/bin/argparser/testfiles/test1.fa --append[linkedId7]=[new;hello=world;1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
+            "linkedId7", Arg.APPEND, "GETINDEX", "0", false },
+        /*
+         */
+        //
+    };
+  }
+
+  @DataProvider(name = "argAutoIndexAndSubstitutions")
+  public Object[][] argAutoIndexAndSubstitutions()
+  {
+    return new Object[][] {
+        //
+        /*
+         */
+        { "--append=filename0 --append=filename1", "JALVIEW:0", Arg.APPEND,
+            "filename0" },
+        { "--append=filename0 --new --append=filename1", "JALVIEW:1",
+            Arg.APPEND, "filename1" },
+        { "--append=filename0 --new --new --append=filename2", "JALVIEW:0",
+            Arg.APPEND, "filename0" },
+        { "--append=filename0 --new --new --append=filename2", "JALVIEW:2",
+            Arg.APPEND, "filename2" },
+        { "--append[linkA-{n}]=filenameA0 --append[linkA-{++n}]=filenameA1",
+            "linkA-0", Arg.APPEND, "filenameA0" },
+        { "--append[linkB-{n}]=filenameB0 --append[linkB-{++n}]=filenameB1",
+            "linkB-1", Arg.APPEND, "filenameB1" },
+        { "--append[linkC-{n}]=filenameC0 --image[linkC-{n}]=outputC{n}.txt",
+            "linkC-0", Arg.IMAGE, "outputC{n}.txt" },
+        { "--append[linkD-{n}]=filenameD0 --substitutions --image[linkD-{n}]=outputD{n}.txt",
+            "linkD-0", Arg.IMAGE, "outputD0.txt" },
+        { "--append[linkE-{n}]=filenameE0 --substitutions --image[linkE-{n}]=output-E{n}.txt --nil[{++n}] --image[linkE-{n}]=outputE{n}.txt",
+            "linkE-0", Arg.IMAGE, "output-E0.txt" },
+        { "--append[linkF-{n}]=filenameF0 --substitutions --image[linkF-{n}]=output-F{n}.txt --nil[{++n}] --image[linkF-{n}]=outputF{n}.txt",
+            "linkF-1", Arg.IMAGE, "outputF1.txt" },
+        { "--append[linkG-{n}]=filenameG0 --substitutions --image[linkG-{n}]=output-G{n}.txt --nil[{++n}] --nosubstitutions --image[linkG-{n}]=outputG{n}.txt",
+            "linkG-1", Arg.IMAGE, "outputG{n}.txt" },
+        { "--append[linkH-{n}]=filenameH0 --substitutions --image[linkH-{n}]=output-H{n}.txt --nil[{++n}] --nosubstitutions --image[linkH-{n}]=outputH{n}.txt",
+            "linkH-0", Arg.IMAGE, "output-H0.txt" },
+        { "--open=filename0 --append=filename1", "JALVIEW:0", Arg.OPEN,
+            "filename0" },
+        { "--open=filename0 --new --append=filename1", "JALVIEW:1",
+            Arg.APPEND, "filename1" },
+        { "--open=filename0 --new --new --append=filename2", "JALVIEW:0",
+            Arg.OPEN, "filename0" },
+        { "--open=filename0 --new --new --append=filename2", "JALVIEW:2",
+            Arg.APPEND, "filename2" },
+        { "--open[linkA-{n}]=filenameA0 --append[linkA-{++n}]=filenameA1",
+            "linkA-0", Arg.OPEN, "filenameA0" },
+        { "--open[linkB-{n}]=filenameB0 --append[linkB-{++n}]=filenameB1",
+            "linkB-1", Arg.APPEND, "filenameB1" },
+        { "--open[linkC-{n}]=filenameC0 --image[linkC-{n}]=outputC{n}.txt",
+            "linkC-0", Arg.IMAGE, "outputC{n}.txt" },
+        { "--open[linkD-{n}]=filenameD0 --substitutions --image[linkD-{n}]=outputD{n}.txt",
+            "linkD-0", Arg.IMAGE, "outputD0.txt" },
+        { "--open[linkE-{n}]=filenameE0 --substitutions --image[linkE-{n}]=output-E{n}.txt --nil[{++n}] --image[linkE-{n}]=outputE{n}.txt",
+            "linkE-0", Arg.IMAGE, "output-E0.txt" },
+        { "--open[linkF-{n}]=filenameF0 --substitutions --image[linkF-{n}]=output-F{n}.txt --nil[{++n}] --image[linkF-{n}]=outputF{n}.txt",
+            "linkF-1", Arg.IMAGE, "outputF1.txt" },
+        { "--open[linkG-{n}]=filenameG0 --substitutions --image[linkG-{n}]=output-G{n}.txt --nil[{++n}] --nosubstitutions --image[linkG-{n}]=outputG{n}.txt",
+            "linkG-1", Arg.IMAGE, "outputG{n}.txt" },
+        { "--open[linkH-{n}]=filenameH0 --substitutions --image[linkH-{n}]=output-H{n}.txt --nil[{++n}] --nosubstitutions --image[linkH-{n}]=outputH{n}.txt",
+            "linkH-0", Arg.IMAGE, "output-H0.txt" },
+        /*
+         */
+
+        //
+    };
+  }
+
+  @DataProvider(name = "argFiles")
+  public Object[][] argFiles()
+  {
+    return new Object[][] { {
+        "--argfile=test/jalview/bin/argparser/testfiles/argfile0.txt --open=shouldntbeabootstrap",
+        Arg.ARGFILE, "test/jalview/bin/argfiles/testfiles/test1.fa" } };
+  }
+
+  @Test(groups = "Functional", dataProvider = "allLinkedIdsData")
+  public void allLinkedIdsTest(String commandLineArgs, Arg a,
+          String[] values, String[] nonvalues)
+  {
+    String[] args = commandLineArgs.split("\\s+");
+    ArgParser argparser = new ArgParser(args);
+
+    int num = values.length;
+    List<String> linkedIds = argparser.getLinkedIds();
+    Assert.assertEquals(linkedIds.size(), num,
+            "Wrong number of linkedIds: " + linkedIds.toString());
+    for (int i = 0; i < num; i++)
+    {
+      String value = values[i];
+      String linkedId = linkedIds.get(i);
+      ArgValuesMap avm = argparser.getLinkedArgs(linkedId);
+      if (value == null)
+      {
+        Assert.assertTrue(avm.containsArg(a),
+                "Arg value for " + a.argString()
+                        + " not applied correctly to linkedId '" + linkedId
+                        + "'");
+      }
+      else
+      {
+        ArgValues avs = avm.getArgValues(a);
+        ArgValue av = avs.getArgValue();
+        String v = av.getValue();
+        value = new File(value).getAbsolutePath();
+        Assert.assertEquals(v, value, "Arg value for " + a.argString()
+                + " not applied correctly to linkedId '" + linkedId + "'");
+      }
+    }
+
+  }
+
+  @DataProvider(name = "allLinkedIdsData")
+  public Object[][] allLinkedIdsData()
+  {
+    return new Object[][] {
+        //
+        /*
+        */
+        { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
+            Arg.CLOSE, new String[]
+            { null, null, null },
+            null },
+        { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --output={dirname}/{basename}.stk --close",
+            Arg.OUTPUT, new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk", },
+            null },
+        { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
+            Arg.IMAGE, new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.png",
+                "test/jalview/bin/argparser/testfiles/test2.png",
+                "test/jalview/bin/argparser/testfiles/test3.png", },
+            null },
+        //
+    };
+  }
+
+  @Test(groups = "Functional", dataProvider = "bootstrapArgsData")
+  public void bootstrapArgsValuesAndHeadlessModeTest(String commandLineArgs,
+          Arg a, String valS, boolean valB, boolean headlessValue)
+  {
+    String[] args = commandLineArgs.split("\\s+");
+    BootstrapArgs bsa = BootstrapArgs.getBootstrapArgs(args);
+    if (a != null)
+    {
+      if (valS != null)
+      {
+        Assert.assertEquals(bsa.getValue(a), valS,
+                "BootstrapArg " + a.argString()
+                        + " value does not match expected '" + valS + "'");
+      }
+      else
+      {
+        Assert.assertEquals(bsa.getBoolean(a), valB,
+                "Boolean/Unary value of BootstrapArg " + a.argString()
+                        + "' is not the expected '" + valB + "'");
+      }
+    }
+
+    boolean isHeadless = bsa.isHeadless();
+    Assert.assertEquals(isHeadless, headlessValue,
+            "Assumed headless setting '" + isHeadless + "' is wrong.");
+  }
+
+  @DataProvider(name = "bootstrapArgsData")
+  public Object[][] bootstrapArgsData()
+  {
+    return new Object[][] {
+        /*
+         * cmdline args
+         * Arg (null if only testing headless)
+         * String value if there is one (null otherwise)
+         * boolean value if String value is null
+         * expected value of isHeadless()
+         */
+        /*
+        */
+        { "--open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
+            Arg.JABAWS, "https://forwardsandbackwards.com/", false, true },
+        { "--help-all --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
+            Arg.HELP, null, true, true },
+        { "--help-all --nonews --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
+            Arg.NEWS, null, false, true },
+        { "--help --nonews --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
+            Arg.NEWS, null, false, true },
+        { "--help-opening --nonews --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
+            Arg.NEWS, null, false, true },
+        { "--nonews --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
+            Arg.NEWS, null, false, true },
+        { "--open thisway.fa --image thatway.png", null, null, false,
+            true },
+        { "--open thisway.fa --output thatway.png", null, null, false,
+            true },
+        { "--open thisway.fa --image thatway.png --noheadless", null, null,
+            false, false },
+        { "--open thisway.fa --output thatway.png --noheadless", null, null,
+            false, false },
+        { "--open thisway.fa --image thatway.png --gui", null, null, false,
+            false },
+        { "--open thisway.fa --output thatway.png --gui", null, null, false,
+            false },
+        // --gui takes precedence
+        { "--open thisway.fa --image thatway.png --gui --headless", null,
+            null, false, false },
+        { "--open thisway.fa --output thatway.png --gui --headless", null,
+            null, false, false },
+        //
+    };
+  }
+
+}
diff --git a/test/jalview/bin/argparser/testfiles/argfile.autocounter b/test/jalview/bin/argparser/testfiles/argfile.autocounter
new file mode 100644 (file)
index 0000000..58445a5
--- /dev/null
@@ -0,0 +1,7 @@
+--open[{++n}]=test/jalview/bin/argparser/testfiles/test1.fa
+--colour[{n}]=gecos-flower
+--open[{++n}]=test/jalview/bin/argparser/testfiles/test2.fa
+--colour[{n}]=zappo
+--open[{++n}]=test/jalview/bin/argparser/testfiles/test1.fa
+--append[{n}]=test/jalview/bin/argparser/testfiles/test2.fa
+--colour[{n}]=taylor
diff --git a/test/jalview/bin/argparser/testfiles/argfile0.txt b/test/jalview/bin/argparser/testfiles/argfile0.txt
new file mode 100644 (file)
index 0000000..e8a8cdc
--- /dev/null
@@ -0,0 +1,2 @@
+--open=test/jalview/bin/argparser/testfiles/test1.fa
+--append=test/jalview/bin/argparser/testfiles/test3.fa
diff --git a/test/jalview/bin/argparser/testfiles/argfile1.txt b/test/jalview/bin/argparser/testfiles/argfile1.txt
new file mode 100644 (file)
index 0000000..e2d0fa4
--- /dev/null
@@ -0,0 +1,4 @@
+--open[all]=test/jalview/bin/argparser/testfiles/test1.fa
+--append[all]=test/jalview/bin/argparser/testfiles/test2.fa
+--open[1]=test/jalview/bin/argparser/testfiles/test1.fa
+--open[2]=test/jalview/bin/argparser/testfiles/test2.fa
diff --git a/test/jalview/bin/argparser/testfiles/argfile2.txt b/test/jalview/bin/argparser/testfiles/argfile2.txt
new file mode 100644 (file)
index 0000000..85ce3c2
--- /dev/null
@@ -0,0 +1 @@
+--open=test/jalview/bin/argparser/testfiles/test2.fa
diff --git a/test/jalview/bin/argparser/testfiles/dir1/argfile.txt b/test/jalview/bin/argparser/testfiles/dir1/argfile.txt
new file mode 100644 (file)
index 0000000..0e9ae50
--- /dev/null
@@ -0,0 +1,6 @@
+--substitutions
+--new
+--append={argfiledirname}/*.fa
+--colour=gecos-flower
+--image={argfiledirname}/{basename}.png
+--close
diff --git a/test/jalview/bin/argparser/testfiles/dir1/test1.fa b/test/jalview/bin/argparser/testfiles/dir1/test1.fa
new file mode 100644 (file)
index 0000000..c9e687f
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST1
+AAAA
diff --git a/test/jalview/bin/argparser/testfiles/dir1/test2.fa b/test/jalview/bin/argparser/testfiles/dir1/test2.fa
new file mode 100644 (file)
index 0000000..fbd15c3
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST2
+LLLL
diff --git a/test/jalview/bin/argparser/testfiles/dir2/argfile.txt b/test/jalview/bin/argparser/testfiles/dir2/argfile.txt
new file mode 100644 (file)
index 0000000..0e9ae50
--- /dev/null
@@ -0,0 +1,6 @@
+--substitutions
+--new
+--append={argfiledirname}/*.fa
+--colour=gecos-flower
+--image={argfiledirname}/{basename}.png
+--close
diff --git a/test/jalview/bin/argparser/testfiles/dir2/test1.fa b/test/jalview/bin/argparser/testfiles/dir2/test1.fa
new file mode 100644 (file)
index 0000000..c9e687f
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST1
+AAAA
diff --git a/test/jalview/bin/argparser/testfiles/dir2/test2.fa b/test/jalview/bin/argparser/testfiles/dir2/test2.fa
new file mode 100644 (file)
index 0000000..fbd15c3
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST2
+LLLL
diff --git a/test/jalview/bin/argparser/testfiles/dir2/test3.fa b/test/jalview/bin/argparser/testfiles/dir2/test3.fa
new file mode 100644 (file)
index 0000000..f9503d4
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST3
+AAARG
diff --git a/test/jalview/bin/argparser/testfiles/dir3/subdir/subdirfile.txt b/test/jalview/bin/argparser/testfiles/dir3/subdir/subdirfile.txt
new file mode 100644 (file)
index 0000000..0e9ae50
--- /dev/null
@@ -0,0 +1,6 @@
+--substitutions
+--new
+--append={argfiledirname}/*.fa
+--colour=gecos-flower
+--image={argfiledirname}/{basename}.png
+--close
diff --git a/test/jalview/bin/argparser/testfiles/dir3/subdir/test0.fa b/test/jalview/bin/argparser/testfiles/dir3/subdir/test0.fa
new file mode 100644 (file)
index 0000000..c9fae78
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST0
+AAAA
diff --git a/test/jalview/bin/argparser/testfiles/dir3/subdir/test1.fa b/test/jalview/bin/argparser/testfiles/dir3/subdir/test1.fa
new file mode 100644 (file)
index 0000000..c9e687f
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST1
+AAAA
diff --git a/test/jalview/bin/argparser/testfiles/dir3/subdir/test2.fa b/test/jalview/bin/argparser/testfiles/dir3/subdir/test2.fa
new file mode 100644 (file)
index 0000000..fbd15c3
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST2
+LLLL
diff --git a/test/jalview/bin/argparser/testfiles/dir3/subdir/test3.fa b/test/jalview/bin/argparser/testfiles/dir3/subdir/test3.fa
new file mode 100644 (file)
index 0000000..f9503d4
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST3
+AAARG
diff --git a/test/jalview/bin/argparser/testfiles/test1.fa b/test/jalview/bin/argparser/testfiles/test1.fa
new file mode 100644 (file)
index 0000000..c9e687f
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST1
+AAAA
diff --git a/test/jalview/bin/argparser/testfiles/test2.fa b/test/jalview/bin/argparser/testfiles/test2.fa
new file mode 100644 (file)
index 0000000..fbd15c3
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST2
+LLLL
diff --git a/test/jalview/bin/argparser/testfiles/test3.fa b/test/jalview/bin/argparser/testfiles/test3.fa
new file mode 100644 (file)
index 0000000..f9503d4
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST3
+AAARG
diff --git a/test/jalview/bin/argparser/testfiles/testProps.jvprops b/test/jalview/bin/argparser/testfiles/testProps.jvprops
new file mode 100644 (file)
index 0000000..8008953
--- /dev/null
@@ -0,0 +1,87 @@
+#---JalviewX Properties File---
+#Fri Apr 25 09:54:25 BST 2014
+SCREEN_Y=768
+SCREEN_X=936
+SHOW_WSDISCOVERY_ERRORS=true
+LATEST_VERSION=2.8.0b1
+SHOW_CONSERVATION=true
+JALVIEW_RSS_WINDOW_SCREEN_WIDTH=550
+JAVA_CONSOLE_SCREEN_WIDTH=450
+LAST_DIRECTORY=/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples
+ID_ITALICS=true
+SORT_ALIGNMENT=No sort
+SHOW_IDENTITY=true
+WSMENU_BYHOST=false
+SEQUENCE_LINKS=EMBL-EBI Search|http\://www.ebi.ac.uk/ebisearch/search.ebi?db\=allebi&query\=$SEQUENCE_ID$
+SHOW_FULLSCREEN=false
+RECENT_URL=http\://www.jalview.org/examples/exampleFile_2_7.jar
+FONT_NAME=SansSerif
+BLC_JVSUFFIX=true
+VERSION_CHECK=false
+YEAR=2011
+SHOW_DBREFS_TOOLTIP=true
+MSF_JVSUFFIX=true
+SCREENGEOMETRY_HEIGHT=1600
+JAVA_CONSOLE_SCREEN_Y=475
+JAVA_CONSOLE_SCREEN_X=830
+PFAM_JVSUFFIX=true
+PIR_JVSUFFIX=true
+STARTUP_FILE=http\://www.jalview.org/examples/exampleFile_2_3.jar
+JAVA_CONSOLE_SCREEN_HEIGHT=162
+PIR_MODELLER=false
+GAP_SYMBOL=-
+SHOW_QUALITY=true
+SHOW_GROUP_CONSERVATION=false
+SHOW_JWS2_SERVICES=true
+SHOW_NPFEATS_TOOLTIP=true
+FONT_STYLE=plain
+ANTI_ALIAS=false
+SORT_BY_TREE=false
+RSBS_SERVICES=|Multi-Harmony|Analysis|Sequence Harmony and Multi-Relief (Brandt et al. 2010)|hseparable,gapCharacter\='-',returns\='ANNOTATION'|?tool\=jalview|http\://zeus.few.vu.nl/programs/shmrwww/index.php?tool\=jalview&groups\=$PARTITION\:min\='2',minsize\='2',sep\=' '$&ali_file\=$ALIGNMENT\:format\='FASTA',writeasfile$
+AUTHORFNAMES=Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+JALVIEW_RSS_WINDOW_SCREEN_HEIGHT=328
+SHOW_GROUP_CONSENSUS=false
+SHOW_CONSENSUS_HISTOGRAM=true
+SHOW_OVERVIEW=false
+AUTHORS=J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+FIGURE_AUTOIDWIDTH=false
+SCREEN_WIDTH=900
+ANNOTATIONCOLOUR_MIN=ffc800
+SHOW_STARTUP_FILE=false
+RECENT_FILE=examples/uniref50.fa\t/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples/RF00031_folded.stk\t/Volumes/Data/Users/jimp/bs_ig_mult.out
+DEFAULT_FILE_FORMAT=FASTA
+SHOW_JAVA_CONSOLE=false
+VERSION=2.8b1
+FIGURE_USERIDWIDTH=
+WSMENU_BYTYPE=false
+DEFAULT_COLOUR=None
+NOQUESTIONNAIRES=true
+JALVIEW_NEWS_RSS_LASTMODIFIED=Apr 23, 2014 2\:53\:26 PM
+BUILD_DATE=01 November 2013
+PILEUP_JVSUFFIX=true
+SHOW_CONSENSUS_LOGO=false
+SCREENGEOMETRY_WIDTH=2560
+SHOW_ANNOTATIONS=true
+JALVIEW_RSS_WINDOW_SCREEN_Y=0
+USAGESTATS=false
+JALVIEW_RSS_WINDOW_SCREEN_X=0
+SHOW_UNCONSERVED=false
+SHOW_JVSUFFIX=true
+DAS_LOCAL_SOURCE=
+SCREEN_HEIGHT=650
+ANNOTATIONCOLOUR_MAX=ff0000
+AUTO_CALC_CONSENSUS=true
+FASTA_JVSUFFIX=true
+DAS_ACTIVE_SOURCE=uniprot\t
+JWS2HOSTURLS=http\://www.compbio.dundee.ac.uk/jabaws
+PAD_GAPS=false
+CLUSTAL_JVSUFFIX=true
+SHOW_ENFIN_SERVICES=true
+FONT_SIZE=10
+RIGHT_ALIGN_IDS=false
+USE_PROXY=false
+WRAP_ALIGNMENT=false
+#DAS_REGISTRY_URL=http\://www.dasregistry.org/das/ # retired 01/05/2015
+DAS_REGISTRY_URL=http\://www.ebi.ac.uk/das-srv/registry/das/
+BOOTSTRAP_TEST=true
+NOTBOOTSTRAP_TEST=true
diff --git a/test/jalview/bin/commandsTest.jvprops b/test/jalview/bin/commandsTest.jvprops
new file mode 100644 (file)
index 0000000..66e2780
--- /dev/null
@@ -0,0 +1,90 @@
+#---JalviewX Properties File---
+#Fri Apr 25 09:54:25 BST 2014
+SCREEN_Y=768
+SCREEN_X=936
+SHOW_WSDISCOVERY_ERRORS=true
+LATEST_VERSION=2.8.0b1
+JALVIEW_RSS_WINDOW_SCREEN_WIDTH=550
+JAVA_CONSOLE_SCREEN_WIDTH=450
+LAST_DIRECTORY=/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples
+ID_ITALICS=true
+SORT_ALIGNMENT=No sort
+WSMENU_BYHOST=false
+SEQUENCE_LINKS=EMBL-EBI Search|http\://www.ebi.ac.uk/ebisearch/search.ebi?db\=allebi&query\=$SEQUENCE_ID$
+SHOW_FULLSCREEN=false
+RECENT_URL=http\://www.jalview.org/examples/exampleFile_2_7.jar
+FONT_NAME=SansSerif
+BLC_JVSUFFIX=true
+VERSION_CHECK=false
+YEAR=2011
+SHOW_DBREFS_TOOLTIP=true
+MSF_JVSUFFIX=true
+SCREENGEOMETRY_HEIGHT=1600
+JAVA_CONSOLE_SCREEN_Y=475
+JAVA_CONSOLE_SCREEN_X=830
+PFAM_JVSUFFIX=true
+PIR_JVSUFFIX=true
+STARTUP_FILE=http\://www.jalview.org/examples/exampleFile_2_3.jar
+JAVA_CONSOLE_SCREEN_HEIGHT=162
+PIR_MODELLER=false
+GAP_SYMBOL=-
+SHOW_QUALITY=true
+SHOW_GROUP_CONSERVATION=false
+SHOW_JWS2_SERVICES=true
+SHOW_NPFEATS_TOOLTIP=true
+FONT_STYLE=plain
+ANTI_ALIAS=false
+SORT_BY_TREE=false
+RSBS_SERVICES=|Multi-Harmony|Analysis|Sequence Harmony and Multi-Relief (Brandt et al. 2010)|hseparable,gapCharacter\='-',returns\='ANNOTATION'|?tool\=jalview|http\://zeus.few.vu.nl/programs/shmrwww/index.php?tool\=jalview&groups\=$PARTITION\:min\='2',minsize\='2',sep\=' '$&ali_file\=$ALIGNMENT\:format\='FASTA',writeasfile$
+AUTHORFNAMES=Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+JALVIEW_RSS_WINDOW_SCREEN_HEIGHT=328
+SHOW_GROUP_CONSENSUS=false
+SHOW_CONSENSUS_HISTOGRAM=true
+SHOW_OVERVIEW=false
+AUTHORS=J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+FIGURE_AUTOIDWIDTH=false
+SCREEN_WIDTH=900
+ANNOTATIONCOLOUR_MIN=ffc800
+SHOW_STARTUP_FILE=false
+RECENT_FILE=examples/uniref50.fa\t/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples/RF00031_folded.stk\t/Volumes/Data/Users/jimp/bs_ig_mult.out
+DEFAULT_FILE_FORMAT=FASTA
+SHOW_JAVA_CONSOLE=false
+VERSION=2.8b1
+FIGURE_USERIDWIDTH=
+WSMENU_BYTYPE=false
+DEFAULT_COLOUR=None
+NOQUESTIONNAIRES=true
+JALVIEW_NEWS_RSS_LASTMODIFIED=Apr 23, 2014 2\:53\:26 PM
+BUILD_DATE=01 November 2013
+PILEUP_JVSUFFIX=true
+SHOW_CONSENSUS_LOGO=false
+SCREENGEOMETRY_WIDTH=2560
+JALVIEW_RSS_WINDOW_SCREEN_Y=0
+USAGESTATS=false
+JALVIEW_RSS_WINDOW_SCREEN_X=0
+SHOW_UNCONSERVED=false
+SHOW_JVSUFFIX=true
+DAS_LOCAL_SOURCE=
+SCREEN_HEIGHT=650
+ANNOTATIONCOLOUR_MAX=ff0000
+AUTO_CALC_CONSENSUS=true
+FASTA_JVSUFFIX=true
+DAS_ACTIVE_SOURCE=uniprot\t
+JWS2HOSTURLS=http\://www.compbio.dundee.ac.uk/jabaws
+PAD_GAPS=false
+CLUSTAL_JVSUFFIX=true
+SHOW_ENFIN_SERVICES=true
+FONT_SIZE=10
+RIGHT_ALIGN_IDS=false
+USE_PROXY=false
+WRAP_ALIGNMENT=false
+#DAS_REGISTRY_URL=http\://www.dasregistry.org/das/ # retired 01/05/2015
+DAS_REGISTRY_URL=http\://www.ebi.ac.uk/das-srv/registry/das/
+SPLASH=false
+ADD_SS_ANN=true
+ADD_TEMPFACT_ANN=true
+SHOW_ANNOTATIONS=true
+SHOW_CONSERVATION=true
+SHOW_IDENTITY=true
+SHOW_OCCUPANCY=true
+STRUCT_FROM_PDB=true
diff --git a/test/jalview/bin/commandsTest2.argfile1 b/test/jalview/bin/commandsTest2.argfile1
new file mode 100644 (file)
index 0000000..ea3a1be
--- /dev/null
@@ -0,0 +1,22 @@
+--substitutions
+--append=examples/test_fab41.result/sample.a2m
+--showannotations
+--showssannotations
+--colour=gecos-flower
+--structure=[viewer=jmol,tempfac=plddt,paematrix={dirname}/test_fab41_unrelaxed_rank_1_model_3_scores.json]{dirname}/test_fab41_unrelaxed_rank_1_model_3.pdb
+--structure={dirname}/test_fab41_unrelaxed_rank_2_model_4.pdb
+--structureviewer=jmol
+--paematrix={dirname}/test_fab41_unrelaxed_rank_2_model_4_scores.json
+--tempfac=plddt
+--structure={dirname}/test_fab41_unrelaxed_rank_3_model_2.pdb
+--structureviewer=jmol
+--paematrix={dirname}/test_fab41_unrelaxed_rank_3_model_2_scores.json
+--tempfac=plddt
+--structure=[viewer=none]{dirname}/test_fab41_unrelaxed_rank_4_model_5.pdb
+--paematrix={dirname}/test_fab41_unrelaxed_rank_4_model_5_scores.json
+--tempfac=plddt
+--structure={dirname}/test_fab41_unrelaxed_rank_5_model_1.pdb
+--structureviewer=none
+--tempfac=plddt
+--paematrix={dirname}/test_fab41_unrelaxed_rank_5_model_1_scores.json
+#--headless
diff --git a/test/jalview/bin/commandsTest2.argfile2 b/test/jalview/bin/commandsTest2.argfile2
new file mode 100644 (file)
index 0000000..1afc69c
--- /dev/null
@@ -0,0 +1,26 @@
+--debug
+--nonews
+--nosplash
+--substitutions
+--append=examples/test_fab41.result/sample.a2m
+--noshowannotations
+--noshowssannotations
+--colour=gecos-flower
+--structure=[tempfac=plddt,paematrix={dirname}/test_fab41_unrelaxed_rank_1_model_3_scores.json]{dirname}/test_fab41_unrelaxed_rank_1_model_3.pdb
+--structureviewer=none
+--structure={dirname}/test_fab41_unrelaxed_rank_2_model_4.pdb
+--structureviewer=jmol
+--paematrix={dirname}/test_fab41_unrelaxed_rank_2_model_4_scores.json
+--tempfac=plddt
+--structure={dirname}/test_fab41_unrelaxed_rank_3_model_2.pdb
+--structureviewer=jmol
+--paematrix={dirname}/test_fab41_unrelaxed_rank_3_model_2_scores.json
+--tempfac=plddt
+--structure=[structureviewer=none]{dirname}/test_fab41_unrelaxed_rank_4_model_5.pdb
+--paematrix={dirname}/test_fab41_unrelaxed_rank_4_model_5_scores.json
+--tempfac=plddt
+--structure={dirname}/test_fab41_unrelaxed_rank_5_model_1.pdb
+--structureviewer=none
+--tempfac=plddt
+--paematrix={dirname}/test_fab41_unrelaxed_rank_5_model_1_scores.json
+#--headless
diff --git a/test/jalview/bin/commandsTest2.jvprops1 b/test/jalview/bin/commandsTest2.jvprops1
new file mode 100644 (file)
index 0000000..bd510e7
--- /dev/null
@@ -0,0 +1,4 @@
+SHOW_STARTUP_FILE=false
+SPLASH=false
+STRUCT_FROM_PDB=true
+ADD_TEMPFACT_ANN=true
diff --git a/test/jalview/bin/commandsTest2.jvprops2 b/test/jalview/bin/commandsTest2.jvprops2
new file mode 100644 (file)
index 0000000..576269a
--- /dev/null
@@ -0,0 +1,4 @@
+SHOW_STARTUP_FILE=false
+SPLASH=false
+STRUCT_FROM_PDB=false
+ADD_TEMPFACT_ANN=true
diff --git a/test/jalview/bin/test1-3.fa b/test/jalview/bin/test1-3.fa
new file mode 100644 (file)
index 0000000..c01e6cf
--- /dev/null
@@ -0,0 +1,6 @@
+>TEST1/1-4
+AAAA
+>TEST2/1-4
+LLLL
+>TEST3/1-5
+AAARG
diff --git a/test/jalview/bin/uniref50-output.blc b/test/jalview/bin/uniref50-output.blc
new file mode 100644 (file)
index 0000000..3614ef8
--- /dev/null
@@ -0,0 +1,174 @@
+>FER_CAPAA/1-97 Ferredoxin
+>FER_CAPAN/1-144 Ferredoxin, chloroplast precursor
+>FER1_SOLLC/1-144 Ferredoxin-1, chloroplast precursor
+>Q93XJ9_SOLTU/1-144 Ferredoxin I precursor
+>FER1_PEA/1-149 Ferredoxin-1, chloroplast precursor
+>Q7XA98_TRIPR/1-152 Ferredoxin I
+>FER1_MESCR/1-148 Ferredoxin-1, chloroplast precursor
+>FER1_SPIOL/1-147 Ferredoxin-1, chloroplast precursor
+>FER3_RAPSA/1-96 Ferredoxin, leaf L-A
+>FER2_ARATH/1-148 Ferredoxin-2, chloroplast precursor
+>FER_BRANA/1-96 Ferredoxin
+>FER1_ARATH/1-148 Ferredoxin-1, chloroplast precursor
+>Q93Z60_ARATH/1-118 At1g10960/T19D16_12
+>FER1_MAIZE/1-150 Ferredoxin-1, chloroplast precursor
+>O80429_MAIZE/1-140 Ferredoxin
+* iteration 1
+-MMMMMMM-M-MMMM
+-AAAAAAA-A-AAAA
+----TTAA-S-SSTA
+----TTTT-T-TTVT
+-------------L-
+-------------G-
+------TT-----S-
+----PPAT-----P-
+-SSSAAAT-A-AAR-
+-VIILLLM-L-LLA-
+-SSSYYSM-S-SSP-
+-AGGGGGG-S-SSA-
+-TTTTTA--A-AAF-
+-MMMAAT--I-IIFA
+-IIIVVMM-V-VVFL
+-SSSSSSA-G-SSSS
+-TTTTTTT-T-TTSM
+-SSSSSAT-S-SSSS
+-FFFFFFF-F-FFSI
+-MLLLMAV-I-LLLL
+-PPPRRPP-R-RRRR
+-RRRTRKK-R-RRA-
+-KKKQQ-P-S-QQA-
+-PPPPP-Q-P-QQP-
+-AAVMVTA-A-TTAA
+-VVVPPPP-P-PPPP
+-TTTMMPP-I-IITP
+-SSSSSMM-S-SSAP
+-LLLVVTM-L-LLVC
+------AA-R-RR-F
+-KKKTAAA-S-SS-S
+-PAATTLL-L-LLAS
+-IIITTPP-P-PPLP
+-PSSKTTS-S-FFPL
+-NNNATNN-A-AAAR
+-VVVFTVT-N-NNAL
+-GGGSKGG-T-TTKR
+-EEENARR-Q-QQVV
+-----F---------
+-----P---------
+-AAAGSAS-S-SSGA
+-LLLFGLL-L-LLIV
+-FFFLFFF-F-FFMA
+-GGGGGGG-G-GGGK
+-LLLLLLL-L-LLRP
+-KKKKKKK-K-KKSL
+-SSSTSST-S-SSAA
+-----V---------
+-AGGSSSG-G-SSSA
+----LTAS-T-TTSP
+----KKSR-A-AARM
+-NRRRRR--R-RRRR
+-GNNGG---G-GG-R
+-GGGDDGG-G-GG-Q
+-KRRLLRG-R-RRRL
+-VIIAAVR-V-VVLL
+-TTTVVTM-T-TTRR
+-CCCAAAT-A-AAAA
+-MMMMMMM-M-MMQQ
+AAAAAAAAAAAAAAA
+SSSSSTAATTTTTTT
+YYYYYYYYYYYYYYY
+KKKKKKKKKKKKKNN
+VVVVVVVVVVVVVVV
+KKKKKKTTKKKKKKK
+LLLLLLLLFFFFFLL
+IIIIVIVVIIIIIII
+TTTTTTTTTTTTTTT
+PPPPPPPPPPPPPPP
+DDEDDEETEEEEEEE
+GGGGGGGGGGGGGGG
+PPPPTPKNEEEEEEE
+IIIIQQQVQLQQQVV
+EEEEEEEEEEEEEEE
+FFFFFFLFVVVVVLL
+DDEEEDEQEEEEEQQ
+CCCCCCCCCCCCCVV
+PPPPPPPPDDDEEPP
+DDDDSDDDDDDEEDD
+DNDDDDDDDDDDDDD
+VVVVVVVVVVVVVVV
+YYYYYYYYYYYYYYY
+IIIIIIIIVVVVVII
+LLLLLLLLLLLLLLL
+DDDDDDDDDDDDDDD
+QQQQHHAAAAAAAQF
+AAAAAAAAAAAAAAA
+EEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEE
+AAEEVVAEAAAAADE
+GGGGGGGGGGGGGGG
+HHHHIIIIIIILLII
+DDDDDEDDDDDDDDD
+LLLLLLLLLLLLLLL
+PPPPPPPPPPPPPPP
+YYYYYYYYYYYYYYF
+SSSSSSSSSSSSSSS
+CCCCCCCCCCCCCCC
+RRRRRRRRRRRRRRR
+AAAAAAAAAAAAAAA
+GGGGGGGGGGGGGGG
+SSSSSSSSSSSSSSS
+CCCCCCCCCCCCCCC
+SSSSSSSSSSSSSSS
+SSSSSSSSSSSSSSS
+CCCCCCCCCCCCCCC
+AAAAAAAAAAAAAAA
+GGGGGGGGGGGGGGG
+KKKKKKKKKKKKKKK
+IIVVVVVLVVVVVVV
+AATTVVTKVVVVVVV
+GGAAGNSTSSSSSSS
+GGGGGGGGGGGGGGG
+AASTENSSSSFSSSS
+VVVVVVVLVVVIIVV
+DDDDDNNNDDDDDDD
+QQQQQQQQQQQQQQQ
+TTSSSEDDSSSSSSS
+DDDDDDDDDDDDDDD
+GGGGGGGQQQEQQQQ
+NNNKSSSSSSSSSSS
+FFFFFFFFFFFFFYF
+LLLLLLLLLLLLLLL
+DDDDDDDDDDDDDDN
+DDEDDDDDDDDDDDD
+DDDDEEDDDEDE-GN
+QQQQQQQQQQQQ-QQ
+LLEEIIIIIIIM-IV
+EEAAEEKDAGAS-AA
+EEAAAGEEEEEE-DD
+GGGGGGGGGGGG-GG
+WWFFFWWWFFFY-WW
+VVVVVVVVVVVV-VV
+LLLLLLLLLLLL-LL
+TTTTTTTTTTTT-TT
+CCCCCCCCCCCC-CC
+VVVVVVVAAAAV-HA
+AAAAAAAAAAAA-AA
+YYYYYFYYYYYY-YY
+PPPPPPPPPPPP-PP
+QQKKTTTVTTTT-TT
+SSGCSSGSSSSS-SS
+DDDDDDDDDDDD-DD
+VVVVVVVVVVVV-VV
+TTTTVTTTTTTV-VV
+IIIIIIIIIIII-II
+EEEEEEEEEEEE-EE
+TTTTTTTTTTTT-TT
+HHHHHHHHHHHH-HH
+KKKKKKKKRKKK-KK
+EEEEEEEEEEEE-EE
+AAEEEEEEEEEE-ED
+EEEEDEEEDDEA-ED
+LLLLLLLLMILI-LL
+VVTTTTTTVVVM-TL
+GGAAAAAA-----G-
+-------------A-
+*
diff --git a/test/jalview/bin/uniref50-output.fa b/test/jalview/bin/uniref50-output.fa
new file mode 100644 (file)
index 0000000..98e89f2
--- /dev/null
@@ -0,0 +1,60 @@
+>FER_CAPAA/1-97 Ferredoxin
+-----------------------------------------------------------ASYKVKLITPDGP
+IEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV
+TIETHKEAELVG-
+>FER_CAPAN/1-144 Ferredoxin, chloroplast precursor
+MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMASYKVKLITPDGP
+IEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV
+TIETHKEAELVG-
+>FER1_SOLLC/1-144 Ferredoxin-1, chloroplast precursor
+MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPEGP
+IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDV
+TIETHKEEELTA-
+>Q93XJ9_SOLTU/1-144 Ferredoxin I precursor
+MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPDGP
+IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDV
+TIETHKEEELTA-
+>FER1_PEA/1-149 Ferredoxin-1, chloroplast precursor
+MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGT
+QEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDV
+VIETHKEEDLTA-
+>Q7XA98_TRIPR/1-152 Ferredoxin I
+MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGP
+QEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDV
+TIETHKEEELTA-
+>FER1_MESCR/1-148 Ferredoxin-1, chloroplast precursor
+MAAT--TAALSGATMSTAFAPK--TPPMTAALPTNVGR--ALFGLKS-SASR-GRVTAMAAYKVTLVTPEGK
+QELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDDDQIKEGWVLTCVAYPTGDV
+TIETHKEEELTA-
+>FER1_SPIOL/1-147 Ferredoxin-1, chloroplast precursor
+MAAT--TTTMMG--MATTFVPKPQAPPMMAALPSNTGR--SLFGLKT-GSR--GGRMTMAAYKVTLVTPTGN
+VEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDV
+TIETHKEEELTA-
+>FER3_RAPSA/1-96 Ferredoxin, leaf L-A
+-----------------------------------------------------------ATYKVKFITPEGE
+QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV
+TIETHREEDMV--
+>FER2_ARATH/1-148 Ferredoxin-2, chloroplast precursor
+MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE
+LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV
+TIETHKEEDIV--
+>FER_BRANA/1-96 Ferredoxin
+-----------------------------------------------------------ATYKVKFITPEGE
+QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV
+TIETHKEEELV--
+>FER1_ARATH/1-148 Ferredoxin-1, chloroplast precursor
+MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
+QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
+VIETHKEEAIM--
+>Q93Z60_ARATH/1-118 At1g10960/T19D16_12
+MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
+QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD-------------------
+-------------
+>FER1_MAIZE/1-150 Ferredoxin-1, chloroplast precursor
+MATVLGSPRAPAFFFSSSSLRAAPAPTAV--ALPAAKV--GIMGRSA-SSRR--RLRAQATYNVKLITPEGE
+VELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDV
+VIETHKEEELTGA
+>O80429_MAIZE/1-140 Ferredoxin
+MAAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQATYNVKLITPEGE
+VELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDV
+VIETHKEDDLL--
index 2f46eca..4615204 100644 (file)
@@ -20,7 +20,9 @@
  */
 package jalview.datamodel;
 
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
 import static org.testng.AssertJUnit.assertEquals;
 
 import jalview.analysis.AlignSeq;
@@ -426,4 +428,23 @@ public class AlignmentAnnotationTests
     assertNull(ann.annotations[0]);
     assertNull(ann.annotations[4]);
   }
+  /**
+   * test the contact matrix nogroups property methods
+   */
+  @Test(groups= {"Functional"})
+  public void test_contactMatrixGroups()
+  {
+    AlignmentAnnotation aa = new AlignmentAnnotation("foo","foo desc",null);
+    assertTrue(aa.isShowGroupsForContactMatrix());
+    aa.setShowGroupsForContactMatrix(false);
+    assertFalse(aa.isShowGroupsForContactMatrix());
+    AlignmentAnnotation copy = new AlignmentAnnotation(aa);
+    assertFalse(copy.isShowGroupsForContactMatrix());
+    aa.setShowGroupsForContactMatrix(true);
+    assertTrue(aa.isShowGroupsForContactMatrix());
+    // copy should not be updated
+    assertFalse(copy.isShowGroupsForContactMatrix());
+    
+    
+  }
 }
index 92db223..1c27420 100644 (file)
@@ -1591,7 +1591,8 @@ public class AlignmentTest
     // ?
 
   }
-  @Test(groups = {"Functional"})
+
+  @Test(groups = { "Functional" })
   public void testEquals()
   {
     SequenceI seq1 = new Sequence("seq1", "ABCDEF--");
@@ -1599,6 +1600,6 @@ public class AlignmentTest
     SequenceI seq3 = new Sequence("seq2", "-PQR");
     AlignmentI a = new Alignment(new SequenceI[] { seq1, seq2, seq3 });
     a.setDataset(null);
-    assertEquals(a.getDataset(),a.getDataset());
+    assertEquals(a.getDataset(), a.getDataset());
   }
 }
index 431834c..8bde11e 100644 (file)
@@ -3,13 +3,14 @@ package jalview.datamodel;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-public class ContactRangeTest {
+public class ContactRangeTest
+{
 
   @Test
   public void testContactRangeBean()
   {
     ContactRange cr = new ContactRange();
-    cr.update(5, 15, 6, 0.2, 12, 1.5,3.7);
+    cr.update(5, 15, 6, 0.2, 12, 1.5, 3.7);
     Assert.assertEquals(5, cr.getFrom_column());
     Assert.assertEquals(15, cr.getTo_column());
     Assert.assertEquals(6, cr.getMinPos());
diff --git a/test/jalview/datamodel/PAEContactMatrixTest.java b/test/jalview/datamodel/PAEContactMatrixTest.java
new file mode 100644 (file)
index 0000000..bdfa5a3
--- /dev/null
@@ -0,0 +1,246 @@
+package jalview.datamodel;
+
+import static org.testng.Assert.*;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import jalview.analysis.AlignmentUtils;
+import jalview.analysis.SeqsetUtils;
+import jalview.gui.JvOptionPane;
+import jalview.util.MapList;
+import jalview.ws.datamodel.MappableContactMatrixI;
+import jalview.ws.datamodel.alphafold.PAEContactMatrix;
+
+public class PAEContactMatrixTest
+{
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  static float[][] PAEdata = { { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f },
+      { 2.0f, 1.0f, 2.0f, 3.0f, 4.0f },
+      { 3.0f, 2.0f, 1.0f, 2.0f, 3.0f },
+      { 4.0f, 3.0f, 2.0f, 1.0f, 2.0f },
+      { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f } };
+
+  /**
+   * test associations for a PAE matrix
+   */
+  @Test(groups = { "Functional" })
+  public void testSeqAssociatedPAEMatrix()
+  {
+    Sequence seq = new Sequence("Seq", "ASDQE");
+    AlignmentAnnotation aa = seq
+            .addContactList(new PAEContactMatrix(seq, PAEdata));
+    assertNotNull(seq.getContactListFor(aa, 0));
+    assertEquals(seq.getContactListFor(aa, 0).getContactAt(0), 1.0);
+    assertNotNull(seq.getContactListFor(aa, 1));
+    assertEquals(seq.getContactListFor(aa, 1).getContactAt(1), 1.0);
+    assertNotNull(seq.getContactListFor(aa, 2));
+    assertEquals(seq.getContactListFor(aa, 2).getContactAt(2), 1.0);
+    assertNotNull(seq.getContactListFor(aa, 3));
+    assertEquals(seq.getContactListFor(aa, 3).getContactAt(3), 1.0);
+    assertNotNull(seq.getContactListFor(aa, 4));
+    assertEquals(seq.getContactListFor(aa, 4).getContactAt(4), 1.0);
+
+    assertNotNull(seq.getContactListFor(aa, seq.getEnd() - 1));
+    assertNull(seq.getContactListFor(aa, seq.getEnd()));
+
+    ContactListI cm = seq.getContactListFor(aa, seq.getStart());
+    assertEquals(cm.getContactAt(seq.getStart()), 1d);
+    verifyPAEmatrix(seq, aa, 0, 0, 4);
+
+    // Now associated with sequence not starting at 1
+    seq = new Sequence("Seq/5-9", "ASDQE");
+    ContactMatrixI paematrix = new PAEContactMatrix(seq, PAEdata);
+    aa = seq.addContactList(paematrix);
+    assertNotNull(aa);
+    // individual annotation elements need to be distinct for Matrix associated
+    // rows
+    Annotation ae5 = aa.getAnnotationForPosition(5);
+    Annotation ae6 = aa.getAnnotationForPosition(6);
+    assertNotNull(ae5);
+    assertNotNull(ae6);
+    assertTrue(ae5 != ae6);
+
+    cm = seq.getContactListFor(aa, 0);
+    assertEquals(cm.getContactAt(0), 1d);
+    verifyPAEmatrix(seq, aa, 0, 0, 4);
+
+    // test clustering
+    paematrix.setGroupSet(GroupSet.makeGroups(paematrix, false,0.1f, false));
+
+    // remap - test the MappableContactMatrix.liftOver method
+    SequenceI newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
+    Mapping sqmap = new Mapping(seq,
+            new MapList(new int[]
+            { 5, 8, 10, 10 }, new int[] { 5, 9 }, 1, 1));
+    assertTrue(paematrix instanceof MappableContactMatrixI);
+
+    MappableContactMatrixI remapped = ((MappableContactMatrixI) paematrix)
+            .liftOver(newseq, sqmap);
+    assertTrue(remapped instanceof PAEContactMatrix);
+
+    AlignmentAnnotation newaa = newseq.addContactList(remapped);
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(1)));
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(4)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(5)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(6)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(7)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(8)));
+    // no mapping for position 9
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(9)));
+    // last column
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(10)));
+
+    // verify MappedPositions includes discontinuity
+    int[] mappedCl = newseq.getContactListFor(newaa, 5)
+            .getMappedPositionsFor(0, 4);
+    assertEquals(4, mappedCl.length,
+            "getMappedPositionsFor doesn't support discontinuous mappings to contactList");
+
+    // make it harder.
+
+    SequenceI alseq = newseq.getSubSequence(6, 10);
+    alseq.insertCharAt(2, 2, '-');
+    AlignmentI alForSeq = new Alignment(new SequenceI[] { alseq });
+    newaa = AlignmentUtils.addReferenceAnnotationTo(alForSeq, alseq, newaa,
+            null);
+    ContactListI alcl = alForSeq.getContactListFor(newaa, 1);
+    assertNotNull(alcl);
+    mappedCl = alcl.getMappedPositionsFor(0, 4);
+    assertNotNull(mappedCl);
+    assertEquals(4, mappedCl.length,
+            "getMappedPositionsFor doesn't support discontinuous mappings to contactList");
+
+    // remap2 - test with original matrix map from 1-5 remapped to 5-9
+
+    seq = new Sequence("Seq/1-5", "ASDQE");
+    paematrix = new PAEContactMatrix(seq, PAEdata);
+    assertTrue(paematrix instanceof MappableContactMatrixI);
+    aa = seq.addContactList(paematrix);
+
+    newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
+    sqmap = new Mapping(seq,
+            new MapList(new int[]
+            { 5, 9 }, new int[] { 1, 5 }, 1, 1));
+
+    remapped = ((MappableContactMatrixI) paematrix).liftOver(newseq, sqmap);
+    assertTrue(remapped instanceof PAEContactMatrix);
+
+    newaa = newseq.addContactList(remapped);
+    verify_mapping(newseq, newaa);
+
+    // remap3 - remap2 but mapping sense in liftover is reversed
+
+    seq = new Sequence("Seq/1-5", "ASDQE");
+    paematrix = new PAEContactMatrix(seq, PAEdata);
+    assertTrue(paematrix instanceof MappableContactMatrixI);
+    aa = seq.addContactList(paematrix);
+
+    newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
+    sqmap = new Mapping(newseq,
+            new MapList(new int[]
+            { 1, 5 }, new int[] { 5, 9 }, 1, 1));
+
+    remapped = ((MappableContactMatrixI) paematrix).liftOver(newseq, sqmap);
+    assertTrue(remapped instanceof PAEContactMatrix);
+
+    newaa = newseq.addContactList(remapped);
+    verify_mapping(newseq, newaa);
+  }
+
+  /**
+   * checks that the PAE matrix is located at positions 1-9 in newseq, and
+   * columns are not truncated.
+   * 
+   * @param newseq
+   * @param newaa
+   */
+  private void verify_mapping(SequenceI newseq, AlignmentAnnotation newaa)
+  {
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(1)));
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(4)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(5)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(6)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(7)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(8)));
+    assertNotNull(
+            newseq.getContactListFor(newaa, -1 + newseq.findIndex(9)));
+    // last column should be null this time
+    assertNull(newseq.getContactListFor(newaa, -1 + newseq.findIndex(10)));
+
+    verifyPAEmatrix(newseq, newaa, 4, 4, 8);
+  }
+
+  private void verifyPAEmatrix(SequenceI seq, AlignmentAnnotation aa,
+          int topl, int rowl, int rowr)
+  {
+    int[] mappedCl;
+    for (int f = rowl; f <= rowr; f++)
+    {
+      ContactListI clist = seq.getContactListFor(aa, f);
+      assertNotNull(clist, "No ContactListI for position " + (f));
+      assertEquals(clist.getContactAt(0), (double) f - topl + 1,
+              "for column " + f + " relative to " + topl);
+      mappedCl = clist.getMappedPositionsFor(0, 0);
+      assertNotNull(mappedCl);
+      assertEquals(mappedCl[0], mappedCl[1]);
+      assertEquals(mappedCl[0], seq.findIndex(seq.getStart() + topl));
+      assertEquals(clist.getContactAt(f - topl), 1d,
+              "for column and row " + f + " relative to " + topl);
+    }
+  }
+
+  /**
+   * check mapping and resolution methods work
+   */
+  @Test(groups= {"Functional"})
+  public void testMappableContactMatrix() {
+    SequenceI newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
+    MapList map = new MapList(new int[]
+            { 5, 9 }, new int[] { 1, 5 }, 1, 1);
+    AlignmentAnnotation aa = newseq
+            .addContactList(new PAEContactMatrix(newseq,map, PAEdata,null));
+    ContactListI clist = newseq.getContactListFor(aa, 4);
+    assertNotNull(clist);
+    clist = newseq.getContactListFor(aa, 3);
+    assertNull(clist);
+    
+    ContactMatrixI cm = newseq.getContactMatrixFor(aa);
+    MappableContactMatrixI mcm = (MappableContactMatrixI) cm;
+    int[] pos = mcm.getMappedPositionsFor(newseq, 0);
+    assertNull(pos);
+
+    pos = mcm.getMappedPositionsFor(newseq, 1);
+    assertNotNull(pos);
+    assertEquals(pos[0],4+newseq.getStart());
+    
+    pos = mcm.getMappedPositionsFor(newseq, 6); // after end of matrix
+    assertNull(pos);
+    pos = mcm.getMappedPositionsFor(newseq, 5); // at end of matrix
+    assertNotNull(pos);
+    assertEquals(pos[0],8+newseq.getStart());
+    SequenceI alseq = newseq.deriveSequence();
+    alseq.insertCharAt(5,'-');
+    pos = mcm.getMappedPositionsFor(alseq, 5); // at end of matrix
+    assertNotNull(pos);
+    assertEquals(pos[0],8+newseq.getStart());
+    
+    
+  }
+}
index 0151a12..7bbb9f3 100644 (file)
@@ -1052,6 +1052,38 @@ public class SequenceTest
     assertEquals("ABCDEF",
             derived.getDatasetSequence().getSequenceAsString());
   }
+  
+  /**
+   * test that creating a copy of an existing sequence with dataset sequence and
+   * associated contact matrix yields annotation associated with the same
+   * contact matrix in the copy
+   */
+  @Test(groups= {"Functional"})
+  public void testCopyPasteStyleDerivesequence_withcontactMatrixAnn()
+  {
+    SequenceI seq1=new Sequence("seq1","ACDACDACD");
+    seq1.createDatasetSequence();
+    ContactMatrixI cm = new SeqDistanceContactMatrix(seq1.getLength());
+    // addContactList needs to return annotation addable to the sequence reference it was called from
+    AlignmentAnnotation aann = seq1.addContactList(cm);
+    assertTrue(aann.sequenceRef==seq1);
+    assertEquals(1,seq1.getAnnotation().length);
+    assertNotNull(seq1.getContactListFor(seq1.getAnnotation()[0], 1));
+    
+    SequenceI seq_derived=seq1.deriveSequence();
+    assertEquals(1,seq_derived.getAnnotation().length);
+    assertTrue(cm==seq_derived.getContactMatrixFor(seq_derived.getAnnotation()[0]));
+    assertNotNull(seq_derived.getContactListFor(seq_derived.getAnnotation()[0], 1));
+    
+    // copy paste actually uses the copy constructor .. so
+    
+    SequenceI seq_copied=new Sequence((Sequence)seq_derived);
+    assertEquals(1,seq_copied.getAnnotation().length);
+    assertTrue(cm==seq_copied.getContactMatrixFor(seq_copied.getAnnotation()[0]));
+    assertNotNull(seq_copied.getContactListFor(seq_copied.getAnnotation()[0], 1));
+    
+    
+  }
 
   @Test(groups = { "Functional" })
   public void testCopyConstructor_noDataset()
@@ -2283,8 +2315,16 @@ public class SequenceTest
   {
     Sequence origSeq = new Sequence("MYSEQ", "THISISASEQ");
     Sequence toSeq = new Sequence("MYSEQ", "THISISASEQ");
+    origSeq.setDescription("DESCRIPTION");
     origSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q12345", null, true));
+
+    toSeq.transferAnnotation(origSeq, null);
+    assertEquals("DESCRIPTION",toSeq.getDescription());
+    toSeq = new Sequence("MYSEQ", "THISISASEQ");
+    toSeq.setDescription("unchanged");
     toSeq.transferAnnotation(origSeq, null);
+    assertEquals("unchanged",toSeq.getDescription());
+    
     assertTrue(toSeq.getDBRefs().size() == 1);
 
     assertTrue(toSeq.getDBRefs().get(0).isCanonical());
index e451ed2..9dec19b 100644 (file)
@@ -24,6 +24,12 @@ import static org.junit.Assert.assertNotNull;
 import static org.testng.Assert.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
+import java.lang.reflect.InvocationTargetException;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
@@ -31,6 +37,7 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
 import jalview.gui.JvOptionPane;
 import jalview.gui.Preferences;
 import jalview.gui.StructureViewer;
@@ -39,12 +46,6 @@ import jalview.io.DataSourceType;
 import jalview.io.FileFormat;
 import jalview.io.FileLoader;
 
-import java.lang.reflect.InvocationTargetException;
-
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
 @Test(singleThreaded = true)
 public class JmolViewerTest
 {
@@ -74,7 +75,8 @@ public class JmolViewerTest
   @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
-    jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" })
index 7f9aa9b..c8e30a7 100644 (file)
@@ -100,7 +100,8 @@ public class JalviewChimeraView
   @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @AfterMethod(alwaysRun = true)
index 2a768ff..ab2a1d0 100644 (file)
@@ -75,7 +75,8 @@ public class AlignFrameTest
   @AfterMethod(alwaysRun = true)
   public void tearDown()
   {
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
   }
 
   /**
index b3c6b2a..4537dcc 100644 (file)
@@ -42,8 +42,10 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.ContactMatrixI;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SeqDistanceContactMatrix;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -537,4 +539,29 @@ public class AlignViewportTest
     assertEquals(0, ranges.getStartSeq());
     assertEquals(2, ranges.getEndSeq());
   }
+  @Test(groups = {"Functional"})
+  public void testGetSelectionAsNewSequences_withContactMatrices()
+  {
+    SequenceI seq = new Sequence("seq","ACADA");
+    ContactMatrixI cmat = new SeqDistanceContactMatrix(5);
+    seq.addContactList(cmat);
+    Alignment al = new Alignment(new SequenceI[] {seq.deriveSequence() });
+    al.addAnnotation(al.getSequenceAt(0).getAnnotation()[0]);
+    AlignFrame af = new AlignFrame(al,500,500);
+    
+    SequenceI selseqs[] = af.getViewport().getSelectionAsNewSequence();
+    assertNotNull(selseqs[0].getAnnotation());
+    assertNotNull(selseqs[0].getAnnotation()[0]);
+    assertEquals(cmat,selseqs[0].getContactMatrixFor(selseqs[0].getAnnotation()[0]));
+    
+    assertNotNull(selseqs[0].getContactListFor(selseqs[0].getAnnotation()[0], 2));
+    
+    // now select everything and test again
+    af.selectAllSequenceMenuItem_actionPerformed(null);
+    selseqs = af.getViewport().getSelectionAsNewSequence();
+    assertNotNull(selseqs[0].getAnnotation());
+    assertNotNull(selseqs[0].getAnnotation()[0]);
+    assertEquals(cmat,selseqs[0].getContactMatrixFor(selseqs[0].getAnnotation()[0]));
+    assertNotNull(selseqs[0].getContactListFor(selseqs[0].getAnnotation()[0], 2));
+  }
 }
index 2d7e3dc..c1896bc 100644 (file)
@@ -291,41 +291,43 @@ public class AlignmentPanelTest
     Cache.setProperty("FIGURE_AUTOIDWIDTH", Boolean.TRUE.toString());
     assertEquals(115, af.alignPanel.getVisibleIdWidth(false));
   }
+
   @Test(groups = "Functional")
   public void testSetOverviewTitle()
   {
     OverviewPanel ov1 = this.af.openOverviewPanel(true);
     String alignFrameTitle = af.getTitle();
     assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle);
-    
+
     /*
      * on New View, existing overview should get " Original" added to title
      * and new view's overview should get " View 1" added
      */
     af.newView_actionPerformed(null);
-    assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle + " Original");
+    assertEquals(ov1.getTitle(),
+            "Overview " + alignFrameTitle + " Original");
     OverviewPanel ov2 = this.af.openOverviewPanel(true);
     assertEquals(ov2.getTitle(), "Overview " + alignFrameTitle + " View 1");
   }
-  
+
   @Test(groups = "Functional")
   public void testSetOverviewTitle_automaticOverview()
   {
-    Cache.setProperty("SHOW_OVERVIEW",  "true");
+    Cache.setProperty("SHOW_OVERVIEW", "true");
     AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
             "examples/uniref50.fa", DataSourceType.FILE);
     OverviewPanel ov1 = alignFrame.alignPanel.getOverviewPanel();
     assertNotNull(ov1);
     String alignFrameTitle = alignFrame.getTitle();
     assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle);
-    
+
     /*
      * on New View, existing overview should get " Original" added to title
      * and new view's automatic overview should have " View 1" added
      */
     alignFrame.newView_actionPerformed(null);
-    assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle + " Original");
+    assertEquals(ov1.getTitle(),
+            "Overview " + alignFrameTitle + " Original");
     OverviewPanel ov2 = alignFrame.alignPanel.getOverviewPanel();
     assertNotNull(ov2);
     assertEquals(ov2.getTitle(), "Overview " + alignFrameTitle + " View 1");
diff --git a/test/jalview/gui/AnnotationLabelsTest2.java b/test/jalview/gui/AnnotationLabelsTest2.java
new file mode 100644 (file)
index 0000000..ad97e8b
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.structure.StructureImportSettings.TFType;
+
+public class AnnotationLabelsTest2
+{
+  @BeforeClass(alwaysRun = true)
+  public static void setUpBeforeClass() throws Exception
+  {
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
+
+    setUpJvOptionPane();
+    /*
+     * use read-only test properties file
+     */
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Jalview.main(new String[] { "--nonews", "--nosplash", });
+  }
+
+  @AfterMethod(alwaysRun = true)
+  public void tearDown()
+  {
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
+  }
+
+  /**
+   * configure (read-only) properties for test to ensure Consensus is computed
+   * for colour Above PID testing
+   */
+  @BeforeMethod(alwaysRun = true)
+  public void setUp()
+  {
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+            Boolean.TRUE.toString());
+
+  }
+
+  public static void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(
+    groups =
+    { "Functional", "testTask1" },
+    dataProvider = "openFilesWithIdWidthChanges")
+  public void testIdWidthChanges(String alignmentFilename, boolean wrap,
+          int idWidth1min, int idWidth1max, int manualWidth,
+          String structureFilename, String paeFilename,
+          boolean secondaryStructureView, TFType temperatureFactorType,
+          ViewerType viewerType, int idWidth2min, int idWidth2max)
+  {
+    AlignFrame af = new FileLoader()
+            .LoadFileWaitTillLoaded(alignmentFilename, DataSourceType.FILE);
+    try
+    {
+      Thread.sleep(200); // to allow alignment annotations to open
+    } catch (InterruptedException e)
+    {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    AlignViewport av = af.getCurrentView();
+
+    int idWidth = 0;
+
+    idWidth = av.getIdWidth();
+    assertTrue(idWidth > idWidth1min,
+            "idWidth (" + idWidth + ") is not greater than " + idWidth1min);
+    assertTrue(idWidth < idWidth1max,
+            "idWidth (" + idWidth + ") is not narrower than" + idWidth1max);
+
+    // set wrap
+    if (wrap)
+    {
+      af.setWrapFormat(true, false);
+      idWidth = av.getIdWidth();
+      assertTrue(idWidth > idWidth1min, "After wrap idWidth (" + idWidth
+              + ") is not greater than " + idWidth1min);
+      assertTrue(idWidth < idWidth1max, "After wrap idWidth (" + idWidth
+              + ") is not narrower than" + idWidth1max);
+    }
+
+    AlignmentI al = av.getAlignment();
+    SequenceI s = al.getSequenceAt(0);
+    AlignmentPanel ap = af.alignPanel;
+
+    File structureFile = new File(structureFilename);
+    File paeFile = new File(paeFilename);
+
+    StructureViewer sv = StructureChooser.openStructureFileForSequence(null,
+            null, ap, s, false, structureFile.getAbsolutePath(),
+            temperatureFactorType, paeFile.getAbsolutePath(), true,
+            secondaryStructureView, false, viewerType);
+    // give time for annotations to open
+    try
+    {
+      Thread.sleep(200); // to allow alignment annotations to open
+    } catch (InterruptedException e)
+    {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+
+    // idWidth = ap.getIdPanel().getWidth();
+    idWidth = av.getIdWidth();
+    assertTrue(idWidth > idWidth2min,
+            "idWidth (" + idWidth + ") is not greater than " + idWidth2min);
+    assertTrue(idWidth < idWidth2max,
+            "idWidth (" + idWidth + ") is not narrower than" + idWidth2max);
+  }
+
+  @Test(
+    groups =
+    { "Functional", "testTask1" },
+    dataProvider = "openFilesWithIdWidthChanges")
+  public void testIdWidthNoChanges(String alignmentFilename, boolean wrap,
+          int idWidth1min, int idWidth1max, int manualWidth,
+          String structureFilename, String paeFilename,
+          boolean secondaryStructureView, TFType temperatureFactorType,
+          ViewerType viewerType, int idWidth2min, int idWidth2max)
+  {
+    AlignFrame af = new FileLoader()
+            .LoadFileWaitTillLoaded(alignmentFilename, DataSourceType.FILE);
+    try
+    {
+      Thread.sleep(200); // to allow alignment annotations to open
+    } catch (InterruptedException e)
+    {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    AlignViewport av = af.getCurrentView();
+
+    int idWidth = 0;
+
+    idWidth = av.getIdWidth();
+    assertTrue(idWidth > idWidth1min,
+            "idWidth (" + idWidth + ") is not greater than " + idWidth1min);
+    assertTrue(idWidth < idWidth1max,
+            "idWidth (" + idWidth + ") is not narrower than" + idWidth1max);
+
+    AlignmentI al = av.getAlignment();
+    SequenceI s = al.getSequenceAt(0);
+    AlignmentPanel ap = af.alignPanel;
+
+    // set width manually
+    av.setIdWidth(manualWidth);
+    ap.validateAnnotationDimensions(false);
+    ap.paintAlignment(true, false);
+    ap.getIdPanel().getIdCanvas().setManuallyAdjusted(true);
+
+    idWidth = av.getIdWidth();
+    assertEquals(idWidth, manualWidth,
+            "idWidth is not set to the manually set width " + manualWidth);
+
+    File structureFile = new File(structureFilename);
+    File paeFile = new File(paeFilename);
+
+    StructureViewer sv = StructureChooser.openStructureFileForSequence(null,
+            null, ap, s, false, structureFile.getAbsolutePath(),
+            temperatureFactorType, paeFile.getAbsolutePath(), false,
+            secondaryStructureView, false, viewerType);
+
+    idWidth = ap.getIdPanel().getWidth();// av.getIdWidth();
+    idWidth = av.getIdWidth();
+    assertEquals(idWidth, manualWidth,
+            "idWidth is not set to the manually set width " + manualWidth
+                    + " after adding structure annotations");
+    assertFalse(idWidth > idWidth2min,
+            "idWidth (" + idWidth + ") is greater than " + idWidth2min);
+  }
+
+  @DataProvider(name = "openFilesWithIdWidthChanges")
+  public Object[][] openFilesWithIdWidthChanges()
+  {
+    /*
+      String alignmentFilename,
+      boolean wrap,
+      int idWidth1min,
+      int idWidth1max,
+      int manualWidth, // ignored by testIdWidthChanges()
+      String structureFilename,
+      String paeFilename,
+      boolean secondaryStructureView,
+      TFType temperatureFactorType,
+      ViewerType viewerType,
+      int idWidth2min,
+      int idWidth2max,
+     */
+    return new Object[][] {
+        //
+        /*
+         */
+        { "./test/files/annotation_label_width/sample.a2m", false, 50, 70,
+            100,
+            "./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb",
+            "./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json",
+            true, TFType.PLDDT, null, 115, 130 },
+        { "./test/files/annotation_label_width/sample.a2m", true, 50, 70,
+            100,
+            "./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb",
+            "./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json",
+            true, TFType.PLDDT, null, 115, 130 },
+        /*
+         */
+    };
+  }
+
+}
index f0b3aef..1b988ec 100644 (file)
@@ -29,9 +29,13 @@ import java.io.File;
 import java.io.IOException;
 import java.util.HashMap;
 
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import jalview.api.FeatureColourI;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.features.FeatureMatcher;
@@ -46,6 +50,23 @@ import jalview.viewmodel.seqfeatures.FeatureRendererModel;
 
 public class FeatureSettingsTest
 {
+  @BeforeClass(alwaysRun = true)
+  public static void setUpBeforeClass() throws Exception
+  {
+    /*
+     * use read-only test properties file
+     */
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Jalview.main(new String[] { "-nonews" });
+  }
+
+  @AfterMethod(alwaysRun = true)
+  public void tearDown()
+  {
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
+  }
+
   /**
    * Test a roundtrip of save and reload of feature colours and filters as XML
    * 
index 81e37d8..a9eca49 100644 (file)
@@ -137,7 +137,8 @@ public class FreeUpMemoryTest
 
     doStuffInJalview(f);
 
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
 
     checkUsedMemory(MAX_RESIDUAL_HEAP);
   }
index b257088..b19f160 100644 (file)
@@ -66,9 +66,12 @@ public class QuitHandlerTest
     // reset mock response
     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
     // close desktop windows/frames
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
     // reset debug delay
     Jalview2XML.setDebugDelaySave(20);
+    // load normal testprops
+    Cache.loadProperties("test/jalview/testProps.jvprops");
   }
 
   @BeforeMethod(alwaysRun = true)
@@ -79,7 +82,8 @@ public class QuitHandlerTest
     // reset mock response
     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
     // close desktop windows/frames
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
     // reset debug delay
     Cache.setProperty("DEBUG_DELAY_SAVE", "false");
     Jalview2XML.setDebugDelaySave(3);
@@ -126,7 +130,6 @@ public class QuitHandlerTest
     Assert.assertTrue(end - start < 500,
             "Quit-with-no-save-needed took too long (" + (end - start)
                     + "ms)");
-    Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" }, singleThreaded = true, priority = 10)
@@ -154,8 +157,6 @@ public class QuitHandlerTest
     Assert.assertEquals(response, QResponse.QUIT);
     Assert.assertTrue(end - start > 2900,
             "Quit-whilst-saving was too short (" + (end - start) + "ms)");
-
-    Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" }, singleThreaded = true, priority = 9)
@@ -182,7 +183,6 @@ public class QuitHandlerTest
 
     // if not saved this would be CANCEL_QUIT
     Assert.assertEquals(response, QResponse.QUIT);
-    Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" }, singleThreaded = true, priority = 9)
@@ -207,7 +207,6 @@ public class QuitHandlerTest
 
     // if not saved this would be CANCEL_QUIT
     Assert.assertEquals(response, QResponse.QUIT);
-    Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" }, singleThreaded = true, priority = 1)
@@ -227,7 +226,6 @@ public class QuitHandlerTest
     QResponse response = QuitHandler.getQuitResponse(true);
 
     Assert.assertEquals(response, QResponse.CANCEL_QUIT);
-    Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" }, singleThreaded = true, priority = 1)
@@ -255,7 +253,6 @@ public class QuitHandlerTest
     QResponse response = QuitHandler.getQuitResponse(false);
 
     Assert.assertEquals(response, QResponse.QUIT);
-    Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" }, singleThreaded = true, priority = 11)
@@ -284,7 +281,6 @@ public class QuitHandlerTest
               jalview.bin.Console.debug(
                       "Setting FORCE_QUIT without actually quitting");
               QuitHandler.setResponse(QResponse.FORCE_QUIT);
-              return null;
             }, QuitHandler.defaultCancelQuit);
     long end = System.currentTimeMillis();
 
@@ -298,7 +294,6 @@ public class QuitHandlerTest
             "Force-Quit-whilst-saving was too long (" + (end - start)
                     + "ms)");
 
-    Desktop.instance.closeAll_actionPerformed(null);
   }
 
 }
index f905ef2..701431b 100644 (file)
@@ -250,7 +250,8 @@ public class SeqPanelTest
   @AfterMethod(alwaysRun = true)
   public void tearDown()
   {
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = "Functional")
@@ -920,7 +921,7 @@ public class SeqPanelTest
     }
     assertEquals(dna.length(), 51200);
     AlignFrame alignFrame = new FileLoader()
-            .LoadFileWaitTillLoaded("dna "+dna, DataSourceType.PASTE);
+            .LoadFileWaitTillLoaded("dna " + dna, DataSourceType.PASTE);
     SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
     AlignViewport av = alignFrame.getViewport();
     av.setScaleAboveWrapped(true);
index b74baf1..dd5cd4c 100644 (file)
@@ -24,15 +24,23 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
 
+import java.io.File;
 import java.util.Collection;
+import java.util.List;
 import java.util.Vector;
 
 import org.junit.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
@@ -43,8 +51,15 @@ import jalview.fts.service.pdb.PDBFTSRestClient;
 import jalview.fts.service.pdb.PDBFTSRestClientTest;
 import jalview.fts.service.threedbeacons.TDBeaconsFTSRestClient;
 import jalview.fts.threedbeacons.TDBeaconsFTSRestClientTest;
+import jalview.gui.StructureViewer.ViewerType;
 import jalview.gui.structurechooser.PDBStructureChooserQuerySource;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormatException;
+import jalview.io.FileFormatI;
+import jalview.io.FileLoader;
+import jalview.io.IdentifyFile;
 import jalview.jbgui.FilterOption;
+import jalview.structure.StructureImportSettings.TFType;
 import junit.extensions.PA;
 
 @Test(singleThreaded = true)
@@ -259,4 +274,147 @@ public class StructureChooserTest
     assertEquals("abcde12345afg",
             PDBStructureChooserQuerySource.sanitizeSeqName(name));
   }
+
+  @Test(groups = { "Functional" }, dataProvider = "openStructureFileParams")
+  public void openStructureFileForSequenceTest(String alfile, String seqid,
+          String sFilename, TFType tft, String paeFilename,
+          boolean showRefAnnotations, boolean doXferSettings,
+          ViewerType viewerType, int seqNum, int annNum, int viewerNum,
+          String propsFile)
+  {
+    Cache.loadProperties(
+            propsFile == null ? "test/jalview/io/testProps.jvprops"
+                    : propsFile);
+
+    Jalview.main(
+            propsFile == null ? null : new String[]
+            { "--props", propsFile });
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.OK_OPTION);
+
+    FileLoader fileLoader = new FileLoader(true);
+    FileFormatI format = null;
+    File alFile = new File(alfile);
+    try
+    {
+      format = new IdentifyFile().identify(alFile, DataSourceType.FILE);
+    } catch (FileFormatException e1)
+    {
+      Assert.fail(
+              "Unknown file format for '" + alFile.getAbsolutePath() + "'");
+    }
+
+    AlignFrame af = fileLoader.LoadFileWaitTillLoaded(alFile,
+            DataSourceType.FILE, format);
+    AlignmentPanel ap = af.alignPanel;
+    Assert.assertNotNull("No alignPanel", ap);
+
+    AlignmentI al = ap.getAlignment();
+    Assert.assertNotNull(al);
+
+    SequenceI seq = al.findName(seqid);
+    Assert.assertNotNull("Sequence '" + seqid + "' not found in alignment",
+            seq);
+
+    StructureChooser.openStructureFileForSequence(null, null, ap, seq,
+            false, sFilename, tft, paeFilename, false, showRefAnnotations,
+            doXferSettings, viewerType);
+
+    List<SequenceI> seqs = al.getSequences();
+    Assert.assertNotNull(seqs);
+
+    Assert.assertEquals("Wrong number of sequences", seqNum, seqs.size());
+
+    AlignViewportI av = ap.getAlignViewport();
+    Assert.assertNotNull(av);
+
+    AlignmentAnnotation[] aas = al.getAlignmentAnnotation();
+    int visibleAnn = 0;
+    for (AlignmentAnnotation aa : aas)
+    {
+      if (aa.visible)
+        visibleAnn++;
+    }
+    Assert.assertEquals("Wrong number of viewed annotations", annNum,
+            visibleAnn);
+
+    if (viewerNum > -1)
+    {
+      try
+      {
+        Thread.sleep(100);
+      } catch (InterruptedException e)
+      {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
+      List<StructureViewerBase> openViewers = Desktop.instance
+              .getStructureViewers(ap, null);
+      Assert.assertNotNull(openViewers);
+      int count = 0;
+      for (StructureViewerBase svb : openViewers)
+      {
+        if (svb.isVisible())
+          count++;
+      }
+      Assert.assertEquals("Wrong number of structure viewers opened",
+              viewerNum, count);
+
+    }
+
+    if (af != null)
+    {
+      af.setVisible(false);
+      af.dispose();
+    }
+  }
+
+  @DataProvider(name = "openStructureFileParams")
+  public Object[][] openStructureFileParams()
+  {
+    /*
+        String alFile,
+        String seqid,
+        String structureFilename,
+        TFType tft,
+        String paeFilename,
+        boolean showRefAnnotations,
+        boolean doXferSettings, // false for Commands
+        ViewerType viewerType,
+        int seqNum,
+        int annNum,
+        int viewerNum,
+        String propsFile
+     */
+    return new Object[][] {
+        /*
+        */
+        { "examples/uniref50.fa", "FER1_SPIOL",
+            "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT,
+            "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
+            true, false, null, 15, 7, 0, null },
+        { "examples/uniref50.fa", "FER1_SPIOL",
+            "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
+            "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
+            true, false, null, 15, 7, 0, null },
+        { "examples/uniref50.fa", "FER1_SPIOL",
+            "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
+            "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
+            false, false, null, 15, 4, 0, null },
+        { "examples/uniref50.fa", "FER1_SPIOL",
+            "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT,
+            "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
+            true, false, ViewerType.JMOL, 15, 7, 1, null },
+        { "examples/uniref50.fa", "FER1_SPIOL",
+            "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
+            "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
+            true, false, ViewerType.JMOL, 15, 7, 1, null },
+        { "examples/uniref50.fa", "FER1_SPIOL",
+            "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
+            "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
+            false, false, ViewerType.JMOL, 15, 4, 1, null }, };
+  }
+
 }
index 16f4b7e..c21add1 100644 (file)
@@ -250,8 +250,7 @@ public class StructureChooserQuerySourceTest
   }
 
   @SuppressWarnings("deprecation")
-  @Test(groups =
-  { "Functional" })
+  @Test(groups = { "Functional" })
   public void buildPDBQueryTest()
   {
     System.out.println("seq >>>> " + seq);
@@ -299,8 +298,7 @@ public class StructureChooserQuerySourceTest
   }
 
   @SuppressWarnings("deprecation")
-  @Test(groups =
-  { "Functional" })
+  @Test(groups = { "Functional" })
   public void buildThreeDBQueryTest()
   {
     System.out.println("seq >>>> " + upSeq);
index 689bd59..1b62ce3 100644 (file)
@@ -24,6 +24,15 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
 
+import java.io.File;
+import java.util.List;
+
+import org.junit.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
@@ -32,19 +41,11 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.features.SequenceFeatures;
 import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
 import jalview.gui.JvOptionPane;
 import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureImportSettings.StructureParser;
 
-import java.io.File;
-import java.util.List;
-
-import org.junit.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
 public class AnnotatedPDBFileInputTest
 {
 
@@ -207,8 +208,8 @@ public class AnnotatedPDBFileInputTest
   @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
-    jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
-
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = { "Functional" })
index a356621..7f04749 100644 (file)
@@ -104,7 +104,8 @@ public class BackupFilesTest
 
     // check no backup files
     File[] backupFiles = getBackupFiles();
-    Assert.assertTrue(backupFiles.length == 0);
+    Assert.assertEquals(backupFiles.length, 0, "Number of backup files is "
+            + backupFiles.length + ", not " + 0);
   }
 
   // save with no numbers in the backup file names
index 3ca6ed8..c46477a 100644 (file)
@@ -24,20 +24,6 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
-import jalview.analysis.CrossRef;
-import jalview.api.AlignmentViewPanel;
-import jalview.datamodel.AlignedCodonFrame;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.AlignmentTest;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.gui.CrossRefAction;
-import jalview.gui.Desktop;
-import jalview.gui.JvOptionPane;
-import jalview.gui.SequenceFetcher;
-import jalview.project.Jalview2XML;
-import jalview.util.DBRefUtils;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -51,6 +37,19 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import jalview.analysis.CrossRef;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentTest;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.CrossRefAction;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.gui.SequenceFetcher;
+import jalview.project.Jalview2XML;
+import jalview.util.DBRefUtils;
 import junit.extensions.PA;
 
 @Test(singleThreaded = true)
@@ -211,7 +210,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
       }
       else
       {
-        Desktop.instance.closeAll_actionPerformed(null);
+        if (Desktop.instance != null)
+          Desktop.instance.closeAll_actionPerformed(null);
         // recover stored project
         af = new FileLoader(false).LoadFileWaitTillLoaded(
                 savedProjects.get(first).toString(), DataSourceType.FILE);
@@ -278,7 +278,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
           }
           else
           {
-            Desktop.instance.closeAll_actionPerformed(null);
+            if (Desktop.instance != null)
+              Desktop.instance.closeAll_actionPerformed(null);
             pass3 = 0;
             // recover stored project
             File storedProject = savedProjects.get(nextxref);
@@ -389,7 +390,8 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
                 }
                 else
                 {
-                  Desktop.instance.closeAll_actionPerformed(null);
+                  if (Desktop.instance != null)
+                    Desktop.instance.closeAll_actionPerformed(null);
                   // recover stored project
                   File storedProject = savedProjects.get(nextnextxref);
                   if (storedProject == null)
index dde23e6..a197340 100644 (file)
  */
 package jalview.io;
 
+import java.util.Date;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeTest;
+
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
 import jalview.datamodel.AlignmentAnnotation;
@@ -27,12 +33,6 @@ import jalview.datamodel.SequenceI;
 import jalview.gui.Desktop;
 import jalview.gui.JvOptionPane;
 
-import java.util.Date;
-
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeTest;
-
 public class Jalview2xmlBase
 {
 
@@ -71,7 +71,8 @@ public class Jalview2xmlBase
   @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
-    jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @BeforeTest(alwaysRun = true)
index 1d138c0..59c5986 100644 (file)
@@ -22,14 +22,15 @@ package jalview.io;
 
 import static org.testng.AssertJUnit.assertTrue;
 
-import jalview.datamodel.SequenceGroup;
-import jalview.gui.AlignFrame;
-import jalview.gui.JvOptionPane;
-
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import jalview.datamodel.SequenceGroup;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+
 /**
  * tests which verify that properties and preferences are correctly interpreted
  * when exporting/importing data
@@ -64,7 +65,8 @@ public class JalviewExportPropertiesTests
   @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
-    jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
 
   }
 
index 65cea6f..d2b6f65 100644 (file)
  */
 package jalview.io;
 
+import jalview.datamodel.SequenceI;
 import jalview.gui.JvOptionPane;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
 import java.io.File;
+import java.io.IOException;
 
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import fr.orsay.lri.varna.utils.RNAMLParser;
+import groovy.lang.Sequence;
+
 public class RNAMLfileTest
 {
 
@@ -57,4 +65,14 @@ public class RNAMLfileTest
 
   }
 
+  @Test(groups= {"Functional"})
+  public void testRnamlSeqImport() throws IOException
+  {
+    RnamlFile parser = new RnamlFile("examples/testdata/7WKP-rna1.xml", DataSourceType.FILE);
+    SequenceI[] seqs  = parser.getSeqsAsArray();
+    assertNotNull(seqs);
+    assertEquals(seqs.length,1);
+    assertEquals(seqs[0].getEnd()-seqs[0].getStart()+1,seqs[0].getSequence().length);
+  }
+
 }
index b1995ab..10f368a 100644 (file)
@@ -137,6 +137,31 @@ public class StockholmFileTest
 
   }
 
+  @Test(groups = { "Functional" })
+  public void descriptionLineOutput() throws Exception
+  {
+    // quick test that sequence description is exported & reimported
+
+    SequenceI sq = new Sequence("FER2_SPIOL", "AASSDDDFFF");
+    String expected_descr = "This is a description !@&^%@£@";
+    sq.setDescription(expected_descr);
+    AppletFormatAdapter af = new AppletFormatAdapter();
+    String toStockholm = af.formatSequences(FileFormat.Stockholm,
+            new Alignment(new SequenceI[]
+            { sq }), false);
+    System.out.println(toStockholm);
+
+    // bleh - java.util.Regex sucks
+    assertTrue(toStockholm.contains(expected_descr),
+            "Couldn't locate expected description srting in generated Stockholm file.");
+
+    AlignmentI fromStockholm = af.readFile(toStockholm,
+            DataSourceType.PASTE, FileFormat.Stockholm);
+    SequenceI importedSeq = fromStockholm.getSequenceAt(0);
+    assertEquals("Description did not get reimported.", expected_descr,
+            importedSeq.getDescription());
+  }
+
   /**
    * test alignment data in given file can be imported, exported and reimported
    * with no dataloss
index 9946f4c..288444e 100644 (file)
  */
 package jalview.io.cache;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.LinkedHashSet;
 
+import javax.swing.SwingUtilities;
+
 import org.junit.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -54,11 +57,19 @@ public class JvCacheableInputBoxTest
 
     try
     {
-      // This delay is essential to prevent the
-      // assertion below from executing before
-      // swing thread finishes updating the combo-box
-      Thread.sleep(350);
-    } catch (InterruptedException e)
+      // fix for JAL-4153
+      // This delay is essential to prevent the assertion below from executing
+      // before swing thread finishes updating the combo-box
+      SwingUtilities.invokeAndWait(() -> {
+        try
+        {
+          Thread.sleep(1);
+        } catch (InterruptedException e)
+        {
+          e.printStackTrace();
+        }
+      });
+    } catch (InvocationTargetException | InterruptedException e)
     {
       e.printStackTrace();
     }
@@ -73,12 +84,21 @@ public class JvCacheableInputBoxTest
     cacheBox.addItem(testInput);
     cacheBox.setSelectedItem(testInput);
     cacheBox.updateCache();
+
     try
     {
-      // This delay is to let
-      // cacheBox.updateCache() finish updating the cache
-      Thread.sleep(350);
-    } catch (InterruptedException e)
+      // fix for JAL-4153
+      // This delay is to let cacheBox.updateCache() finish updating the cache
+      SwingUtilities.invokeAndWait(() -> {
+        try
+        {
+          Thread.sleep(1);
+        } catch (InterruptedException e)
+        {
+          e.printStackTrace();
+        }
+      });
+    } catch (InvocationTargetException | InterruptedException e)
     {
       e.printStackTrace();
     }
index 81756e0..c9532cc 100644 (file)
@@ -32,7 +32,9 @@ import java.awt.Color;
 import java.awt.Rectangle;
 import java.io.File;
 import java.io.IOException;
+import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.BitSet;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -59,6 +61,7 @@ import jalview.datamodel.ContactMatrix;
 import jalview.datamodel.ContactMatrixI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.GeneLocus;
+import jalview.datamodel.GroupSet;
 import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.PDBEntry;
@@ -100,6 +103,7 @@ import jalview.util.MapList;
 import jalview.util.matcher.Condition;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.seqfeatures.FeatureRendererModel;
+import jalview.ws.datamodel.MappableContactMatrixI;
 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 
 @Test(singleThreaded = true)
@@ -110,6 +114,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   @BeforeClass(alwaysRun = true)
   public void setUpJvOptionPane()
   {
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
     JvOptionPane.setInteractiveMode(false);
     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
   }
@@ -243,9 +249,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
     boolean diffseqcols = false, diffgseqcols = false;
     SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
-    for (int p = 0,
-            pSize = af.getViewport().getAlignment().getWidth(); p < pSize
-                    && (!diffseqcols || !diffgseqcols); p++)
+    for (int p = 0, pSize = af.getViewport().getAlignment()
+            .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
     {
       if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
               .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
@@ -264,9 +269,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     assertTrue(__rcs.isSeqAssociated(),
             "Group Annotation colourscheme wasn't sequence associated");
 
-    for (int p = 0,
-            pSize = af.getViewport().getAlignment().getWidth(); p < pSize
-                    && (!diffseqcols || !diffgseqcols); p++)
+    for (int p = 0, pSize = af.getViewport().getAlignment()
+            .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
     {
       if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
               0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
@@ -1559,18 +1563,48 @@ public class Jalview2xmlTests extends Jalview2xmlBase
       {
         paevals[i][j] = ((i - j < 2)
                 || ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
-        paevals[j][i] = paevals[i][j];
+        paevals[j][i] = -paevals[i][j];
       }
     }
     PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
     String content = ContactMatrix.contactToFloatString(dummyMat);
-    Assert.assertTrue(content.contains("\t1.")); // at least one element must be 1
-    float[][] vals = ContactMatrix.fromFloatStringToContacts(content, sq.getLength(), sq.getLength());
-    assertEquals(vals[3][4],paevals[3][4]);
-    dummyMat.makeGroups(0.5f, false);
+    Assert.assertTrue(content.contains("\t1.")); // at least one element must be
+                                                 // 1
+    float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
+            sq.getLength(), sq.getLength());
+    assertEquals(vals[3][4], paevals[3][4]);
+    assertEquals(vals[4][3], paevals[4][3]);
+    dummyMat.setGroupSet(GroupSet.makeGroups(dummyMat, false,0.5f, false));
     Assert.assertNotSame(dummyMat.getNewick(), "");
     AlignmentAnnotation paeCm = sq.addContactList(dummyMat);
     al.addAnnotation(paeCm);
+    // verify store/restore of group bitsets
+    for (BitSet gp : dummyMat.getGroups())
+    {
+      StringBuilder sb = new StringBuilder();
+      for (long val : gp.toLongArray())
+      {
+        if (sb.length() > 0)
+        {
+          sb.append(",");
+        }
+        sb.append(val);
+      }
+      String[] longvals = sb.toString().split(",");
+      long[] newlongvals = new long[longvals.length];
+      for (int lv = 0; lv < longvals.length; lv++)
+      {
+        try
+        {
+          newlongvals[lv] = Long.valueOf(longvals[lv]);
+        } catch (Exception x)
+        {
+          Assert.fail("failed to deserialise bitset element ");
+        }
+      }
+      BitSet newGp = BitSet.valueOf(newlongvals);
+      assertTrue(gp.equals(newGp));
+    }
     File tfile = File.createTempFile("testStoreAndRecoverPAEmatrix",
             ".jvp");
     new Jalview2XML(false).saveState(tfile);
@@ -1590,21 +1624,28 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     ContactMatrixI restoredMat = newSeq
             .getContactMatrixFor(newSeq.getAnnotation()[0]);
     Assert.assertNotNull(restoredMat);
+    MapList oldMap = ((MappableContactMatrixI) dummyMat).getMapFor(sq);
+    MapList newMap = ((MappableContactMatrixI) restoredMat)
+            .getMapFor(newSeq);
+    Assert.assertEquals(oldMap.getFromRanges(), newMap.getFromRanges());
+    Assert.assertEquals(oldMap.getToRanges(), newMap.getToRanges());
+    Assert.assertEquals(oldMap.getFromRatio(), newMap.getFromRatio());
+    Assert.assertEquals(oldMap.getToRatio(), newMap.getToRatio());
     for (i = sq.getLength() - 1; i >= 0; i--)
     {
       ContactListI oldCM = dummyMat.getContactList(i),
               newCM = restoredMat.getContactList(i);
       for (int j = oldCM.getContactHeight(); j >= 0; j--)
       {
-        Assert.assertEquals(oldCM.getContactAt(j), newCM.getContactAt(j));
+        double old_j = oldCM.getContactAt(j);
+        double new_j = newCM.getContactAt(j);
+        Assert.assertEquals(old_j, new_j);
       }
     }
     Assert.assertEquals(restoredMat.hasGroups(), dummyMat.hasGroups());
     Assert.assertEquals(restoredMat.getGroups(), dummyMat.getGroups());
     Assert.assertEquals(restoredMat.hasTree(), dummyMat.hasTree());
-    Assert.assertEquals( restoredMat.getNewick(),dummyMat.getNewick());
-    
-    
+    Assert.assertEquals(restoredMat.getNewick(), dummyMat.getNewick());
   }
 
 }
index cdb69e3..829eec5 100644 (file)
@@ -47,8 +47,8 @@ public class OverviewRendererTest
   public void testGetColumnColourFromSequence()
   {
     // gapColour, residueColour, hiddenColour
-    OverviewResColourFinder cf = new OverviewResColourFinder(
-            Color.PINK, Color.white, Color.green); 
+    OverviewResColourFinder cf = new OverviewResColourFinder(Color.PINK,
+            Color.white, Color.green);
     Sequence seq1 = new Sequence("seq1", "PQ-RL-");
     Sequence seq2 = new Sequence("seq2", "FVE");
     AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
index 028777e..1c9daea 100644 (file)
@@ -186,7 +186,8 @@ public class OverviewResColourFinderTest
             av.getResidueShading(), groups, seq, 2, null));
 
     // use legacy colouring
-    rcf = new OverviewResColourFinder(Color.white, Color.lightGray, Color.red);
+    rcf = new OverviewResColourFinder(Color.white, Color.lightGray,
+            Color.red);
 
     // G in group specified as magenta in Zappo
     assertEquals(Color.magenta, rcf.getResidueColour(false,
@@ -237,7 +238,8 @@ public class OverviewResColourFinderTest
     assertEquals(OverviewCanvas.OVERVIEW_DEFAULT_GAP, c);
 
     // legacy colouring set explicitly via constructor
-    rcf = new OverviewResColourFinder(Color.white, Color.lightGray, Color.red);
+    rcf = new OverviewResColourFinder(Color.white, Color.lightGray,
+            Color.red);
     shader = new ResidueShader();
 
     // residues light gray
@@ -273,7 +275,8 @@ public class OverviewResColourFinderTest
     assertEquals(Color.blue, c);
 
     // legacy colouring with colour scheme
-    rcf = new OverviewResColourFinder(Color.white, Color.lightGray, Color.red);
+    rcf = new OverviewResColourFinder(Color.white, Color.lightGray,
+            Color.red);
 
     // M residue pink
     c = rcf.getBoxColour(shader, seq, 0);
index 637bbf4..3d8313d 100644 (file)
@@ -169,7 +169,8 @@ public class FeatureColourFinderTest
   @Test(groups = "Functional")
   public void testFindFeatureColour_nestedFeatures()
   {
-    SequenceFeature sf1 = new SequenceFeature("domain", "peptide", 1, 120, 0f, null);
+    SequenceFeature sf1 = new SequenceFeature("domain", "peptide", 1, 120,
+            0f, null);
     seq.addSequenceFeature(sf1);
     SequenceFeature sf2 = new SequenceFeature("domain", "binding", 10, 20,
             0f, null);
index a3d0a7c..944f147 100644 (file)
@@ -27,6 +27,16 @@ import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
 import jalview.analysis.GeneticCodes;
 import jalview.api.AlignViewportI;
 import jalview.api.FeatureColourI;
@@ -46,17 +56,14 @@ import jalview.schemes.FeatureColour;
 import jalview.util.matcher.Condition;
 import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean;
 
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.testng.annotations.Test;
-
 public class FeatureRendererTest
 {
+  @BeforeMethod(alwaysRun = true)
+  public void closeAll()
+  {
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
+  }
 
   @Test(groups = "Functional")
   public void testFindAllFeatures()
index 58e272d..0184f12 100644 (file)
@@ -25,6 +25,14 @@ import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
+import java.awt.Color;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
 import jalview.api.AlignViewportI;
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
@@ -38,14 +46,6 @@ import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
 import jalview.schemes.ClustalxColourScheme.ClustalColour;
 
-import java.awt.Color;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
 public class ColourSchemesTest
 {
   /*
@@ -192,7 +192,8 @@ public class ColourSchemesTest
   @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
   }
 
   @Test(groups = "Functional")
index ac8235d..624548f 100644 (file)
@@ -204,7 +204,8 @@ public class StructureSelectionManagerTest extends Jalview2xmlBase
   {
     // for some reason 'BeforeMethod' (which should be inherited from
     // Jalview2XmlBase isn't always called)...
-    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.instance != null)
+      Desktop.instance.closeAll_actionPerformed(null);
     try
     {
       Thread.sleep(200);
index 95da22e..fc58822 100644 (file)
@@ -83,3 +83,4 @@ USE_PROXY=false
 WRAP_ALIGNMENT=false
 #DAS_REGISTRY_URL=http\://www.dasregistry.org/das/ # retired 01/05/2015
 DAS_REGISTRY_URL=http\://www.ebi.ac.uk/das-srv/registry/das/
+SPLASH=false
diff --git a/test/jalview/util/FileUtilsTest.java b/test/jalview/util/FileUtilsTest.java
new file mode 100644 (file)
index 0000000..35853b0
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class FileUtilsTest
+{
+  @Test(groups = "Functional", dataProvider = "patternsAndMinNumFiles")
+  public void testJavaFileGlob(String pattern, int atLeast, int atMost)
+  {
+    List<File> files = FileUtils.getFilesFromGlob(pattern);
+    if (atLeast != -1)
+    {
+      Assert.assertTrue(files.size() > atLeast,
+              "Did not find more than " + atLeast + " files with " + pattern
+                      + " (found " + files.size() + ")");
+    }
+    if (atLeast != -1)
+    {
+      Assert.assertTrue(files.size() > atLeast,
+              "Did not find more than " + atLeast + " files with " + pattern
+                      + " (found " + files.size() + ")");
+    }
+    if (atMost != -1)
+    {
+      Assert.assertTrue(files.size() < atMost,
+              "Did not find fewer than " + atMost + " files with " + pattern
+                      + " (found " + files.size() + ")");
+    }
+  }
+
+  @Test(groups = "Functional", dataProvider = "dirnamesAndBasenames")
+  public void testDirnamesAndBasenames(String filename, int where,
+          String dirname, String basename, String notInDirname)
+  {
+    File file = new File(filename);
+    String d = FileUtils.getDirname(file);
+    String b = FileUtils.getBasename(file);
+    Assert.assertEquals(b, basename);
+    if (where == 0)
+      Assert.assertEquals(d, dirname);
+    else if (where < 0)
+      Assert.assertTrue(d.startsWith(dirname),
+              "getDirname(" + file.getPath() + ")=" + d
+                      + " didn't start with '" + dirname + "'");
+    else if (where > 0)
+      Assert.assertTrue(d.endsWith(dirname), "getDirname(" + file.getPath()
+              + ")=" + d + " didn't end with '" + d + "'");
+
+    // ensure dirname doesn't end with basename (which means you can't use same
+    // filename as dir in tests!)
+    Assert.assertFalse(d.endsWith(b));
+
+    if (notInDirname != null)
+      Assert.assertFalse(d.contains(notInDirname));
+  }
+
+  @DataProvider(name = "patternsAndMinNumFiles")
+  public Object[][] patternsAndMinNumFiles()
+  {
+    return new Object[][] { { "src/**/*.java", 900, 100000 },
+        { "src/**.java", 900, 100000 },
+        { "test/**/*.java", 250, 2500 },
+        { "test/**.java", 250, 2500 },
+        { "help/**/*.html", 100, 1000 },
+        { "test/**/F*.java", 15, 150 },
+        { "test/jalview/*/F*.java", 10, 15 }, // 12 at time of writing
+        { "test/jalview/**/F*.java", 18, 30 }, // 20 at time of writing
+        { "test/jalview/util/F**.java", 1, 5 }, // 2 at time of writing
+        { "src/jalview/b*/*.java", 14, 19 }, // 15 at time of writing
+        { "src/jalview/b**/*.java", 20, 25 }, // 22 at time of writing
+    };
+  }
+
+  @DataProvider(name = "dirnamesAndBasenames")
+  public Object[][] dirnamesAndBasenames()
+  {
+    String homeDir = null;
+    try
+    {
+      homeDir = new File(System.getProperty("user.home"))
+              .getCanonicalPath();
+    } catch (IOException e)
+    {
+      System.err.println("Problem getting canonical home dir");
+      e.printStackTrace();
+    }
+    return new Object[][] { // -1=startsWith, 0=equals, 1=endsWith
+        { "~/hello/sailor", -1, homeDir, "sailor", "~" }, //
+        { "~/hello/sailor", 1, "/hello", "sailor", "~" }, //
+        { "./examples/uniref50.fa", -1, "/", "uniref50", "." }, //
+        { "./examples/uniref50.fa", 1, "/examples", "uniref50", "." }, //
+        { "examples/uniref50.fa", 1, "/examples", "uniref50", ".fa" }, //
+    };
+  }
+}
diff --git a/test/jalview/util/imagemaker/BitmapImageSizeTest.java b/test/jalview/util/imagemaker/BitmapImageSizeTest.java
new file mode 100644 (file)
index 0000000..49e1084
--- /dev/null
@@ -0,0 +1,43 @@
+package jalview.util.imagemaker;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+import jalview.bin.Cache;
+
+public class BitmapImageSizeTest {
+  @Test(groups = {"Functional"})
+  public void testCacheSettingsRecovery() {
+    Cache.setPropsAreReadOnly(true);
+    Cache.loadProperties("test/jalview/bin/testProps.jvprops");
+    
+    Cache.removeProperty(BitmapImageSizing.BITMAP_HEIGHT);
+    Cache.removeProperty(BitmapImageSizing.BITMAP_SCALE);
+    Cache.removeProperty(BitmapImageSizing.BITMAP_WIDTH);
+    
+    BitmapImageSizing def = BitmapImageSizing.defaultBitmapImageSizing();
+    BitmapImageSizing zero = BitmapImageSizing.nullBitmapImageSizing();
+
+    assertEquals(def.height, zero.height);
+    assertEquals(def.width, zero.width);
+    assertEquals(def.scale, zero.scale);
+    
+    Cache.setProperty(BitmapImageSizing.BITMAP_HEIGHT,"120");
+    Cache.setProperty(BitmapImageSizing.BITMAP_SCALE,"240");
+    Cache.setProperty(BitmapImageSizing.BITMAP_WIDTH,"360");
+    
+    def = BitmapImageSizing.defaultBitmapImageSizing();
+    
+    assertEquals(def.height, 120);
+    assertEquals(def.width, 360);
+    assertEquals(def.scale, 24f);
+    
+    Cache.removeProperty(BitmapImageSizing.BITMAP_WIDTH);
+    
+    def = BitmapImageSizing.defaultBitmapImageSizing();
+    assertEquals(def.height, 120);
+    assertEquals(def.width, zero.width);
+    assertEquals(def.scale, 24f);    
+  }
+}
index e619b8e..8cba8ab 100644 (file)
@@ -1,14 +1,25 @@
 package jalview.ws.dbsources;
 
+import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 
-import org.junit.Assert;
+import org.json.simple.parser.ParseException;
+import org.testng.Assert;
+import org.testng.FileAssert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.gui.Desktop;
 import jalview.gui.JvOptionPane;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 
 public class EBIAlphaFoldTest
@@ -24,11 +35,13 @@ public class EBIAlphaFoldTest
   @DataProvider(name = "getExamplePAEfiles")
   public Object[][] getExamplePAEfiles()
   {
-    return new String[][] { {
-        "examples/test_fab41.result/test_fab41_predicted_aligned_error_v1.json" },
+    return new String[][] {
+        //
+        { "examples/test_fab41.result/test_fab41_predicted_aligned_error_v1.json" },
         { "examples/AlphaFold/AF-A0A1U8FD60-F1-predicted_aligned_error_v4.json" },
         { "examples/AlphaFold/AF-Q5VSL9-F1-predicted_aligned_error_v4.json" },
-        { "examples/AlphaFold/AF-Q5VSL9-F1-predicted_aligned_error_v4_2023.json" } };
+        //
+    };
   }
 
   @Test(groups = { "Functional" }, dataProvider = "getExamplePAEfiles")
@@ -38,6 +51,60 @@ public class EBIAlphaFoldTest
             new Sequence("Dummy/1-2000", "ASDASDA"),
             EBIAlfaFold.parseJSONtoPAEContactMatrix(
                     new FileInputStream(paeFile)));
-    Assert.assertNotEquals("No data from " + paeFile, cm.getMax(), 0);
+    Assert.assertNotEquals(cm.getMax(), 0.0f, "No data from " + paeFile);
   }
+
+  @Test(groups = { "Functional" }, dataProvider = "getPDBandPAEfiles")
+  public void checkImportPAEToStructure(String pdbFile, String paeFile)
+  {
+    FileInputStream paeInput = null;
+    try
+    {
+      paeInput = new FileInputStream(paeFile);
+    } catch (FileNotFoundException e)
+    {
+      e.printStackTrace();
+      FileAssert.assertFile(new File(paeFile),
+              "Test file '" + paeFile + "' doesn't seem to exist");
+    }
+    SequenceI seq = new Sequence("Dummy/1-2000", "ASDASDA");
+    AlignmentI al = new Alignment(new SequenceI[] { seq });
+    StructureSelectionManager ssm = StructureSelectionManager
+            .getStructureSelectionManager(Desktop.instance);
+    StructureMapping sm = new StructureMapping(seq, pdbFile, null, null,
+            null, null);
+    ssm.addStructureMapping(sm);
+
+    StructureMapping[] smArray = ssm.getMapping(pdbFile);
+
+    try
+    {
+      boolean done = EBIAlfaFold.importPaeJSONAsContactMatrixToStructure(
+              smArray, paeInput, "label");
+      Assert.assertTrue(done,
+              "Import of '" + paeFile + "' didn't complete successfully");
+    } catch (IOException | ParseException e)
+    {
+      Assert.fail("Exception importing paefile '" + paeFile + "'", e);
+    }
+  }
+
+  @DataProvider(name = "getPDBandPAEfiles")
+  public Object[][] getPDBandPAEfiles()
+  {
+    return new String[][] {
+        //
+        /*
+         */
+        { "examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb",
+            "examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json" },
+        { "examples/AlphaFold/AF-A0A1U8FD60-F1-model_v4.pdb",
+            "examples/AlphaFold/AF-A0A1U8FD60-F1-predicted_aligned_error_v4.json" },
+        { "examples/AlphaFold/AF-Q5VSL9-F1-model_v4.pdb",
+            "examples/AlphaFold/AF-Q5VSL9-F1-predicted_aligned_error_v4.json" },
+        /*
+         */
+    };
+  }
+
 }
index 44a6a02..0f5bd4d 100644 (file)
@@ -195,8 +195,10 @@ public class SiftsClientTest
     SiftsSettings.setCacheThresholdInDays("2");
     SiftsSettings.setFailSafePIDThreshold("70");
     PDBfile pdbFile;
+    
     pdbFile = new PDBfile(false, false, false,
             "test/jalview/io/" + testPDBId + ".pdb", DataSourceType.FILE);
+    // TODO: this uses a network connection - we should mock the sifts testPDBId.xml.gz
     siftsClient = new SiftsClient(pdbFile);
   }
 
@@ -205,6 +207,12 @@ public class SiftsClientTest
   {
     siftsClient = null;
   }
+  
+  @Test(groups= {"Functional"})
+  public void testSIFTsDownloadURL() {
+    String expectedUrl = "https://ftp.ebi.ac.uk/pub/databases/msd/sifts/split_xml/xy/1xyz.sifts.xml.gz";
+    Assert.assertEquals(SiftsClient.getDownloadUrlFor("1xyz.sifts.xml.gz"), expectedUrl);
+  }
 
   @Test(groups = { "Network" })
   public void getSIFTsFileTest() throws SiftsException, IOException
@@ -215,7 +223,7 @@ public class SiftsClientTest
     long t1 = siftsFile.lastModified();
 
     // re-read file should be returned from cache
-    siftsFile = SiftsClient.downloadSiftsFile(testPDBId);
+    siftsFile = SiftsClient.getSiftsFile(testPDBId);
     FileAssert.assertFile(siftsFile);
     long t2 = siftsFile.lastModified();
     assertEquals(t1, t2);
@@ -368,7 +376,7 @@ public class SiftsClientTest
   {
     SequenceI invalidTestSeq = new Sequence("testSeq", "ABCDEFGH");
     DBRefEntry invalidDBRef = new DBRefEntry();
-    invalidDBRef.setAccessionId("BLAR");
+    invalidDBRef.setAccessionId("BLAR"); // note no version is set, so also invalid
     invalidTestSeq.addDBRef(invalidDBRef);
     siftsClient.getValidSourceDBRef(invalidTestSeq);
   }
diff --git a/utils/biotools/Jalview.json b/utils/biotools/Jalview.json
new file mode 100644 (file)
index 0000000..69aa95c
--- /dev/null
@@ -0,0 +1,417 @@
+{
+  "name": "Jalview",
+  "description": "Jalview is a free program for multiple sequence alignment editing, visualisation and analysis. Use it to view and edit sequence alignments, analyse them with phylogenetic trees and principal components analysis (PCA) plots and explore molecular structures and annotation.",
+  "homepage": "https://www.jalview.org/",
+  "biotoolsID": "Jalview",
+  "biotoolsCURIE": "biotools:Jalview",
+  "version": [
+    "2.11.2.7"
+  ],
+  "relation": [
+    {
+      "biotoolsID": "jabaws",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "chimera",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "chimerax",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "pymol",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "bioconda",
+      "type": "includedIn"
+    },
+    {
+      "biotoolsID": "3d-beacons",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "uniprot",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "pfam",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "ensembl",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "pdb",
+      "type": "uses"
+    },
+    {
+      "biotoolsID": "rfam",
+      "type": "uses"
+    }
+  ],
+  "function": [
+    {
+      "operation": [
+        {
+          "uri": "http://edamontology.org/operation_0564",
+          "term": "Sequence visualisation"
+        },
+        {
+          "uri": "http://edamontology.org/operation_0324",
+          "term": "Phylogenetic tree analysis"
+        },
+        {
+          "uri": "http://edamontology.org/operation_3081",
+          "term": "Sequence alignment editing"
+        }
+      ],
+      "input": [
+        {
+          "data": {
+            "uri": "http://edamontology.org/data_0863",
+            "term": "Sequence alignment"
+          },
+          "format": [
+            {
+              "uri": "http://edamontology.org/format_1939",
+              "term": "GFF3-seq"
+            },
+            {
+              "uri": "http://edamontology.org/format_1982",
+              "term": "ClustalW format"
+            },
+            {
+              "uri": "http://edamontology.org/format_1961",
+              "term": "Stockholm format"
+            },
+            {
+              "uri": "http://edamontology.org/format_1984",
+              "term": "FASTA-aln"
+            },
+            {
+              "uri": "http://edamontology.org/format_1938",
+              "term": "GFF2-seq"
+            },
+            {
+              "uri": "http://edamontology.org/format_1929",
+              "term": "FASTA"
+            },
+            {
+              "uri": "http://edamontology.org/format_1948",
+              "term": "nbrf/pir"
+            },
+            {
+              "uri": "http://edamontology.org/format_3774",
+              "term": "BioJSON (Jalview)"
+            },
+            {
+              "uri": "http://edamontology.org/format_1997",
+              "term": "PHYLIP format"
+            },
+            {
+              "uri": "http://edamontology.org/format_3313",
+              "term": "BLC"
+            },
+            {
+              "uri": "http://edamontology.org/format_3311",
+              "term": "RNAML"
+            },
+            {
+              "uri": "http://edamontology.org/format_1947",
+              "term": "GCG MSF"
+            },
+            {
+              "uri": "http://edamontology.org/format_3015",
+              "term": "Pileup"
+            },
+            {
+              "uri": "http://edamontology.org/format_1477",
+              "term": "mmCIF"
+            },
+            {
+              "uri": "http://edamontology.org/format_3016",
+              "term": "VCF"
+            },
+            {
+              "uri": "http://edamontology.org/format_1915",
+              "term": "Format"
+            }
+          ]
+        },
+        {
+          "data": {
+            "uri": "http://edamontology.org/data_0886",
+            "term": "Structure alignment"
+          },
+          "format": [
+            {
+              "uri": "http://edamontology.org/format_1476",
+              "term": "PDB"
+            }
+          ]
+        }
+      ],
+      "output": [
+        {
+          "data": {
+            "uri": "http://edamontology.org/data_0863",
+            "term": "Sequence alignment"
+          },
+          "format": [
+            {
+              "uri": "http://edamontology.org/format_1948",
+              "term": "nbrf/pir"
+            },
+            {
+              "uri": "http://edamontology.org/format_3464",
+              "term": "JSON"
+            },
+            {
+              "uri": "http://edamontology.org/format_1961",
+              "term": "Stockholm format"
+            },
+            {
+              "uri": "http://edamontology.org/format_1929",
+              "term": "FASTA"
+            },
+            {
+              "uri": "http://edamontology.org/format_1997",
+              "term": "PHYLIP format"
+            },
+            {
+              "uri": "http://edamontology.org/format_3313",
+              "term": "BLC"
+            },
+            {
+              "uri": "http://edamontology.org/format_3774",
+              "term": "BioJSON (Jalview)"
+            },
+            {
+              "uri": "http://edamontology.org/format_1947",
+              "term": "GCG MSF"
+            },
+            {
+              "uri": "http://edamontology.org/format_3015",
+              "term": "Pileup"
+            },
+            {
+              "uri": "http://edamontology.org/format_1982",
+              "term": "ClustalW format"
+            }
+          ]
+        },
+        {
+          "data": {
+            "uri": "http://edamontology.org/data_2884",
+            "term": "Plot"
+          },
+          "format": [
+            {
+              "uri": "http://edamontology.org/format_3603",
+              "term": "PNG"
+            },
+            {
+              "uri": "http://edamontology.org/format_2331",
+              "term": "HTML"
+            },
+            {
+              "uri": "http://edamontology.org/format_3466",
+              "term": "EPS"
+            },
+            {
+              "uri": "http://edamontology.org/format_3604",
+              "term": "SVG"
+            },
+            {
+              "uri": "http://edamontology.org/format_1915",
+              "term": "Format"
+            }
+          ]
+        }
+      ],
+      "note": "Other Input formats:\nAMSA (.amsa);\nJnetFile (.concise, .jnet);\nPFAM (.pfam);\nSubstitution matrix (.matrix);\nJalview Project File (.jvp);\nJalview Feature File (.features, .jvfeatures);\nJalview Annotations File (.annotations, .jvannotations);\n\n...\nOther Output formats:\nPFAM (.pfam);\nBioJS (.biojs) (interactive HTML/Javascript);\nJalview Project File (.jvp);"
+    }
+  ],
+  "toolType": [
+    "Desktop application"
+  ],
+  "topic": [
+    {
+      "uri": "http://edamontology.org/topic_0080",
+      "term": "Sequence analysis"
+    },
+    {
+      "uri": "http://edamontology.org/topic_0092",
+      "term": "Data visualisation"
+    }
+  ],
+  "operatingSystem": [
+    "Linux",
+    "Windows",
+    "Mac"
+  ],
+  "license": "GPL-3.0",
+  "maturity": "Mature",
+  "cost": "Free of charge",
+  "accessibility": "Open access",
+  "elixirPlatform": [
+    "Tools"
+  ],
+  "elixirNode": [
+    "UK"
+  ],
+  "link": [
+    {
+      "url": "https://discourse.jalview.org/",
+      "type": [
+        "Discussion forum"
+      ]
+    },
+    {
+      "url": "https://issues.jalview.org/",
+      "type": [
+        "Issue tracker"
+      ]
+    },
+    {
+      "url": "https://www.jalview.org/development/jalview_develop/",
+      "type": [
+        "Other"
+      ],
+      "note": "Latest development version"
+    },
+    {
+      "url": "https://source.jalview.org/crucible/browse/jalview",
+      "type": [
+        "Repository"
+      ]
+    },
+    {
+      "url": "https://twitter.com/Jalview",
+      "type": [
+        "Social media"
+      ],
+      "note": "Twitter feed"
+    },
+    {
+      "url": "https://www.youtube.com/channel/UCIjpnvZB770yz7ftbrJ0tfw",
+      "type": [
+        "Social media"
+      ],
+      "note": "YouTube training videos"
+    }
+  ],
+  "download": [
+    {
+      "url": "https://www.jalview.org/download",
+      "type": "Downloads page"
+    },
+    {
+      "url": "https://www.jalview.org/download/source/",
+      "type": "Source code"
+    },
+    {
+      "url": "https://www.jalview.org/download/?os=all",
+      "type": "Binaries",
+      "note": "Binaries for all platforms"
+    },
+    {
+      "url": "https://www.jalview.org/favicon.svg",
+      "type": "Icon"
+    },
+    {
+      "url": "https://www.jalview.org/download/other/jar/",
+      "type": "Binaries",
+      "note": "Executable JAR file"
+    }
+  ],
+  "documentation": [
+    {
+      "url": "https://www.jalview.org/about/citation",
+      "type": [
+        "Citation instructions"
+      ]
+    },
+    {
+      "url": "https://www.jalview.org/training/",
+      "type": [
+        "Training material"
+      ],
+      "note": "Hands-on exercises, Training courses and Training videos"
+    },
+    {
+      "url": "https://www.jalview.org/help/faq",
+      "type": [
+        "FAQ"
+      ]
+    },
+    {
+      "url": "https://www.jalview.org/help/documentation/",
+      "type": [
+        "User manual"
+      ]
+    }
+  ],
+  "publication": [
+    {
+      "doi": "10.1093/bioinformatics/btp033",
+      "metadata": {
+        "title": "Jalview Version 2-A multiple sequence alignment editor and analysis workbench",
+        "abstract": "Summary: Jalview Version 2 is a system for interactive WYSIWYG editing, analysis and annotation of multiple sequence alignments. Core features include keyboard and mouse-based editing, multiple views and alignment overviews, and linked structure display with Jmol. Jalview 2 is available in two forms: a lightweight Java applet for use in web applications, and a powerful desktop application that employs web services for sequence alignment, secondary structure prediction and the retrieval of alignments, sequences, annotation and structures from public databases and any DAS 1.53 compliant sequence or annotation server. © 2009 The Author(s).",
+        "date": "2009-05-07T00:00:00Z",
+        "citationCount": 5999,
+        "authors": [
+          {
+            "name": "Waterhouse A.M."
+          },
+          {
+            "name": "Procter J.B."
+          },
+          {
+            "name": "Martin D.M.A."
+          },
+          {
+            "name": "Clamp M."
+          },
+          {
+            "name": "Barton G.J."
+          }
+        ],
+        "journal": "Bioinformatics"
+      }
+    }
+  ],
+  "credit": [
+    {
+      "name": "Jim Procter",
+      "url": "http://www.lifesci.dundee.ac.uk/people/jim-procter",
+      "orcidid": "https://orcid.org/0000-0002-7865-7382",
+      "typeEntity": "Person",
+      "typeRole": [
+        "Primary contact"
+      ]
+    },
+    {
+      "name": "Geoff Barton",
+      "url": "https://www.lifesci.dundee.ac.uk/people/geoff-barton",
+      "orcidid": "https://orcid.org/0000-0002-9014-5355"
+    }
+  ],
+  "owner": "ben_s",
+  "additionDate": "2019-02-13T17:01:40Z",
+  "lastUpdate": "2023-07-22T09:24:44.755337Z",
+  "editPermission": {
+    "type": "group",
+    "authors": [
+      "ben_s",
+      "jimprocter"
+    ]
+  },
+  "validated": 1,
+  "homepage_status": 0,
+  "elixir_badge": 0
+}
diff --git a/utils/biotools/README.md b/utils/biotools/README.md
new file mode 100644 (file)
index 0000000..948a751
--- /dev/null
@@ -0,0 +1,13 @@
+This is the JSON representation of the latest Jalview release's record on bio.tools
+
+To update:
+1. go to https://bio.tools/Jalview
+2. log in and scroll down to the 'Update Record' button to open the edit interface.
+3. Make any chances to the entry - press Validate to ensure all is good
+4. Select the JSON tab and copy paste into
+
+``
+cat > utils/biotools/Jalview.json
+``
+
+Thanks to Herve Menager for the tutorial on storing bio.tools records with the tool's software repository at [CoFest 2023](https://www.open-bio.org/events/bosc-2023/obf-bosc-collaborationfest-2023)
\ No newline at end of file
diff --git a/utils/conda/jalview.sh b/utils/conda/jalview.sh
new file mode 100755 (executable)
index 0000000..995195f
--- /dev/null
@@ -0,0 +1,178 @@
+#!/usr/bin/env bash
+
+###############################
+# Wrapper for Jalview
+#
+# 2023-08-16 Jalview 2.11.3.0 has new command line arguments
+# Old command line arguments are currently detected and actioned
+# but are no longer supported and will be removed at a later date.
+#
+# See
+#   Jalview -> Help -> Documentation -> Command Line -> introduction and reference
+# or
+#   https://www.jalview.org/help/html/features/clarguments.html
+# for details of the new command line arguments.
+#
+# Note, in order to run commandline-only calls use
+#   --headless
+#
+# By default, this wrapper executes java -version to determine the JRE version
+# Set JALVIEW_JRE=j1.8 or JALVIEW_JRE=j11 to skip the version check.
+#
+# By default, this wrapper does NOT restrict the memory consumption of Jalview.
+# Set eg. JALVIEW_MAXMEM=1g to set the maximal memory of Jalview's VM
+#
+# This script is maintained in the Jalview repository in utils/conda/jalview.sh
+###############################
+
+declare -a ARGS=("${@}")
+ARG1=$1
+
+# this function is because there's no readlink -f in Darwin/macOS
+function readlinkf() {
+  FINDFILE="$1"
+  FILE="${FINDFILE}"
+  PREVFILE=""
+  C=0
+  MAX=100 # just in case we end up in a loop
+  FOUND=0
+  while [ "${C}" -lt "${MAX}" -a "${FILE}" != "${PREVFILE}" -a "${FOUND}" -ne 1 ]; do
+    PREVFILE="${FILE}"
+    FILE="$(readlink "${FILE}")"
+    if [ -z "${FILE}" ]; then
+      # the readlink is empty means we've arrived at the script, let's canonicalize with pwd
+      FILE="$(cd "$(dirname "${PREVFILE}")" &> /dev/null && pwd -P)"/"$(basename "${PREVFILE}")"
+      FOUND=1
+    elif [ "${FILE#/}" = "${FILE}" ]; then
+      # FILE is not an absolute path link, we need to add the relative path to the previous dir
+      FILE="$(dirname "${PREVFILE}")/${FILE}"
+    fi
+    C=$((C+1))
+  done
+  if [ "${FOUND}" -ne 1 ]; then
+    echo "Could not determine path to actual file '$(basename "${FINDFILE}")'" >&2
+    exit 1
+  fi
+  echo "${FILE}"
+}
+
+ISMACOS=0
+if [ "$( uname -s )" = "Darwin" ]; then
+  ISMACOS=1
+fi
+
+# check for headless mode
+HEADLESS=0
+GUI=0
+HELP=0
+DEBUG=0
+for RAWARG in "${@}"; do
+  ARG="${RAWARG%%=*}"
+  case "${ARG}" in
+    --headless|--output|--image|--structureimage)
+      HEADLESS=1
+      ;;
+    --help|--help-*|--version)
+      HELP=1
+      ;;
+    --gui)
+      GUI=1
+      ;;
+    --debug)
+      DEBUG=1
+      ;;
+  esac
+  
+  if [ "${HELP}" = 1 ]; then
+    # --help takes precedence
+    HEADLESS=1
+    GUI=0
+  elif [ "${GUI}" = 1 ]; then
+    # --gui takes precedence over --headless
+    HEADLESS=0
+  fi
+done
+
+declare -a JVMARGS=()
+
+# set vars for being inside the macos App Bundle
+if [ "${ISMACOS}" = 1 ]; then
+# MACOS ONLY
+  DIR="$(dirname "$(readlinkf "$0")")"
+  JVMARGS=( "${JVMARGS[@]}" "-Xdock:icon=${DIR}/jalview_logo.png" )
+else
+# NOT MACOS
+  DIR="$(dirname "$(readlink -f "$0")")"
+fi
+
+if [ "${HEADLESS}" = 1 ]; then
+  # this suppresses the Java icon appearing in the macOS Dock and maybe other things in other OSes
+  JVMARGS=( "${JVMARGS[@]}" "-Djava.awt.headless=true" )
+fi
+
+JAVA=java
+
+# decide which jalview jar to launch - either 'j11' or 'j1.8'
+if [[ "$JALVIEW_JRE" != "j11" && "$JALVIEW_JRE" != "j1.8" ]]; then
+  JALVIEW_JRE="j11"
+  # if java 8 is installed we pick the j1.8 build
+  if [[ $( "${JAVA}" -version 2>&1 | grep '"1.8' ) != "" ]]; then
+    JALVIEW_JRE="j1.8"
+  fi
+fi
+
+JARPATH="${DIR}/jalview-all-${JALVIEW_JRE}.jar"
+
+# check if memory maximum is set and if so forward to java-based jalview call
+if [ \! -z "$JALVIEW_MAXMEM" ]; then
+  JVMARGS=( "${JVMARGS[@]}" "-Xmx${JALVIEW_MAXMEM}" )
+fi
+
+# WINDOWS ONLY (Cygwin or WSL)
+# change paths for Cygwin or Windows Subsystem for Linux (WSL)
+if [ "${ISMACOS}" != 1 ]; then # older macos doesn't like uname -o, best to avoid
+  if [ "$(uname -o)" = "Cygwin" ]; then
+  # CYGWIN
+    JARPATH="$(cygpath -pw "${JARPATH}")"
+    # now for some arg paths fun. only translating paths starting with './', '../', '/' or '~'
+    ARGS=()
+    for ARG in "${@}"; do
+      if [ "${ARG}" != "${ARG#@(/|./|../|~)}" ]; then
+        ARGS=( "${ARGS[@]}" "$(cygpath -aw "${ARG}")" )
+      else
+        ARGS=( "${ARGS[@]}" "${ARG}" )
+      fi
+    done
+  elif uname -r | grep -i microsoft | grep -i wsl >/dev/null; then
+  # WSL
+    JARPATH="$(wslpath -aw "${JARPATH}")"
+    ARGS=()
+    for ARG in "${@}"; do
+      if [ "${ARG}" != "${ARG#@(/|./|../|~)}" ]; then
+        # annoyingly wslpath does not work if the file doesn't exist!
+        ARGBASENAME="$(basename "${ARG}")"
+        ARGDIRNAME="$(dirname "${ARG}")"
+        ARGS=( "${ARGS[@]}" "$(wslpath -aw "${ARGDIRNAME}")\\${ARGBASENAME}" )
+      else
+        ARGS=( "${ARGS[@]}" "${ARG}" )
+      fi
+    done
+    JAVA="${JAVA}.exe"
+  fi
+fi
+
+# get console width -- three ways to try, just in case
+if command -v tput 2>&1 >/dev/null; then
+  COLUMNS=$(tput cols) 2>/dev/null
+elif command -v stty 2>&1 >/dev/null; then
+  COLUMNS=$(stty size | cut -d" " -f2) 2>/dev/null
+elif command -v resize 2>&1 >/dev/null; then
+  COLUMNS=$(resize -u | grep COLUMNS= | sed -e 's/.*=//;s/;//') 2>/dev/null
+fi
+JVMARGS=( "${JVMARGS[@]}" "-DCONSOLEWIDTH=${COLUMNS}" )
+
+if [ "${DEBUG}" = 1 ]; then
+ echo Shell running: "${JAVA}" "${JVMARGS[@]}" -jar \""${JARPATH}"\" "${ARGS[@]}"
+fi
+
+"${JAVA}" "${JVMARGS[@]}" -jar "${JARPATH}" "${ARGS[@]}"
index 1527c79..4d3762e 100644 (file)
@@ -1,6 +1,8 @@
---- a/build.gradle     2021-09-21 09:52:04.653972716 +0100
-+++ b/build.gradle     2021-09-21 09:52:18.117985307 +0100
-@@ -2,56 +2,12 @@
+diff --git a/build.gradle b/build.gradle
+index ca599a85a..ce7f13634 100644
+--- a/build.gradle
++++ b/build.gradle
+@@ -2,66 +2,12 @@
   * For properties set within build.gradle, use camelCaseNoSpace.
   */
  import org.apache.tools.ant.filters.ReplaceTokens
 -import org.gradle.plugins.ide.eclipse.model.Output
 -import org.gradle.plugins.ide.eclipse.model.Library
 -import java.security.MessageDigest
+-import java.util.regex.Matcher
 -import groovy.transform.ExternalizeMethods
 -import groovy.util.XmlParser
 -import groovy.xml.XmlUtil
+-import groovy.json.JsonBuilder
 -import com.vladsch.flexmark.util.ast.Node
 -import com.vladsch.flexmark.html.HtmlRenderer
 -import com.vladsch.flexmark.parser.Parser
 -import com.vladsch.flexmark.ext.autolink.AutolinkExtension
 -import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension
 -import com.vladsch.flexmark.ext.toc.TocExtension
+-import com.google.common.hash.HashCode
+-import com.google.common.hash.Hashing
+-import com.google.common.io.Files
+-import org.jsoup.Jsoup
+-import org.jsoup.nodes.Element
 -
 -buildscript {
 -  repositories {
@@ -32,6 +41,8 @@
 -  }
 -  dependencies {
 -    classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
+-    classpath "org.jsoup:jsoup:1.14.3"
+-    classpath "com.eowise:gradle-imagemagick:0.5.1"
 -  }
 -}
 -
@@ -42,9 +53,9 @@
 -  id 'eclipse'
 -  id "com.diffplug.gradle.spotless" version "3.28.0"
 -  id 'com.github.johnrengelman.shadow' version '4.0.3'
--  id 'com.install4j.gradle' version '8.0.10'
--  id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
--  id 'com.palantir.git-version' version '0.12.3'
+-  id 'com.install4j.gradle' version '10.0.3'
+-  id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
+-  id 'com.palantir.git-version' version '0.13.0' apply false
 -}
 -
 -repositories {
  }
  
 -
+-
  // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
  def string(Object o) {
    return o == null ? "" : o.toString()
-@@ -92,23 +48,15 @@
+@@ -102,34 +48,20 @@ def overrideProperties(String propsFileName, boolean output = false) {
    }
  }
  
 +project.ext {
    jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
    jalviewDirRelativePath = jalviewDir
+-  date = new Date()
  
 -  getdownChannelName = CHANNEL.toLowerCase()
 -  // default to "default". Currently only has different cosmetics for "develop", "release", "default"
 -  propertiesChannelName = ["develop", "release", "test-release", "jalviewjs", "jalviewjs-release" ].contains(getdownChannelName) ? getdownChannelName : "default"
+-  channelDirName = propertiesChannelName
 -  // Import channel_properties
+-  if (getdownChannelName.startsWith("develop-")) {
+-    channelDirName = "develop-SUFFIX"
+-  }
+-  channelDir = string("${jalviewDir}/${channel_properties_dir}/${channelDirName}")
 +  propertiesChannelName = "release"
-   channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}")
++  channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}")
    channelGradleProperties = string("${channelDir}/channel_gradle.properties")
+-  channelPropsFile = string("${channelDir}/${resource_dir}/${channel_props}")
    overrideProperties(channelGradleProperties, false)
 -  // local build environment properties
 -  // can be "projectDir/local.properties"
    ////  
    // Import releaseProps from the RELEASE file
    // or a file specified via JALVIEW_RELEASE_FILE if defined
-@@ -128,41 +76,6 @@
+   // Expect jalview.version and target release branch in jalview.release        
+-  releaseProps = new Properties();
++  def releaseProps = new Properties();
+   def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
+   def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
+   try {
+@@ -144,42 +76,6 @@ ext {
    if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
      JALVIEW_VERSION = releaseProps.get("jalview.version")
    }
+-  println("JALVIEW_VERSION is set to '${JALVIEW_VERSION}'")
 -  
 -  // this property set when running Eclipse headlessly
 -  j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
  
    // essentials
    bareSourceDir = string(source_dir)
-@@ -173,218 +86,18 @@
+@@ -190,273 +86,18 @@ ext {
  
    classesDir = string("${jalviewDir}/${classes_dir}")
  
 -  cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
 -  //cloverTestClassesDir = cloverClassesDir
 -  cloverDb = string("${cloverBuildDir}/clover.db")
--
++  useClover = false
 -  testSourceDir = useClover ? cloverTestInstrDir : testDir
 -  testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
--
--  getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
++  resourceClassesDir = classesDir
+-  channelSuffix = ""
+-  backgroundImageText = BACKGROUNDIMAGETEXT
+-  getdownChannelDir = string("${getdown_website_dir}/${propertiesChannelName}")
+-  getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}")
+-  getdownArchiveDir = string("${jalviewDir}/${getdown_archive_dir}")
+-  getdownFullArchiveDir = null
+-  getdownTextLines = []
+-  getdownLaunchJvl = null
+-  getdownVersionLaunchJvl = null
 -  buildDist = true
 -  buildProperties = null
--
++  testSourceDir = testDir
++  testClassesDir = "${jalviewDir}/${test_output_dir}"
 -  // the following values might be overridden by the CHANNEL switch
 -  getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
 -  getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
+-  getdownArchiveAppBase = getdown_archive_base
 -  getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
 -  getdownAppDistDir = getdown_app_dir_alt
 -  getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
--  getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
+-  getdownImagesBuildDir = string("${buildDir}/imagemagick/getdown")
++  buildProperties = string("${classesDir}/${build_properties_file}")
+   getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
 -  reportRsyncCommand = false
 -  jvlChannelName = CHANNEL.toLowerCase()
 -  install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
 -  install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
--  install4jDMGBackgroundImage = "${install4j_images_dir}/${install4j_dmg_background}"
+-  install4jDMGBackgroundImageDir = "${install4j_images_dir}"
+-  install4jDMGBackgroundImageBuildDir = "build/imagemagick/install4j"
+-  install4jDMGBackgroundImageFile = "${install4j_dmg_background}"
 -  install4jInstallerName = "${jalview_name} Non-Release Installer"
 -  install4jExecutableName = install4j_executable_name
 -  install4jExtraScheme = "jalviewx"
 -  install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
 -  install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
 -  install4jBackground = string("${install4j_images_dir}/${install4j_background}")
+-  install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
+-  install4jCheckSums = true
+-
+-  applicationName = "${jalview_name}"
 -  switch (CHANNEL) {
 -
 -    case "BUILD":
 -      testng_excluded_groups = "Not-bamboo"
 -    }
 -    install4jExtraScheme = "jalviewb"
+-    backgroundImageText = true
 -    break
-+  useClover = false
+-
 -    case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
 -    getdownAppDistDir = getdown_app_dir_release
+-    getdownSetAppBaseProperty = true
 -    reportRsyncCommand = true
 -    install4jSuffix = ""
 -    install4jInstallerName = "${jalview_name} Installer"
 -    case "ARCHIVELOCAL":
 -    getdownChannelName = string("archive/${JALVIEW_VERSION}")
 -    getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
--    getdownAppBase = file(getdownWebsiteDir).toURI().toString()
+-    getdownAppBase = file(getdownAppBaseDir).toURI().toString()
 -    if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
--      throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
+-      throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution [did not find '${ARCHIVEDIR}/${package_dir}']")
 -    } else {
 -      package_dir = string("${ARCHIVEDIR}/${package_dir}")
 -      buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
 -    install4jExtraScheme = "jalviewa"
 -    break
 -
+-    case ~/^DEVELOP-([\.\-\w]*)$/:
+-    def suffix = Matcher.lastMatcher[0][1]
+-    reportRsyncCommand = true
+-    getdownSetAppBaseProperty = true
+-    JALVIEW_VERSION=JALVIEW_VERSION+"-d${suffix}-${buildDate}"
+-    install4jSuffix = "Develop ${suffix}"
+-    install4jExtraScheme = "jalviewd"
+-    install4jInstallerName = "${jalview_name} Develop ${suffix} Installer"
+-    getdownChannelName = string("develop-${suffix}")
+-    getdownChannelDir = string("${getdown_website_dir}/${getdownChannelName}")
+-    getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}")
+-    getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
+-    getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
+-    channelSuffix = string(suffix)
+-    backgroundImageText = true
+-    break
+-
 -    case "DEVELOP":
 -    reportRsyncCommand = true
 -    getdownSetAppBaseProperty = true
 -    install4jSuffix = "Develop"
 -    install4jExtraScheme = "jalviewd"
 -    install4jInstallerName = "${jalview_name} Develop Installer"
+-    backgroundImageText = true
 -    break
 -
 -    case "TEST-RELEASE":
 -    reportRsyncCommand = true
+-    getdownSetAppBaseProperty = true
 -    // Don't ignore transpile errors for release build
 -    if (jalviewjs_ignore_transpile_errors.equals("true")) {
 -      jalviewjs_ignore_transpile_errors = "false"
 -    install4jSuffix = "Test"
 -    install4jExtraScheme = "jalviewt"
 -    install4jInstallerName = "${jalview_name} Test Installer"
+-    backgroundImageText = true
 -    break
 -
 -    case ~/^SCRATCH(|-[-\w]*)$/:
 -    install4jSuffix = "Test-Local"
 -    install4jExtraScheme = "jalviewt"
 -    install4jInstallerName = "${jalview_name} Test Installer"
+-    backgroundImageText = true
 -    break
 -
 -    case [ "LOCAL", "JALVIEWJS" ]:
 -    JALVIEW_VERSION = "TEST"
--    getdownAppBase = file(getdownWebsiteDir).toURI().toString()
+-    getdownAppBase = file(getdownAppBaseDir).toURI().toString()
+-    getdownArchiveAppBase = file("${jalviewDir}/${getdown_archive_dir}").toURI().toString()
 -    getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
 -    install4jExtraScheme = "jalviewl"
+-    install4jCheckSums = false
 -    break
 -
 -    default: // something wrong specified
 -    break
 -
 -  }
+-  JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
+-  hugoDataJsonFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_data_installers_dir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
+-  hugoArchiveMdFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_version_archive_dir}/Version-${JALVIEW_VERSION_UNDERSCORES}/_index.md")
 -  // override getdownAppBase if requested
 -  if (findProperty("getdown_appbase_override") != null) {
 -    // revert to LOCAL if empty string
 -    if (string(getdown_appbase_override) == "") {
--      getdownAppBase = file(getdownWebsiteDir).toURI().toString()
+-      getdownAppBase = file(getdownAppBaseDir).toURI().toString()
 -      getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
 -    } else if (string(getdown_appbase_override).startsWith("file://")) {
 -      getdownAppBase = string(getdown_appbase_override)
 -  jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
 -  // install4j application and folder names
 -  if (install4jSuffix == "") {
--    install4jApplicationName = "${jalview_name}"
 -    install4jBundleId = "${install4j_bundle_id}"
 -    install4jWinApplicationId = install4j_release_win_application_id
 -  } else {
--    install4jApplicationName = "${jalview_name} ${install4jSuffix}"
+-    applicationName = "${jalview_name} ${install4jSuffix}"
 -    install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
 -    // add int hash of install4jSuffix to the last part of the application_id
 -    def id = install4j_release_win_application_id
 -  }
 -  // sanitise folder and id names
 -  // install4jApplicationFolder = e.g. "Jalview Build"
--  install4jApplicationFolder = install4jApplicationName
+-  install4jApplicationFolder = applicationName
 -                                    .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
 -                                    .replaceAll("_+", "_") // collapse __
--  install4jInternalId = install4jApplicationName
+-  install4jInternalId = applicationName
 -                                    .replaceAll(" ","_")
 -                                    .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
 -                                    .replaceAll("_+", "") // collapse __
 -                                    //.replaceAll("_*-_*", "-") // collapse _-_
--  install4jUnixApplicationFolder = install4jApplicationName
+-  install4jUnixApplicationFolder = applicationName
 -                                    .replaceAll(" ","_")
 -                                    .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
 -                                    .replaceAll("_+", "_") // collapse __
 -                                    .toLowerCase()
 -
 -  getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
--  getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
--  //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
--  getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
--  getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
+-  getdownAppDir = string("${getdownAppBaseDir}/${getdownAppDistDir}")
+-  //getdownJ11libDir = "${getdownAppBaseDir}/${getdown_j11lib_dir}"
+-  getdownResourceDir = string("${getdownAppBaseDir}/${getdown_resource_dir}")
+-  getdownInstallDir = string("${getdownAppBaseDir}/${getdown_install_dir}")
 -  getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
 -  getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
 -  /* compile without modules -- using classpath libraries
 -  modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
 -  modules_runtimeClasspath = modules_compileClasspath
 -  */
--  def details = versionDetails()
--  gitHash = details.gitHash
--  gitBranch = details.branchName
-+  resourceClassesDir = classesDir
-+
-+  testSourceDir = testDir
-+  testClassesDir = "${jalviewDir}/${test_output_dir}"
+-
+-  gitHash = "SOURCE"
+-  gitBranch = "Source"
+-  try {
+-    apply plugin: "com.palantir.git-version"
+-    def details = versionDetails()
+-    gitHash = details.gitHash
+-    gitBranch = details.branchName
+-  } catch(org.gradle.api.internal.plugins.PluginApplicationException e) {
+-    println("Not in a git repository. Using git values from RELEASE properties file.")
+-    gitHash = releaseProps.getProperty("git.hash")
+-    gitBranch = releaseProps.getProperty("git.branch")
+-  } catch(java.lang.RuntimeException e1) {
+-    throw new GradleException("Error with git-version plugin.  Directory '.git' exists but versionDetails() cannot be found.")
+-  }
  
-+  buildProperties = string("${classesDir}/${build_properties_file}")
-+  getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
-+
 +  install4jApplicationName = "${jalview_name}"
 +  
    println("Using a ${CHANNEL} profile.")
  
    additional_compiler_args = []
-@@ -396,71 +109,16 @@
+@@ -468,65 +109,16 @@ ext {
      libDistDir = j8libDir
      compile_source_compatibility = 1.8
      compile_target_compatibility = 1.8
 -    '--add-modules', j11modules
 -    ]
 -     */
--  } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
--    JAVA_INTEGER_VERSION = JAVA_VERSION
--    libDir = j11libDir
--    libDistDir = j11libDir
--    compile_source_compatibility = JAVA_VERSION
--    compile_target_compatibility = JAVA_VERSION
+-  } else if (JAVA_VERSION.equals("17")) {
+-    JAVA_INTEGER_VERSION = string("17")
+-    libDir = j17libDir
+-    libDistDir = j17libDir
+-    compile_source_compatibility = 17
+-    compile_target_compatibility = 17
 -    getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
 -    getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
 -    getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
--    eclipseJavaRuntimeName = string("JavaSE-11")
+-    eclipseJavaRuntimeName = string("JavaSE-17")
 -    /* compile without modules -- using classpath libraries
 -    additional_compiler_args += [
 -    '--module-path', modules_compileClasspath.asPath,
 -  // for install4j
 -  JAVA_MIN_VERSION = JAVA_VERSION
 -  JAVA_MAX_VERSION = JAVA_VERSION
--  def jreInstallsDir = string(jre_installs_dir)
+-  jreInstallsDir = string(jre_installs_dir)
 -  if (jreInstallsDir.startsWith("~/")) {
 -    jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
 -  }
--  macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
--  macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
--  windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
--  windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
--  linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
--  linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
 -  install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
 -  install4jConfFileName = string("jalview-install4j-conf.install4j")
 -  install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
    resourceBuildDir = string("${buildDir}/resources")
    resourcesBuildDir = string("${resourceBuildDir}/resources_build")
    helpBuildDir = string("${resourceBuildDir}/help_build")
-@@ -474,31 +132,6 @@
+@@ -540,39 +132,6 @@ ext {
    helpSourceDir = string("${helpParentDir}/${help_dir}")
    helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
  
+-  convertBinary = null
+-  convertBinaryExpectedLocation = imagemagick_convert
+-  if (convertBinaryExpectedLocation.startsWith("~/")) {
+-    convertBinaryExpectedLocation = System.getProperty("user.home") + convertBinaryExpectedLocation.substring(1)
+-  }
+-  if (file(convertBinaryExpectedLocation).exists()) {
+-    convertBinary = convertBinaryExpectedLocation
+-  }
 -
 -  relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
 -  jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
    // ENDEXT
  }
  
-@@ -517,27 +150,12 @@
+@@ -591,27 +150,12 @@ sourceSets {
      compileClasspath = files(sourceSets.main.java.outputDir)
      compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
  
    }
  
    test {
-@@ -557,453 +175,41 @@
+@@ -631,453 +175,41 @@ sourceSets {
      runtimeClasspath = compileClasspath
      runtimeClasspath += files(sourceSets.test.resources.srcDirs)
    }
 -  if (cloverreport_jvmargs.length() > 0) {
 -    jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
 -  }
--
 -  def argsList = [
 -    "--alwaysreport",
 -    "--initstring",
 -
 -  args argsList.toArray()
 -}
-+    compileClasspath = files( sourceSets.test.java.outputDir )
-+    compileClasspath += sourceSets.main.compileClasspath
-+    compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**   REMOVE_THIS_GAP  /*.jar"])
+-
+-
 -task cloverReport {
 -  group = "Verification"
 -  description = "Creates clover reports"
 -
 -
 -compileCloverJava {
--
++    compileClasspath = files( sourceSets.test.java.outputDir )
++    compileClasspath += sourceSets.main.compileClasspath
++    compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**   REMOVE_THIS_GAP  /*.jar"])
 -  doFirst {
 -    sourceCompatibility = compile_source_compatibility
 -    targetCompatibility = compile_target_compatibility
 -  // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
    sourceCompatibility = compile_source_compatibility
    targetCompatibility = compile_target_compatibility
-   options.compilerArgs = additional_compiler_args
+-  options.compilerArgs += additional_compiler_args
 -  options.encoding = "UTF-8"
++  options.compilerArgs = additional_compiler_args
    doFirst {
      print ("Setting target compatibility to "+compile_target_compatibility+"\n")
    }
  compileTestJava {
 -  sourceCompatibility = compile_source_compatibility
 -  targetCompatibility = compile_target_compatibility
--  options.compilerArgs = additional_compiler_args
+-  options.compilerArgs += additional_compiler_args
    doFirst {
 +    sourceCompatibility = compile_source_compatibility
 +    targetCompatibility = compile_target_compatibility
      print ("Setting target compatibility to "+targetCompatibility+"\n")
    }
  }
-@@ -1017,7 +223,6 @@
+@@ -1091,7 +223,6 @@ clean {
  
  
  cleanTest {
    doFirst {
      delete sourceSets.test.java.outputDir
    }
-@@ -1031,85 +236,6 @@
+@@ -1100,89 +231,11 @@ cleanTest {
+ // format is a string like date.format("dd MMMM yyyy")
+ def getDate(format) {
++  def date = new Date()
+   return date.format(format)
  }
  
  
  task copyDocs(type: Copy) {
    def inputDir = "${jalviewDir}/${doc_dir}"
    def outputDir = "${docBuildDir}/${doc_dir}"
-@@ -1140,27 +266,6 @@
+@@ -1213,235 +266,6 @@ task copyDocs(type: Copy) {
  }
  
  
 -}
 -
 -
+-def hugoTemplateSubstitutions(String input, Map extras=null) {
+-  def replacements = [
+-    DATE: getDate("yyyy-MM-dd"),
+-    CHANNEL: propertiesChannelName,
+-    APPLICATION_NAME: applicationName,
+-    GIT_HASH: gitHash,
+-    GIT_BRANCH: gitBranch,
+-    VERSION: JALVIEW_VERSION,
+-    JAVA_VERSION: JAVA_VERSION,
+-    VERSION_UNDERSCORES: JALVIEW_VERSION_UNDERSCORES,
+-    DRAFT: "false",
+-    JVL_HEADER: ""
+-  ]
+-  def output = input
+-  if (extras != null) {
+-    extras.each{ k, v ->
+-      output = output.replaceAll("__${k}__", ((v == null)?"":v))
+-    }
+-  }
+-  replacements.each{ k, v ->
+-    output = output.replaceAll("__${k}__", ((v == null)?"":v))
+-  }
+-  return output
+-}
+-
+-def mdFileComponents(File mdFile, def dateOnly=false) {
+-  def map = [:]
+-  def content = ""
+-  if (mdFile.exists()) {
+-    def inFrontMatter = false
+-    def firstLine = true
+-    mdFile.eachLine { line ->
+-      if (line.matches("---")) {
+-        def prev = inFrontMatter
+-        inFrontMatter = firstLine
+-        if (inFrontMatter != prev)
+-          return false
+-      }
+-      if (inFrontMatter) {
+-        def m = null
+-        if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/) {
+-          map["date"] = new Date().parse("yyyy-MM-dd HH:mm:ss", m[0][1])
+-        } else if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2})/) {
+-          map["date"] = new Date().parse("yyyy-MM-dd", m[0][1])
+-        } else if (m = line =~ /^channel:\s*(\S+)/) {
+-          map["channel"] = m[0][1]
+-        } else if (m = line =~ /^version:\s*(\S+)/) {
+-          map["version"] = m[0][1]
+-        } else if (m = line =~ /^\s*([^:]+)\s*:\s*(\S.*)/) {
+-          map[ m[0][1] ] = m[0][2]
+-        }
+-        if (dateOnly && map["date"] != null) {
+-          return false
+-        }
+-      } else {
+-        if (dateOnly)
+-          return false
+-        content += line+"\n"
+-      }
+-      firstLine = false
+-    }
+-  }
+-  return dateOnly ? map["date"] : [map, content]
+-}
+-
+-task hugoTemplates {
+-  group "website"
+-  description "Create partially populated md pages for hugo website build"
+-
+-  def hugoTemplatesDir = file("${jalviewDir}/${hugo_templates_dir}")
+-  def hugoBuildDir = "${jalviewDir}/${hugo_build_dir}"
+-  def templateFiles = fileTree(dir: hugoTemplatesDir)
+-  def releaseMdFile = file("${jalviewDir}/${releases_dir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
+-  def whatsnewMdFile = file("${jalviewDir}/${whatsnew_dir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
+-  def oldJvlFile = file("${jalviewDir}/${hugo_old_jvl}")
+-  def jalviewjsFile = file("${jalviewDir}/${hugo_jalviewjs}")
+-
+-  doFirst {
+-    // specific release template for version archive
+-    def changes = ""
+-    def whatsnew = null
+-    def givenDate = null
+-    def givenChannel = null
+-    def givenVersion = null
+-    if (CHANNEL == "RELEASE") {
+-      def (map, content) = mdFileComponents(releaseMdFile)
+-      givenDate = map.date
+-      givenChannel = map.channel
+-      givenVersion = map.version
+-      changes = content
+-      if (givenVersion != null && givenVersion != JALVIEW_VERSION) {
+-        throw new GradleException("'version' header (${givenVersion}) found in ${releaseMdFile} does not match JALVIEW_VERSION (${JALVIEW_VERSION})")
+-      }
+-
+-      if (whatsnewMdFile.exists())
+-        whatsnew = whatsnewMdFile.text
+-    }
+-
+-    def oldJvl = oldJvlFile.exists() ? oldJvlFile.collect{it} : []
+-    def jalviewjsLink = jalviewjsFile.exists() ? jalviewjsFile.collect{it} : []
+-
+-    def changesHugo = null
+-    if (changes != null) {
+-      changesHugo = '<div class="release_notes">\n\n'
+-      def inSection = false
+-      changes.eachLine { line ->
+-        def m = null
+-        if (m = line =~ /^##([^#].*)$/) {
+-          if (inSection) {
+-            changesHugo += "</div>\n\n"
+-          }
+-          def section = m[0][1].trim()
+-          section = section.toLowerCase()
+-          section = section.replaceAll(/ +/, "_")
+-          section = section.replaceAll(/[^a-z0-9_\-]/, "")
+-          changesHugo += "<div class=\"${section}\">\n\n"
+-          inSection = true
+-        } else if (m = line =~ /^(\s*-\s*)<!--([^>]+)-->(.*?)(<br\/?>)?\s*$/) {
+-          def comment = m[0][2].trim()
+-          if (comment != "") {
+-            comment = comment.replaceAll('"', "&quot;")
+-            def issuekeys = []
+-            comment.eachMatch(/JAL-\d+/) { jal -> issuekeys += jal }
+-            def newline = m[0][1]
+-            if (comment.trim() != "")
+-              newline += "{{<comment>}}${comment}{{</comment>}}  "
+-            newline += m[0][3].trim()
+-            if (issuekeys.size() > 0)
+-              newline += "  {{< jal issue=\"${issuekeys.join(",")}\" alt=\"${comment}\" >}}"
+-            if (m[0][4] != null)
+-              newline += m[0][4]
+-            line = newline
+-          }
+-        }
+-        changesHugo += line+"\n"
+-      }
+-      if (inSection) {
+-        changesHugo += "\n</div>\n\n"
+-      }
+-      changesHugo += '</div>'
+-    }
+-
+-    templateFiles.each{ templateFile ->
+-      def newFileName = string(hugoTemplateSubstitutions(templateFile.getName()))
+-      def relPath = hugoTemplatesDir.toPath().relativize(templateFile.toPath()).getParent()
+-      def newRelPathName = hugoTemplateSubstitutions( relPath.toString() )
+-
+-      def outPathName = string("${hugoBuildDir}/$newRelPathName")
+-
+-      copy {
+-        from templateFile
+-        rename(templateFile.getName(), newFileName)
+-        into outPathName
+-      }
+-
+-      def newFile = file("${outPathName}/${newFileName}".toString())
+-      def content = newFile.text
+-      newFile.text = hugoTemplateSubstitutions(content,
+-        [
+-          WHATSNEW: whatsnew,
+-          CHANGES: changesHugo,
+-          DATE: givenDate == null ? "" : givenDate.format("yyyy-MM-dd"),
+-          DRAFT: givenDate == null ? "true" : "false",
+-          JALVIEWJSLINK: jalviewjsLink.contains(JALVIEW_VERSION) ? "true" : "false",
+-          JVL_HEADER: oldJvl.contains(JALVIEW_VERSION) ? "jvl: true" : ""
+-        ]
+-      )
+-    }
+-
+-  }
+-
+-  inputs.file(oldJvlFile)
+-  inputs.dir(hugoTemplatesDir)
+-  inputs.property("JALVIEW_VERSION", { JALVIEW_VERSION })
+-  inputs.property("CHANNEL", { CHANNEL })
+-}
+-
+-def getMdDate(File mdFile) {
+-  return mdFileComponents(mdFile, true)
+-}
+-
+-def getMdSections(String content) {
+-  def sections = [:]
+-  def sectionContent = ""
+-  def sectionName = null
+-  content.eachLine { line ->
+-    def m = null
+-    if (m = line =~ /^##([^#].*)$/) {
+-      if (sectionName != null) {
+-        sections[sectionName] = sectionContent
+-        sectionName = null
+-        sectionContent = ""
+-      }
+-      sectionName = m[0][1].trim()
+-      sectionName = sectionName.toLowerCase()
+-      sectionName = sectionName.replaceAll(/ +/, "_")
+-      sectionName = sectionName.replaceAll(/[^a-z0-9_\-]/, "")
+-    } else if (sectionName != null) {
+-      sectionContent += line+"\n"
+-    }
+-  }
+-  if (sectionContent != null) {
+-    sections[sectionName] = sectionContent
+-  }
+-  return sections
+-}
+-
+-
  task copyHelp(type: Copy) {
    def inputDir = helpSourceDir
    def outputDir = "${helpBuildDir}/${help_dir}"
-@@ -1242,24 +347,15 @@
+@@ -1476,7 +300,6 @@ task copyHelp(type: Copy) {
+   outputs.dir(outputDir)
+ }
+-
+ task releasesTemplates {
+   group "help"
+   description "Recreate whatsNew.html and releases.html from markdown files and templates in help"
+@@ -1491,6 +314,7 @@ task releasesTemplates {
+   def whatsnewMdDir = "${jalviewDir}/${whatsnew_dir}"
+   doFirst {
++    def JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
+     def releaseMdFile = file("${releasesMdDir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
+     def whatsnewMdFile = file("${whatsnewMdDir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
+@@ -1505,7 +329,7 @@ task releasesTemplates {
+     def releaseFiles = fileTree(dir: releasesMdDir, include: "release-*.md")
+     def releaseFilesDates = releaseFiles.collectEntries {
+-      [(it): getMdDate(it)]
++      [(it): getDate("")]
+     }
+     releaseFiles = releaseFiles.sort { a,b -> releaseFilesDates[a].compareTo(releaseFilesDates[b]) }
+@@ -1513,96 +337,13 @@ task releasesTemplates {
+     def m = releasesTemplate =~ /(?s)__VERSION_LOOP_START__(.*)__VERSION_LOOP_END__/
+     def versionTemplate = m[0][1]
+-    MutableDataSet options = new MutableDataSet()
+-
+-    def extensions = new ArrayList<>()
+-    options.set(Parser.EXTENSIONS, extensions)
+-    options.set(Parser.HTML_BLOCK_COMMENT_ONLY_FULL_LINE, true)
+-
+-    Parser parser = Parser.builder(options).build()
+-    HtmlRenderer renderer = HtmlRenderer.builder(options).build()
+-
+-    def actualVersions = releaseFiles.collect { rf ->
+-      def (rfMap, rfContent) = mdFileComponents(rf)
+-      return rfMap.version
+-    }
+     def versionsHtml = ""
+     def linkedVersions = []
+-    releaseFiles.reverse().each { rFile ->
+-      def (rMap, rContent) = mdFileComponents(rFile)
+-
+-      def versionLink = ""
+-      def partialVersion = ""
+-      def firstPart = true
+-      rMap.version.split("\\.").each { part ->
+-        def displayPart = ( firstPart ? "" : "." ) + part
+-        partialVersion += displayPart
+-        if (
+-            linkedVersions.contains(partialVersion)
+-            || ( actualVersions.contains(partialVersion) && partialVersion != rMap.version )
+-            ) {
+-          versionLink += displayPart
+-        } else {
+-          versionLink += "<a id=\"Jalview.${partialVersion}\">${displayPart}</a>"
+-          linkedVersions += partialVersion
+-        }
+-        firstPart = false
+-      }
+-      def displayDate = releaseFilesDates[rFile].format("dd/MM/yyyy")
+-
+-      def lm = null
+-      def rContentProcessed = ""
+-      rContent.eachLine { line ->
+-        if (lm = line =~ /^(\s*-)(\s*<!--[^>]*?-->)(.*)$/) {
+-          line = "${lm[0][1]}${lm[0][3]}${lm[0][2]}"
+-      } else if (lm = line =~ /^###([^#]+.*)$/) {
+-          line = "_${lm[0][1].trim()}_"
+-        }
+-        rContentProcessed += line + "\n"
+-      }
+-
+-      def rContentSections = getMdSections(rContentProcessed)
+-      def rVersion = versionTemplate
+-      if (rVersion != "") {
+-        def rNewFeatures = rContentSections["new_features"]
+-        def rIssuesResolved = rContentSections["issues_resolved"]
+-        Node newFeaturesNode = parser.parse(rNewFeatures)
+-        String newFeaturesHtml = renderer.render(newFeaturesNode)
+-        Node issuesResolvedNode = parser.parse(rIssuesResolved)
+-        String issuesResolvedHtml = renderer.render(issuesResolvedNode)
+-        rVersion = hugoTemplateSubstitutions(rVersion,
+-          [
+-            VERSION: rMap.version,
+-            VERSION_LINK: versionLink,
+-            DISPLAY_DATE: displayDate,
+-            NEW_FEATURES: newFeaturesHtml,
+-            ISSUES_RESOLVED: issuesResolvedHtml
+-          ]
+-        )
+-        versionsHtml += rVersion
+-      }
+-    }
+     releasesTemplate = releasesTemplate.replaceAll("(?s)__VERSION_LOOP_START__.*__VERSION_LOOP_END__", versionsHtml)
+-    releasesTemplate = hugoTemplateSubstitutions(releasesTemplate)
+     releasesHtmlFile.text = releasesTemplate
+-    if (whatsnewMdFile.exists()) {
+-      def wnDisplayDate = releaseFilesDates[releaseMdFile] != null ? releaseFilesDates[releaseMdFile].format("dd MMMM yyyy") : ""
+-      def whatsnewMd = hugoTemplateSubstitutions(whatsnewMdFile.text)
+-      Node whatsnewNode = parser.parse(whatsnewMd)
+-      String whatsnewHtml = renderer.render(whatsnewNode)
+-      whatsnewHtml = whatsnewTemplateFile.text.replaceAll("__WHATS_NEW__", whatsnewHtml)
+-      whatsnewHtmlFile.text = hugoTemplateSubstitutions(whatsnewHtml,
+-        [
+-            VERSION: JALVIEW_VERSION,
+-          DISPLAY_DATE: wnDisplayDate
+-        ]
+-      )
+-    } else if (gradle.taskGraph.hasTask(":linkCheck")) {
+-      whatsnewHtmlFile.text = "Development build " + getDate("yyyy-MM-dd HH:mm:ss")
+-    }
+-
++    whatsnewHtmlFile.text = "Debian build " + getDate("yyyy-MM-dd HH:mm:ss")
+   }
+   inputs.file(releasesTemplateFile)
+@@ -1613,7 +354,6 @@ task releasesTemplates {
+   outputs.file(whatsnewHtmlFile)
+ }
+-
+ task copyResources(type: Copy) {
+   group = "build"
+   description = "Copy (and make text substitutions in) the resources dir to the build area"
+@@ -1653,44 +393,22 @@ task copyChannelResources(type: Copy) {
+   def inputDir = "${channelDir}/${resource_dir}"
+   def outputDir = resourcesBuildDir
+-  from(inputDir) {
+-    include(channel_props)
+-    filter(ReplaceTokens,
+-      beginToken: '__',
+-      endToken: '__',
+-      tokens: [
+-        'SUFFIX': channelSuffix
+-      ]
+-    )
+-  }
+-  from(inputDir) {
+-    exclude(channel_props)
+-  }
++  from inputDir
+   into outputDir
+   inputs.dir(inputDir)
    outputs.dir(outputDir)
  }
  
 -  property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
 -  property "VERSION", JALVIEW_VERSION
 -  property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
+-  property "JAVA_COMPILE_VERSION", JAVA_INTEGER_VERSION
 -  if (getdownSetAppBaseProperty) {
 -    property "GETDOWNAPPBASE", getdownAppBase
 -    property "GETDOWNAPPDISTDIR", getdownAppDistDir
    outputs.file(outputFile)
  }
  
-@@ -1293,7 +389,6 @@
-   dependsOn buildResources
+@@ -1725,123 +443,31 @@ task prepare {
    dependsOn copyDocs
    dependsOn copyHelp
+   dependsOn releasesTemplates
 -  dependsOn convertMdFiles
    dependsOn buildIndices
  }
  
-@@ -1306,12 +401,7 @@
- //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
+ compileJava.dependsOn prepare
+ run.dependsOn compileJava
+-compileTestJava.dependsOn compileJava
+-
++//run.dependsOn prepare
++//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
  test {
-   dependsOn prepare
+-  group = "Verification"
+-  description = "Runs all testTaskN tasks)"
 -
 -  if (useClover) {
 -    dependsOn cloverClasses
--   } else { //?
--    dependsOn compileJava //?
+-  } else { //?
+-    dependsOn testClasses
+-  }
+-
+-  // not running tests in this task
+-  exclude "**/*"
+-}
+-/* testTask0 is the main test task */
+-task testTask0(type: Test) {
+-  group = "Verification"
+-  description = "The main test task. Runs all non-testTaskN-labelled tests (unless excluded)"
+-  useTestNG() {
+-    includeGroups testng_groups.split(",")
+-    excludeGroups testng_excluded_groups.split(",")
+-    tasks.withType(Test).matching {it.name.startsWith("testTask") && it.name != name}.all {t -> excludeGroups t.name}
+-    preserveOrder true
+-    useDefaultListeners=true
+-  }
+-}
+-
+-/* separated tests */
+-task testTask1(type: Test) {
+-  group = "Verification"
+-  description = "Tests that need to be isolated from the main test run"
+-  useTestNG() {
+-    includeGroups name
+-    excludeGroups testng_excluded_groups.split(",")
+-    preserveOrder true
+-    useDefaultListeners=true
 -  }
+-}
++  dependsOn prepare
 +  dependsOn compileJava //?
  
+-/* insert more testTaskNs here -- change N to next digit or other string */
+-/*
+-task testTaskN(type: Test) {
+-  group = "Verification"
+-  description = "Tests that need to be isolated from the main test run"
    useTestNG() {
-     includeGroups testng_groups
-@@ -1323,6 +413,7 @@
+-    includeGroups name
+-    excludeGroups testng_excluded_groups.split(",")
++    includeGroups testng_groups
++    excludeGroups testng_excluded_groups
+     preserveOrder true
+     useDefaultListeners=true
+   }
+-}
+-*/
+-
+-/*
+- * adapted from https://medium.com/@wasyl/pretty-tests-summary-in-gradle-744804dd676c
+- * to summarise test results from all Test tasks
+- */
+-/* START of test tasks results summary */
+-import groovy.time.TimeCategory
+-import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+-import org.gradle.api.tasks.testing.logging.TestLogEvent
+-rootProject.ext.testsResults = [] // Container for tests summaries
+-
+-tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { testTask ->
+-
+-  // from original test task
+-  if (useClover) {
+-    dependsOn cloverClasses
+-  } else { //?
+-    dependsOn testClasses //?
+-  }
+-
+-  // run main tests first
+-  if (!testTask.name.equals("testTask0"))
+-    testTask.mustRunAfter "testTask0"
+-
+-  testTask.testLogging { logging ->
+-    events TestLogEvent.FAILED
+-//      TestLogEvent.SKIPPED,
+-//      TestLogEvent.STANDARD_OUT,
+-//      TestLogEvent.STANDARD_ERROR
+-
+-    exceptionFormat TestExceptionFormat.FULL
+-    showExceptions true
+-    showCauses true
+-    showStackTraces true
+-
+-    info.events = [ TestLogEvent.FAILED ]
+-  }
+-
+-
+-
+-  ignoreFailures = true // Always try to run all tests for all modules
+-
+-  afterSuite { desc, result ->
+-    if (desc.parent)
+-      return // Only summarize results for whole modules
+-
+-    def resultsInfo = [testTask.project.name, testTask.name, result, TimeCategory.minus(new Date(result.endTime), new Date(result.startTime)), testTask.reports.html.entryPoint]
+-
+-    rootProject.ext.testsResults.add(resultsInfo)
+-  }
+-  // from original test task
    maxHeapSize = "1024m"
  
    workingDir = jalviewDir
    def testLaf = project.findProperty("test_laf")
    if (testLaf != null) {
      println("Setting Test LaF to '${testLaf}'")
-@@ -1338,9 +429,6 @@
+@@ -1857,143 +483,8 @@ tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { te
    jvmArgs += additional_compiler_args
  
    doFirst {
+-    // this is not perfect yet -- we should only add the commandLineIncludePatterns to the
+-    // testTasks that include the tests, and exclude all from the others.
+-    // get --test argument
+-    filter.commandLineIncludePatterns = test.filter.commandLineIncludePatterns
+-    // do something with testTask.getCandidateClassFiles() to see if the test should silently finish because of the
+-    // commandLineIncludePatterns not matching anything.  Instead we are doing setFailOnNoMatchingTests(false) below
+-
+-
 -    if (useClover) {
 -      println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
 -    }
+-  }
+-
+-
+-  /* don't fail on no matching tests (so --tests will run across all testTasks) */
+-  testTask.filter.setFailOnNoMatchingTests(false)
+-
+-  /* ensure the "test" task dependsOn all the testTasks */
+-  test.dependsOn testTask
+-}
+-
+-gradle.buildFinished {
+-    def allResults = rootProject.ext.testsResults
+-
+-    if (!allResults.isEmpty()) {
+-        printResults allResults
+-        allResults.each {r ->
+-          if (r[2].resultType == TestResult.ResultType.FAILURE)
+-            throw new GradleException("Failed tests!")
+-        }
+-    }
+-}
+-
+-private static String colString(styler, col, colour, text) {
+-  return col?"${styler[colour](text)}":text
+-}
+-
+-private static String getSummaryLine(s, pn, tn, rt, rc, rs, rf, rsk, t, col) {
+-  def colour = 'black'
+-  def text = rt
+-  def nocol = false
+-  if (rc == 0) {
+-    text = "-----"
+-    nocol = true
+-  } else {
+-    switch(rt) {
+-      case TestResult.ResultType.SUCCESS:
+-        colour = 'green'
+-        break;
+-      case TestResult.ResultType.FAILURE:
+-        colour = 'red'
+-        break;
+-      default:
+-        nocol = true
+-        break;
+-    }
    }
+-  StringBuilder sb = new StringBuilder()
+-  sb.append("${pn}")
+-  if (tn != null)
+-    sb.append(":${tn}")
+-  sb.append(" results: ")
+-  sb.append(colString(s, col && !nocol, colour, text))
+-  sb.append(" (")
+-  sb.append("${rc} tests, ")
+-  sb.append(colString(s, col && rs > 0, 'green', rs))
+-  sb.append(" successes, ")
+-  sb.append(colString(s, col && rf > 0, 'red', rf))
+-  sb.append(" failures, ")
+-  sb.append("${rsk} skipped) in ${t}")
+-  return sb.toString()
+-}
+-
+-private static void printResults(allResults) {
+-
+-    // styler from https://stackoverflow.com/a/56139852
+-    def styler = 'black red green yellow blue magenta cyan white'.split().toList().withIndex(30).collectEntries { key, val -> [(key) : { "\033[${val}m${it}\033[0m" }] }
+-
+-    def maxLength = 0
+-    def failedTests = false
+-    def summaryLines = []
+-    def totalcount = 0
+-    def totalsuccess = 0
+-    def totalfail = 0
+-    def totalskip = 0
+-    def totaltime = TimeCategory.getSeconds(0)
+-    // sort on project name then task name
+-    allResults.sort {a, b -> a[0] == b[0]? a[1]<=>b[1]:a[0] <=> b[0]}.each {
+-      def projectName = it[0]
+-      def taskName = it[1]
+-      def result = it[2]
+-      def time = it[3]
+-      def report = it[4]
+-      def summaryCol = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, true)
+-      def summaryPlain = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, false)
+-      def reportLine = "Report file: ${report}"
+-      def ls = summaryPlain.length()
+-      def lr = reportLine.length()
+-      def m = [ls, lr].max()
+-      if (m > maxLength)
+-        maxLength = m
+-      def info = [ls, summaryCol, reportLine]
+-      summaryLines.add(info)
+-      failedTests |= result.resultType == TestResult.ResultType.FAILURE
+-      totalcount += result.testCount
+-      totalsuccess += result.successfulTestCount
+-      totalfail += result.failedTestCount
+-      totalskip += result.skippedTestCount
+-      totaltime += time
+-    }
+-    def totalSummaryCol = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, true)
+-    def totalSummaryPlain = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, false)
+-    def tls = totalSummaryPlain.length()
+-    if (tls > maxLength)
+-      maxLength = tls
+-    def info = [tls, totalSummaryCol, null]
+-    summaryLines.add(info)
+-
+-    def allSummaries = []
+-    for(sInfo : summaryLines) {
+-      def ls = sInfo[0]
+-      def summary = sInfo[1]
+-      def report = sInfo[2]
+-
+-      StringBuilder sb = new StringBuilder()
+-      sb.append("│" + summary + " " * (maxLength - ls) + "│")
+-      if (report != null) {
+-        sb.append("\n│" + report + " " * (maxLength - report.length()) + "│")
+-      }
+-      allSummaries += sb.toString()
+-    }
+-
+-    println "┌${"${"─" * maxLength}"}┐"
+-    println allSummaries.join("\n├${"${"─" * maxLength}"}┤\n")
+-    println "└${"${"─" * maxLength}"}┘"
  }
+-/* END of test tasks results summary */
  
-@@ -1420,1752 +508,7 @@
+ task compileLinkCheck(type: JavaCompile) {
+@@ -2052,7 +543,7 @@ jar {
+   manifest {
+     attributes "Main-Class": main_class,
+     "Permissions": "all-permissions",
+-    "Application-Name": applicationName,
++    "Application-Name": install4jApplicationName,
+     "Codebase": application_codebase,
+     "Implementation-Version": JALVIEW_VERSION
+   }
+@@ -2060,8 +551,6 @@ jar {
+   def outputDir = "${jalviewDir}/${package_dir}"
+   destinationDirectory = file(outputDir)
+   archiveFileName = rootProject.name+".jar"
+-  duplicatesStrategy "EXCLUDE"
+-
+   exclude "cache*/**"
+   exclude "*.jar"
+@@ -2073,2137 +562,7 @@ jar {
    sourceSets.main.resources.srcDirs.each{ dir ->
      inputs.dir(dir)
    }
 -  }
 -  manifest {
 -    attributes "Implementation-Version": JALVIEW_VERSION,
--    "Application-Name": install4jApplicationName
+-    "Application-Name": applicationName
 -  }
+-
+-  duplicatesStrategy "INCLUDE"
+-
 -  mainClassName = shadow_jar_main_class
 -  mergeServiceFiles()
 -  classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
 -  minimize()
 -}
 -
+-task getdownImagesCopy() {
+-  inputs.dir getdownImagesDir
+-  outputs.dir getdownImagesBuildDir
+-
+-  doFirst {
+-    copy {
+-      from(getdownImagesDir) {
+-        include("*getdown*.png")
+-      }
+-      into getdownImagesBuildDir
+-    }
+-  }
+-}
+-
+-task getdownImagesProcess() {
+-  dependsOn getdownImagesCopy
+-
+-  doFirst {
+-    if (backgroundImageText) {
+-      if (convertBinary == null) {
+-        throw new StopExecutionException("No ImageMagick convert binary installed at '${convertBinaryExpectedLocation}'")
+-      }
+-      if (!project.hasProperty("getdown_background_image_text_suffix_cmd")) {
+-        throw new StopExecutionException("No property 'getdown_background_image_text_suffix_cmd' defined. See channel_gradle.properties for channel ${CHANNEL}")
+-      }
+-      fileTree(dir: getdownImagesBuildDir, include: "*background*.png").getFiles().each { file ->
+-        exec {
+-          executable convertBinary
+-          args = [
+-            file.getPath(),
+-            '-font', getdown_background_image_text_font,
+-            '-fill', getdown_background_image_text_colour,
+-            '-draw', sprintf(getdown_background_image_text_suffix_cmd, channelSuffix),
+-            '-draw', sprintf(getdown_background_image_text_commit_cmd, "git-commit: ${gitHash}"),
+-            '-draw', sprintf(getdown_background_image_text_date_cmd, getDate("yyyy-MM-dd HH:mm:ss")),
+-            file.getPath()
+-          ]
+-        }
+-      }
+-    }
+-  }
+-}
+-
+-task getdownImages() {
+-  dependsOn getdownImagesProcess
+-}
 -
 -task getdownWebsite() {
 -  group = "distribution"
 -  description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
+-
+-  dependsOn getdownImages
 -  if (buildDist) {
 -    dependsOn makeDist
 -  }
 -
 -  def getdownWebsiteResourceFilenames = []
--  def getdownTextString = ""
 -  def getdownResourceDir = getdownResourceDir
 -  def getdownResourceFilenames = []
 -
 -  doFirst {
 -    // clean the getdown website and files dir before creating getdown folders
--    delete getdownWebsiteDir
+-    delete getdownAppBaseDir
 -    delete getdownFilesDir
 -
 -    copy {
 -    }
 -    getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
 -
--    // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
+-    copy {
+-      from channelPropsFile
+-      filter(ReplaceTokens,
+-        beginToken: '__',
+-        endToken: '__',
+-        tokens: [
+-          'SUFFIX': channelSuffix
+-        ]
+-      )
+-      into getdownAppBaseDir
+-    }
+-    getdownWebsiteResourceFilenames += file(channelPropsFile).getName()
+-
+-    // set some getdownTxt_ properties then go through all properties looking for getdownTxt_...
 -    def props = project.properties.sort { it.key }
 -    if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
 -      props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
 -    if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
 -      props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
 -    }
--    if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
--      props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
--      props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
--      props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
--      props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
+-    if (getdownImagesBuildDir != null && file(getdownImagesBuildDir).exists()) {
+-      props.put("getdown_txt_ui.background_image", "${getdownImagesBuildDir}/${getdown_background_image}")
+-      props.put("getdown_txt_ui.instant_background_image", "${getdownImagesBuildDir}/${getdown_instant_background_image}")
+-      props.put("getdown_txt_ui.error_background", "${getdownImagesBuildDir}/${getdown_error_background}")
+-      props.put("getdown_txt_ui.progress_image", "${getdownImagesBuildDir}/${getdown_progress_image}")
 -      props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
 -      props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
 -    }
 -
 -    props.put("getdown_txt_title", jalview_name)
--    props.put("getdown_txt_ui.name", install4jApplicationName)
+-    props.put("getdown_txt_ui.name", applicationName)
 -
 -    // start with appbase
--    getdownTextString += "appbase = ${getdownAppBase}\n"
+-    getdownTextLines += "appbase = ${getdownAppBase}"
 -    props.each{ prop, val ->
 -      if (prop.startsWith("getdown_txt_") && val != null) {
 -        if (prop.startsWith("getdown_txt_multi_")) {
 -          def key = prop.substring(18)
 -          val.split(",").each{ v ->
--            def line = "${key} = ${v}\n"
--            getdownTextString += line
+-            def line = "${key} = ${v}"
+-            getdownTextLines += line
 -          }
 -        } else {
 -          // file values rationalised
 -            }
 -          }
 -          if (! prop.startsWith("getdown_txt_resource")) {
--            def line = prop.substring(12) + " = ${val}\n"
--            getdownTextString += line
+-            def line = prop.substring(12) + " = ${val}"
+-            getdownTextLines += line
 -          }
 -        }
 -      }
 -    }
 -
 -    getdownWebsiteResourceFilenames.each{ filename ->
--      getdownTextString += "resource = ${filename}\n"
+-      getdownTextLines += "resource = ${filename}"
 -    }
 -    getdownResourceFilenames.each{ filename ->
 -      copy {
 -      if (s.exists()) {
 -        copy {
 -          from s
--          into "${getdownWebsiteDir}/${getdown_wrapper_script_dir}"
+-          into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}"
 -        }
--        getdownTextString += "resource = ${getdown_wrapper_script_dir}/${script}\n"
+-        getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}"
 -      }
 -    }
 -
 -        codeFiles += f
 -      }
 -    }
--    codeFiles.sort().each{f ->
+-    def jalviewJar = jar.archiveFileName.getOrNull()
+-    // put jalview.jar first for CLASSPATH and .properties files reasons
+-    codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f ->
 -      def name = f.getName()
--      def line = "code = ${getdownAppDistDir}/${name}\n"
--      getdownTextString += line
+-      def line = "code = ${getdownAppDistDir}/${name}"
+-      getdownTextLines += line
 -      copy {
 -        from f.getPath()
 -        into getdownAppDir
 -    def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
 -    j11libFiles.sort().each{f ->
 -    def name = f.getName()
--    def line = "code = ${getdown_j11lib_dir}/${name}\n"
--    getdownTextString += line
+-    def line = "code = ${getdown_j11lib_dir}/${name}"
+-    getdownTextLines += line
 -    copy {
 -    from f.getPath()
 -    into getdownJ11libDir
 -     */
 -
 -    // getdown-launcher.jar should not be in main application class path so the main application can move it when updated.  Listed as a resource so it gets updated.
--    //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
--    getdownTextString += "resource = ${getdown_launcher_new}\n"
--    getdownTextString += "class = ${main_class}\n"
+-    //getdownTextLines += "class = " + file(getdownLauncher).getName()
+-    getdownTextLines += "resource = ${getdown_launcher_new}"
+-    getdownTextLines += "class = ${main_class}"
 -    // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
 -    if (getdownSetAppBaseProperty) {
--      getdownTextString += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}\n"
--      getdownTextString += "jvmarg = -Dgetdownappbase=${getdownAppBase}\n"
+-      getdownTextLines += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}"
+-      getdownTextLines += "jvmarg = -Dgetdownappbase=${getdownAppBase}"
 -    }
 -
--    def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
--    getdown_txt.write(getdownTextString)
+-    def getdownTxt = file("${getdownAppBaseDir}/getdown.txt")
+-    getdownTxt.write(getdownTextLines.join("\n"))
 -
--    def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
--    def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
+-    getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
+-    def launchJvl = file("${getdownAppBaseDir}/${getdownLaunchJvl}")
 -    launchJvl.write("appbase=${getdownAppBase}")
 -
 -    // files going into the getdown website dir: getdown-launcher.jar
 -    copy {
 -      from getdownLauncher
 -      rename(file(getdownLauncher).getName(), getdown_launcher_new)
--      into getdownWebsiteDir
+-      into getdownAppBaseDir
 -    }
 -
 -    // files going into the getdown website dir: getdown-launcher(-local).jar
 -      if (file(getdownLauncher).getName() != getdown_launcher) {
 -        rename(file(getdownLauncher).getName(), getdown_launcher)
 -      }
--      into getdownWebsiteDir
+-      into getdownAppBaseDir
 -    }
 -
 -    // files going into the getdown website dir: ./install dir and files
 -    if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
 -      copy {
--        from getdown_txt
+-        from getdownTxt
 -        from getdownLauncher
 -        from "${getdownAppDir}/${getdown_build_properties}"
 -        if (file(getdownLauncher).getName() != getdown_launcher) {
 -
 -    // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
 -    copy {
--      from getdown_txt
+-      from getdownTxt
 -      from launchJvl
 -      from getdownLauncher
--      from "${getdownWebsiteDir}/${getdown_build_properties}"
+-      from "${getdownAppBaseDir}/${getdown_build_properties}"
+-      from "${getdownAppBaseDir}/${channel_props}"
 -      if (file(getdownLauncher).getName() != getdown_launcher) {
 -        rename(file(getdownLauncher).getName(), getdown_launcher)
 -      }
 -      into getdownFilesDir
 -    }
 -
--    // and ./resources (not all downloaded by getdown)
+-    // and ./resource (not all downloaded by getdown)
 -    copy {
 -      from getdownResourceDir
 -      into "${getdownFilesDir}/${getdown_resource_dir}"
 -  if (buildDist) {
 -    inputs.dir("${jalviewDir}/${package_dir}")
 -  }
--  outputs.dir(getdownWebsiteDir)
+-  outputs.dir(getdownAppBaseDir)
 -  outputs.dir(getdownFilesDir)
 -}
 -
 -    classpath = files(getdownLauncher)
 -  }
 -  main = "com.threerings.getdown.tools.Digester"
--  args getdownWebsiteDir
--  inputs.dir(getdownWebsiteDir)
--  outputs.file("${getdownWebsiteDir}/digest2.txt")
+-  args getdownAppBaseDir
+-  inputs.dir(getdownAppBaseDir)
+-  outputs.file("${getdownAppBaseDir}/digest2.txt")
 -}
 -
 -
 -  dependsOn getdownDigest
 -  doLast {
 -    if (reportRsyncCommand) {
--      def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
+-      def fromDir = getdownAppBaseDir + (getdownAppBaseDir.endsWith('/')?'':'/')
 -      def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
 -      println "LIKELY RSYNC COMMAND:"
 -      println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
 -    }
 -  }
 -}
+-
+-task getdownArchiveBuild() {
+-  group = "distribution"
+-  description = "Put files in the archive dir to go on the website"
+-
+-  dependsOn getdownWebsite
+-
+-  def v = "v${JALVIEW_VERSION_UNDERSCORES}"
+-  def vDir = "${getdownArchiveDir}/${v}"
+-  getdownFullArchiveDir = "${vDir}/getdown"
+-  getdownVersionLaunchJvl = "${vDir}/jalview-${v}.jvl"
+-
+-  def vAltDir = "alt_${v}"
+-  def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images"
+-
+-  doFirst {
+-    // cleanup old "old" dir
+-    delete getdownArchiveDir
+-
+-    def getdownArchiveTxt = file("${getdownFullArchiveDir}/getdown.txt")
+-    getdownArchiveTxt.getParentFile().mkdirs()
+-    def getdownArchiveTextLines = []
+-    def getdownFullArchiveAppBase = "${getdownArchiveAppBase}${getdownArchiveAppBase.endsWith("/")?"":"/"}${v}/getdown/"
+-
+-    // the libdir
+-    copy {
+-      from "${getdownAppBaseDir}/${getdownAppDistDir}"
+-      into "${getdownFullArchiveDir}/${vAltDir}"
+-    }
+-
+-    getdownTextLines.each { line ->
+-      line = line.replaceAll("^(?<s>appbase\\s*=\\s*).*", '${s}'+getdownFullArchiveAppBase)
+-      line = line.replaceAll("^(?<s>(resource|code)\\s*=\\s*)${getdownAppDistDir}/", '${s}'+vAltDir+"/")
+-      line = line.replaceAll("^(?<s>ui.background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background.png")
+-      line = line.replaceAll("^(?<s>ui.instant_background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_initialising.png")
+-      line = line.replaceAll("^(?<s>ui.error_background\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_error.png")
+-      line = line.replaceAll("^(?<s>ui.progress_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_progress_bar.png")
+-      // remove the existing resource = resource/ or bin/ lines
+-      if (! line.matches("resource\\s*=\\s*(resource|bin)/.*")) {
+-        getdownArchiveTextLines += line
+-      }
+-    }
+-
+-    // the resource dir -- add these files as resource lines in getdown.txt
+-    copy {
+-      from "${archiveImagesDir}"
+-      into "${getdownFullArchiveDir}/${getdown_resource_dir}"
+-      eachFile { file ->
+-        getdownArchiveTextLines += "resource = ${getdown_resource_dir}/${file.getName()}"
+-      }
+-    }
+-
+-    getdownArchiveTxt.write(getdownArchiveTextLines.join("\n"))
+-
+-    def vLaunchJvl = file(getdownVersionLaunchJvl)
+-    vLaunchJvl.getParentFile().mkdirs()
+-    vLaunchJvl.write("appbase=${getdownFullArchiveAppBase}\n")
+-    def vLaunchJvlPath = vLaunchJvl.toPath().toAbsolutePath()
+-    def jvlLinkPath = file("${vDir}/jalview.jvl").toPath().toAbsolutePath()
+-    // for some reason filepath.relativize(fileInSameDirPath) gives a path to "../" which is wrong
+-    //java.nio.file.Files.createSymbolicLink(jvlLinkPath, jvlLinkPath.relativize(vLaunchJvlPath));
+-    java.nio.file.Files.createSymbolicLink(jvlLinkPath, java.nio.file.Paths.get(".",vLaunchJvl.getName()));
+-
+-    // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
+-    copy {
+-      from getdownLauncher
+-      from "${getdownAppBaseDir}/${getdownLaunchJvl}"
+-      from "${getdownAppBaseDir}/${getdown_launcher_new}"
+-      from "${getdownAppBaseDir}/${channel_props}"
+-      if (file(getdownLauncher).getName() != getdown_launcher) {
+-        rename(file(getdownLauncher).getName(), getdown_launcher)
+-      }
+-      into getdownFullArchiveDir
+-    }
+-
+-  }
+-}
+-
+-task getdownArchiveDigest(type: JavaExec) {
+-  group = "distribution"
+-  description = "Digest the getdown archive folder"
+-
+-  dependsOn getdownArchiveBuild
+-
+-  doFirst {
+-    classpath = files(getdownLauncher)
+-    args getdownFullArchiveDir
+-  }
+-  main = "com.threerings.getdown.tools.Digester"
+-  inputs.dir(getdownFullArchiveDir)
+-  outputs.file("${getdownFullArchiveDir}/digest2.txt")
+-}
 -
+-task getdownArchive() {
+-  group = "distribution"
+-  description = "Build the website archive dir with getdown digest"
+-
+-  dependsOn getdownArchiveBuild
+-  dependsOn getdownArchiveDigest
+-}
 -
 -tasks.withType(JavaCompile) {
 -      options.encoding = 'UTF-8'
 -
 -clean {
 -  doFirst {
--    delete getdownWebsiteDir
+-    delete getdownAppBaseDir
 -    delete getdownFilesDir
+-    delete getdownArchiveDir
 -  }
 -}
 -
 -      }
 -    }
 -
+-    // disable install screen for OSX dmg (for 2.11.2.0)
+-    install4jConfigXml.'**'.macosArchive.each { macosArchive -> 
+-      macosArchive.attributes().remove('executeSetupApp')
+-      macosArchive.attributes().remove('setupAppId')
+-    }
+-
 -    // turn off checksum creation for LOCAL channel
 -    def e = install4jConfigXml.application[0]
--    if (CHANNEL == "LOCAL") {
--      e.'@createChecksums' = "false"
--    } else {
--      e.'@createChecksums' = "true"
--    }
+-    e.'@createChecksums' = string(install4jCheckSums)
 -
 -    // put file association actions where placeholder action is
 -    def install4jFileAssociationsText = install4jFileAssociationsFile.text
 -  }
 -}
 -
+-task cleanInstallersDataFiles {
+-  def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
+-  def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
+-  def hugoDataJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
+-  doFirst {
+-    delete installersOutputTxt
+-    delete installersSha256
+-    delete hugoDataJsonFile
+-  }
+-}
+-
+-task install4jDMGBackgroundImageCopy {
+-  inputs.file "${install4jDMGBackgroundImageDir}/${install4jDMGBackgroundImageFile}"
+-  outputs.dir "${install4jDMGBackgroundImageBuildDir}"
+-  doFirst {
+-    copy {
+-      from(install4jDMGBackgroundImageDir) {
+-        include(install4jDMGBackgroundImageFile)
+-      }
+-      into install4jDMGBackgroundImageBuildDir
+-    }
+-  }
+-}
+-
+-task install4jDMGBackgroundImageProcess {
+-  dependsOn install4jDMGBackgroundImageCopy
+-
+-  doFirst {
+-    if (backgroundImageText) {
+-      if (convertBinary == null) {
+-        throw new StopExecutionException("No ImageMagick convert binary installed at '${convertBinaryExpectedLocation}'")
+-      }
+-      if (!project.hasProperty("install4j_background_image_text_suffix_cmd")) {
+-        throw new StopExecutionException("No property 'install4j_background_image_text_suffix_cmd' defined. See channel_gradle.properties for channel ${CHANNEL}")
+-      }
+-      fileTree(dir: install4jDMGBackgroundImageBuildDir, include: "*.png").getFiles().each { file ->
+-        exec {
+-          executable convertBinary
+-          args = [
+-            file.getPath(),
+-            '-font', install4j_background_image_text_font,
+-            '-fill', install4j_background_image_text_colour,
+-            '-draw', sprintf(install4j_background_image_text_suffix_cmd, channelSuffix),
+-            '-draw', sprintf(install4j_background_image_text_commit_cmd, "git-commit: ${gitHash}"),
+-            '-draw', sprintf(install4j_background_image_text_date_cmd, getDate("yyyy-MM-dd HH:mm:ss")),
+-            file.getPath()
+-          ]
+-        }
+-      }
+-    }
+-  }
+-}
+-
+-task install4jDMGBackgroundImage {
+-  dependsOn install4jDMGBackgroundImageProcess
+-}
 -
--task installers(type: com.install4j.gradle.Install4jTask) {
+-task installerFiles(type: com.install4j.gradle.Install4jTask) {
 -  group = "distribution"
 -  description = "Create the install4j installers"
 -  dependsOn getdown
 -  dependsOn copyInstall4jTemplate
+-  dependsOn cleanInstallersDataFiles
+-  dependsOn install4jDMGBackgroundImage
 -
 -  projectFile = install4jConfFile
 -
 -    filesMd5 = filesMd5.substring(0,8)
 -  }
 -  def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
--  // make install4jBuildDir relative to jalviewDir
--  def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
 -
 -  variables = [
 -    'JALVIEW_NAME': jalview_name,
--    'JALVIEW_APPLICATION_NAME': install4jApplicationName,
+-    'JALVIEW_APPLICATION_NAME': applicationName,
 -    'JALVIEW_DIR': "../..",
 -    'OSX_KEYSTORE': OSX_KEYSTORE,
 -    'OSX_APPLEID': OSX_APPLEID,
 -    'JAVA_VERSION': JAVA_VERSION,
 -    'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
 -    'VERSION': JALVIEW_VERSION,
--    'MACOS_JAVA_VM_DIR': macosJavaVMDir,
--    'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
--    'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
--    'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
--    'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
--    'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
 -    'COPYRIGHT_MESSAGE': install4j_copyright_message,
 -    'BUNDLE_ID': install4jBundleId,
 -    'INTERNAL_ID': install4jInternalId,
 -    'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
 -    'MACOS_DMG_DS_STORE': install4jDMGDSStore,
--    'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
+-    'MACOS_DMG_BG_IMAGE': "${install4jDMGBackgroundImageBuildDir}/${install4jDMGBackgroundImageFile}",
 -    'WRAPPER_LINK': getdownWrapperLink,
 -    'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
 -    'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
+-    'BATCH_WRAPPER_SCRIPT': getdown_batch_wrapper_script,
 -    'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
 -    'INSTALLER_NAME': install4jInstallerName,
 -    'INSTALL4J_UTILS_DIR': install4j_utils_dir,
--    'GETDOWN_WEBSITE_DIR': getdown_website_dir,
+-    'GETDOWN_CHANNEL_DIR': getdownChannelDir,
 -    'GETDOWN_FILES_DIR': getdown_files_dir,
 -    'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
 -    'GETDOWN_DIST_DIR': getdownAppDistDir,
 -    'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
 -    'PNG_ICON_FILE': install4jPngIconFile,
 -    'BACKGROUND': install4jBackground,
+-  ]
 -
+-  def varNameMap = [
+-    'mac': 'MACOS',
+-    'windows': 'WINDOWS',
+-    'linux': 'LINUX'
 -  ]
+-  
+-  // these are the bundled OS/architecture VMs needed by install4j
+-  def osArch = [
+-    [ "mac", "x64" ],
+-    [ "mac", "aarch64" ],
+-    [ "windows", "x64" ],
+-    [ "linux", "x64" ],
+-    [ "linux", "aarch64" ]
+-  ]
+-  osArch.forEach { os, arch ->
+-    variables[ sprintf("%s_%s_JAVA_VM_DIR", varNameMap[os], arch.toUpperCase(Locale.ROOT)) ] = sprintf("%s/jre-%s-%s-%s/jre", jreInstallsDir, JAVA_INTEGER_VERSION, os, arch)
+-    // N.B. For some reason install4j requires the below filename to have underscores and not hyphens
+-    // otherwise running `gradle installers` generates a non-useful error:
+-    // `install4j: compilation failed. Reason: java.lang.NumberFormatException: For input string: "windows"`
+-    variables[ sprintf("%s_%s_JAVA_VM_TGZ", varNameMap[os], arch.toUpperCase(Locale.ROOT)) ] = sprintf("%s/tgz/jre_%s_%s_%s.tar.gz", jreInstallsDir, JAVA_INTEGER_VERSION, os, arch)
+-  }
 -
 -  //println("INSTALL4J VARIABLES:")
 -  //variables.each{k,v->println("${k}=${v}")}
 -  }
 -  //verbose=true
 -
--  inputs.dir(getdownWebsiteDir)
+-  inputs.dir(getdownAppBaseDir)
 -  inputs.file(install4jConfFile)
 -  inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
--  inputs.dir(macosJavaVMDir)
--  inputs.dir(windowsJavaVMDir)
 -  outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
 -}
 -
+-def getDataHash(File myFile) {
+-  HashCode hash = Files.asByteSource(myFile).hash(Hashing.sha256())
+-  return myFile.exists()
+-  ? [
+-      "file" : myFile.getName(),
+-      "filesize" : myFile.length(),
+-      "sha256" : hash.toString()
+-    ]
+-  : null
+-}
+-
+-def writeDataJsonFile(File installersOutputTxt, File installersSha256, File dataJsonFile) {
+-  def hash = [
+-    "channel" : getdownChannelName,
+-    "date" : getDate("yyyy-MM-dd HH:mm:ss"),
+-    "git-commit" : "${gitHash} [${gitBranch}]",
+-    "version" : JALVIEW_VERSION
+-  ]
+-  // install4j installer files
+-  if (installersOutputTxt.exists()) {
+-    def idHash = [:]
+-    installersOutputTxt.readLines().each { def line ->
+-      if (line.startsWith("#")) {
+-        return;
+-      }
+-      line.replaceAll("\n","")
+-      def vals = line.split("\t")
+-      def filename = vals[3]
+-      def filesize = file(filename).length()
+-      filename = filename.replaceAll(/^.*\//, "")
+-      hash[vals[0]] = [ "id" : vals[0], "os" : vals[1], "name" : vals[2], "file" : filename, "filesize" : filesize ]
+-      idHash."${filename}" = vals[0]
+-    }
+-    if (install4jCheckSums && installersSha256.exists()) {
+-      installersSha256.readLines().each { def line ->
+-        if (line.startsWith("#")) {
+-          return;
+-        }
+-        line.replaceAll("\n","")
+-        def vals = line.split(/\s+\*?/)
+-        def filename = vals[1]
+-        def innerHash = (hash.(idHash."${filename}"))."sha256" = vals[0]
+-      }
+-    }
+-  }
+-
+-  [
+-    "JAR": shadowJar.archiveFile, // executable JAR
+-    "JVL": getdownVersionLaunchJvl, // version JVL
+-    "SOURCE": sourceDist.archiveFile // source TGZ
+-  ].each { key, value ->
+-    def file = file(value)
+-    if (file.exists()) {
+-      def fileHash = getDataHash(file)
+-      if (fileHash != null) {
+-        hash."${key}" = fileHash;
+-      }
+-    }
+-  }
+-  return dataJsonFile.write(new JsonBuilder(hash).toPrettyString())
+-}
+-
+-task staticMakeInstallersJsonFile {
+-  doFirst {
+-    def output = findProperty("i4j_output")
+-    def sha256 = findProperty("i4j_sha256")
+-    def json = findProperty("i4j_json")
+-    if (output == null || sha256 == null || json == null) {
+-      throw new GradleException("Must provide paths to all of output.txt, sha256sums, and output.json with '-Pi4j_output=... -Pi4j_sha256=... -Pi4j_json=...")
+-    }
+-    writeDataJsonFile(file(output), file(sha256), file(json))
+-  }
+-}
+-
+-task installers {
+-  dependsOn installerFiles
+-}
+-
 -
 -spotless {
 -  java {
 -  }
 -}
 -
+-task createSourceReleaseProperties(type: WriteProperties) {
+-  group = "distribution"
+-  description = "Create the source RELEASE properties file"
+-  
+-  def sourceTarBuildDir = "${buildDir}/sourceTar"
+-  def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE"
+-  outputFile (sourceReleasePropertiesFile)
+-
+-  doFirst {
+-    releaseProps.each{ key, val -> property key, val }
+-    property "git.branch", gitBranch
+-    property "git.hash", gitHash
+-  }
+-
+-  outputs.file(outputFile)
+-}
 -
 -task sourceDist(type: Tar) {
 -  group "distribution"
 -
 -  dependsOn createBuildProperties
 -  dependsOn convertMdFiles
+-  dependsOn eclipseAllPreferences
+-  dependsOn createSourceReleaseProperties
+-
 -
--  def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
--  def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
+-  def outputFileName = "${project.name}_${JALVIEW_VERSION_UNDERSCORES}.tar.gz"
 -  archiveFileName = outputFileName
 -  
 -  compression Compression.GZIP
 -    "*locales/**",
 -    "utils/InstallAnywhere",
 -    "**/*.log",
+-    "RELEASE",
 -  ] 
 -  def PROCESS_FILES=[
 -    "AUTHORS",
 -    "FEATURETODO",
 -    "LICENSE",
 -    "**/README",
--    "RELEASE",
 -    "THIRDPARTYLIBS",
 -    "TESTNG",
 -    "build.gradle",
 -    "**/*.sh",
 -  ]
 -  def INCLUDE_FILES=[
--    ".settings/org.eclipse.jdt.core.jalview.prefs",
+-    ".classpath",
+-    ".settings/org.eclipse.buildship.core.prefs",
+-    ".settings/org.eclipse.jdt.core.prefs"
 -  ]
 -
 -  from(jalviewDir) {
 -    exclude ("utils/InstallAnywhere")
 -
 -    exclude (getdown_files_dir)
--    exclude (getdown_website_dir)
+-    // getdown_website_dir and getdown_archive_dir moved to build/website/docroot/getdown
+-    //exclude (getdown_website_dir)
+-    //exclude (getdown_archive_dir)
 -
 -    // exluding these as not using jars as modules yet
 -    exclude ("${j11modDir}/**/*.jar")
 -    })
 -  }
 -
+-  def sourceTarBuildDir = "${buildDir}/sourceTar"
+-  from(sourceTarBuildDir) {
+-    // this includes the appended RELEASE properties file
+-  }
 -}
 -
+-task dataInstallersJson {
+-  group "website"
+-  description "Create the installers-VERSION.json data file for installer files created"
+-
+-  mustRunAfter installers
+-  mustRunAfter shadowJar
+-  mustRunAfter sourceDist
+-  mustRunAfter getdownArchive
+-
+-  def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
+-  def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
+-
+-  if (installersOutputTxt.exists()) {
+-    inputs.file(installersOutputTxt)
+-  }
+-  if (install4jCheckSums && installersSha256.exists()) {
+-    inputs.file(installersSha256)
+-  }
+-  [
+-    shadowJar.archiveFile, // executable JAR
+-    getdownVersionLaunchJvl, // version JVL
+-    sourceDist.archiveFile // source TGZ
+-  ].each { fileName ->
+-    if (file(fileName).exists()) {
+-      inputs.file(fileName)
+-    }
+-  }
+-
+-  outputs.file(hugoDataJsonFile)
+-
+-  doFirst {
+-    writeDataJsonFile(installersOutputTxt, installersSha256, hugoDataJsonFile)
+-  }
+-}
 -
 -task helppages {
+-  group "help"
+-  description "Copies all help pages to build dir. Runs ant task 'pubhtmlhelp'."
+-
 -  dependsOn copyHelp
 -  dependsOn pubhtmlhelp
 -  
 -  preserve {
 -    include "**"
 -  }
+-
+-  // should this be exclude really ?
+-  duplicatesStrategy "INCLUDE"
+-
 -  outputs.files outputFiles
 -  inputs.files inputFiles
 -}
 -      println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
 -    }
 -  }
+-
 -  //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
 -  def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
 -  executable(eclipseBinary)
 -          new org.apache.tools.ant.util.TeeOutputStream(
 -            logErrFOS,
 -            stderr),
--          errorOutput)
+-          System.err)
 -    } else {
 -      standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
 -        logOutFOS,
 -task eclipseAutoBuildTask {
 -  //dependsOn jalviewjsIDE_checkJ2sPlugin
 -  //dependsOn jalviewjsIDE_PrepareSite
-+  outputs.file("${outputDir}/${archiveFileName}")
- }
+-}
+-
 -
 -task jalviewjs {
 -  group "JalviewJS"
 -  description "Build the site"
 -  dependsOn jalviewjsBuildSite
--}
++  outputs.file("${outputDir}/${archiveFileName}")
+ }
index 5be7ab9..62816e5 100644 (file)
@@ -1,22 +1,22 @@
-application/x-jalview+xml+zip; jalview -open '%s'; description="Jalview File"; nametemplate=%s.jvp; test=test -n "$DISPLAY"; priority=10
-chemical/x-cif; jalview -open '%s'; description="CIF File"; nametemplate=%s.cif; test=test -n "$DISPLAY"; priority=4
-chemical/x-mmcif; jalview -open '%s'; description="mmCIF File"; nametemplate=%s.mcif; test=test -n "$DISPLAY"; priority=4
-chemical/x-pdb; jalview -open '%s'; description="PDB File"; nametemplate=%s.pdb; test=test -n "$DISPLAY"; priority=4
-application/x-amsa+txt; jalview -open '%s'; description="AMSA File"; nametemplate=%s.amsa; test=test -n "$DISPLAY"; priority=9
-application/x-jalview-annotations+text; jalview -open '%s'; description="Jalview Annotations File"; nametemplate=%s.annotations; test=test -n "$DISPLAY"; priority=10
-application/x-jalview-biojson+json; jalview -open '%s'; description="BioJSON File"; nametemplate=%s.biojson; test=test -n "$DISPLAY"; priority=10
-application/x-blc+txt; jalview -open '%s'; description="BLC File"; nametemplate=%s.blc; test=test -n "$DISPLAY"; priority=9
-application/x-clustal+txt; jalview -open '%s'; description="Clustal File"; nametemplate=%s.aln; test=test -n "$DISPLAY"; priority=9
-application/x-fasta+txt; jalview -open '%s'; description="Fasta File"; nametemplate=%s.fa; test=test -n "$DISPLAY"; priority=9
-application/x-jalview-features+text; jalview -open '%s'; description="Jalview Features File"; nametemplate=%s.features; test=test -n "$DISPLAY"; priority=10
-application/x-gff2+txt; jalview -open '%s'; description="Generic Features Format v2 File"; nametemplate=%s.gff2; test=test -n "$DISPLAY"; priority=9
-application/x-gff3+txt; jalview -open '%s'; description="Generic Features Format v3 File"; nametemplate=%s.gff3; test=test -n "$DISPLAY"; priority=9
-application/x-jalview-jnet+text; jalview -open '%s'; description="JnetFile File"; nametemplate=%s.concise; test=test -n "$DISPLAY"; priority=10
-application/x-msf+txt; jalview -open '%s'; description="MSF File"; nametemplate=%s.msf; test=test -n "$DISPLAY"; priority=9
-application/x-pfam+txt; jalview -open '%s'; description="PFAM File"; nametemplate=%s.pfam; test=test -n "$DISPLAY"; priority=9
-application/x-phylip+txt; jalview -open '%s'; description="PHYLIP File"; nametemplate=%s.phy; test=test -n "$DISPLAY"; priority=9
-application/x-pileup+txt; jalview -open '%s'; description="PileUp File"; nametemplate=%s.pileup; test=test -n "$DISPLAY"; priority=9
-application/x-pir+txt; jalview -open '%s'; description="PIR File"; nametemplate=%s.pir; test=test -n "$DISPLAY"; priority=9
-application/rnaml+xml; jalview -open '%s'; description="RNAML File"; nametemplate=%s.rnaml; test=test -n "$DISPLAY"; priority=9
-application/x-jalview-scorematrix+text; jalview -open '%s'; description="Substitution Matrix File"; nametemplate=%s.mat; test=test -n "$DISPLAY"; priority=10
-application/x-stockholm+txt; jalview -open '%s'; description="Stockholm File"; nametemplate=%s.sto; test=test -n "$DISPLAY"; priority=9
+application/x-jalview+xml+zip; jalview '%s'; description="Jalview File"; nametemplate=%s.jvp; test=test -n "$DISPLAY"; priority=10
+chemical/x-cif; jalview '%s'; description="CIF File"; nametemplate=%s.cif; test=test -n "$DISPLAY"; priority=4
+chemical/x-mmcif; jalview '%s'; description="mmCIF File"; nametemplate=%s.mcif; test=test -n "$DISPLAY"; priority=4
+chemical/x-pdb; jalview '%s'; description="PDB File"; nametemplate=%s.pdb; test=test -n "$DISPLAY"; priority=4
+application/x-amsa+txt; jalview '%s'; description="AMSA File"; nametemplate=%s.amsa; test=test -n "$DISPLAY"; priority=9
+application/x-jalview-annotations+text; jalview '%s'; description="Jalview Annotations File"; nametemplate=%s.annotations; test=test -n "$DISPLAY"; priority=10
+application/x-jalview-biojson+json; jalview '%s'; description="BioJSON File"; nametemplate=%s.biojson; test=test -n "$DISPLAY"; priority=10
+application/x-blc+txt; jalview '%s'; description="BLC File"; nametemplate=%s.blc; test=test -n "$DISPLAY"; priority=9
+application/x-clustal+txt; jalview '%s'; description="Clustal File"; nametemplate=%s.aln; test=test -n "$DISPLAY"; priority=9
+application/x-fasta+txt; jalview '%s'; description="Fasta File"; nametemplate=%s.fa; test=test -n "$DISPLAY"; priority=9
+application/x-jalview-features+text; jalview '%s'; description="Jalview Features File"; nametemplate=%s.features; test=test -n "$DISPLAY"; priority=10
+application/x-gff2+txt; jalview '%s'; description="Generic Features Format v2 File"; nametemplate=%s.gff2; test=test -n "$DISPLAY"; priority=9
+application/x-gff3+txt; jalview '%s'; description="Generic Features Format v3 File"; nametemplate=%s.gff3; test=test -n "$DISPLAY"; priority=9
+application/x-jalview-jnet+text; jalview '%s'; description="JnetFile File"; nametemplate=%s.concise; test=test -n "$DISPLAY"; priority=10
+application/x-msf+txt; jalview '%s'; description="MSF File"; nametemplate=%s.msf; test=test -n "$DISPLAY"; priority=9
+application/x-pfam+txt; jalview '%s'; description="PFAM File"; nametemplate=%s.pfam; test=test -n "$DISPLAY"; priority=9
+application/x-phylip+txt; jalview '%s'; description="PHYLIP File"; nametemplate=%s.phy; test=test -n "$DISPLAY"; priority=9
+application/x-pileup+txt; jalview '%s'; description="PileUp File"; nametemplate=%s.pileup; test=test -n "$DISPLAY"; priority=9
+application/x-pir+txt; jalview '%s'; description="PIR File"; nametemplate=%s.pir; test=test -n "$DISPLAY"; priority=9
+application/rnaml+xml; jalview '%s'; description="RNAML File"; nametemplate=%s.rnaml; test=test -n "$DISPLAY"; priority=9
+application/x-jalview-scorematrix+text; jalview '%s'; description="Substitution Matrix File"; nametemplate=%s.mat; test=test -n "$DISPLAY"; priority=10
+application/x-stockholm+txt; jalview '%s'; description="Stockholm File"; nametemplate=%s.sto; test=test -n "$DISPLAY"; priority=9
index 4823bee..0f44579 100755 (executable)
@@ -7,11 +7,4 @@ if [ -n "${HOME}" -a \! -e ${HOME}/.jalview_properties ]; then
   /bin/cp /etc/jalview_properties ${HOME}/.jalview_properties
 fi
 
-# check to see if $1 is set and is not start of other cli set args
-OPEN=""
-if [ -n "$ARG1" -a "$ARG1" = "${ARG1#-}" ]; then
-  # first argument exists and does not start with a "-"
-  OPEN="-open"
-fi
-  
-java -jar /usr/share/java/jalview.jar $OPEN "$@"
+java -jar /usr/share/java/jalview.jar "$@"
index a0e8cd9..ce7f136 100644 (file)
@@ -300,6 +300,59 @@ task copyHelp(type: Copy) {
   outputs.dir(outputDir)
 }
 
+task releasesTemplates {
+  group "help"
+  description "Recreate whatsNew.html and releases.html from markdown files and templates in help"
+
+  dependsOn copyHelp
+
+  def releasesTemplateFile = file("${jalviewDir}/${releases_template}")
+  def whatsnewTemplateFile = file("${jalviewDir}/${whatsnew_template}")
+  def releasesHtmlFile = file("${helpBuildDir}/${help_dir}/${releases_html}")
+  def whatsnewHtmlFile = file("${helpBuildDir}/${help_dir}/${whatsnew_html}")
+  def releasesMdDir = "${jalviewDir}/${releases_dir}"
+  def whatsnewMdDir = "${jalviewDir}/${whatsnew_dir}"
+
+  doFirst {
+    def JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
+    def releaseMdFile = file("${releasesMdDir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
+    def whatsnewMdFile = file("${whatsnewMdDir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
+
+    if (CHANNEL == "RELEASE") {
+      if (!releaseMdFile.exists()) {
+        throw new GradleException("File ${releaseMdFile} must be created for RELEASE")
+      }
+      if (!whatsnewMdFile.exists()) {
+        throw new GradleException("File ${whatsnewMdFile} must be created for RELEASE")
+      }
+    }
+
+    def releaseFiles = fileTree(dir: releasesMdDir, include: "release-*.md")
+    def releaseFilesDates = releaseFiles.collectEntries {
+      [(it): getDate("")]
+    }
+    releaseFiles = releaseFiles.sort { a,b -> releaseFilesDates[a].compareTo(releaseFilesDates[b]) }
+
+    def releasesTemplate = releasesTemplateFile.text
+    def m = releasesTemplate =~ /(?s)__VERSION_LOOP_START__(.*)__VERSION_LOOP_END__/
+    def versionTemplate = m[0][1]
+
+    def versionsHtml = ""
+    def linkedVersions = []
+
+    releasesTemplate = releasesTemplate.replaceAll("(?s)__VERSION_LOOP_START__.*__VERSION_LOOP_END__", versionsHtml)
+    releasesHtmlFile.text = releasesTemplate
+
+    whatsnewHtmlFile.text = "Debian build " + getDate("yyyy-MM-dd HH:mm:ss")
+  }
+
+  inputs.file(releasesTemplateFile)
+  inputs.file(whatsnewTemplateFile)
+  inputs.dir(releasesMdDir)
+  inputs.dir(whatsnewMdDir)
+  outputs.file(releasesHtmlFile)
+  outputs.file(whatsnewHtmlFile)
+}
 
 task copyResources(type: Copy) {
   group = "build"
@@ -389,6 +442,7 @@ task prepare {
   dependsOn buildResources
   dependsOn copyDocs
   dependsOn copyHelp
+  dependsOn releasesTemplates
   dependsOn buildIndices
 }
 
@@ -453,7 +507,7 @@ task linkCheck(type: JavaExec) {
   def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
   classpath = files("${jalviewDir}/${utils_dir}")
   main = "HelpLinksChecker"
-  workingDir = jalviewDir
+  workingDir = "${helpBuildDir}"
   args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
 
   def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
index 14033a6..3c986a1 100755 (executable)
@@ -1,3 +1,11 @@
-#!/usr/bin/env sh
+#!/usr/bin/env bash
 
-java -cp "./bin/main:./j11lib/*:./resources:./help" jalview.bin.Jalview "${@}"
+if command -v tput 2>&1 >/dev/null; then
+  COLUMNS=$(tput cols) 2>/dev/null
+elif command -v stty 2>&1 >/dev/null; then
+  COLUMNS=$(stty size | cut -d" " -f2) 2>/dev/null
+elif command -v resize 2>&1 >/dev/null; then
+  COLUMNS=$(resize -u | grep COLUMNS= | sed -e 's/.*=//;s/;//') 2>/dev/null
+fi
+
+java "-DCONSOLEWIDTH=${COLUMNS}" -cp "./bin/main:./j11lib/*:./resources:./help" jalview.bin.Launcher "${@}"
index 7ae9a57..1098010 100755 (executable)
@@ -57,12 +57,6 @@ $CMDPATH = ( Get-Item $MyInvocation.MyCommand.Path )
 $SCRIPTPATH = Readlink-f -Link $CMDPATH
 $DIR = Split-Path -Path $SCRIPTPATH -Parent
 
-# set the "-open" parameter if myArg1 is non-zero-length, and not "open" or starts with a "-"
-$OPEN = ""
-if ( $myArg1.length -gt 0 -and ( -not $myArg1.StartsWith("-") ) -and $myArg1 -cne "open" ) {
-  $OPEN = "-open"
-}
-
 $APPDIR = If ( ( Split-Path -Path $DIR -Leaf ) -eq "bin" ) { Split-Path -Path $DIR -Parent } Else { $DIR }
 $JAVAEXE = If ( $myIsWindows ) { "java.exe" } Else { "java" }
 $JAVA = Join-Path -Path $APPDIR -ChildPath ( "jre/" + $( If ( $myIsMacOS ) { "Contents/Home/" } Else { "" } ) + "bin/${JAVAEXE}" )
@@ -81,7 +75,14 @@ if ( -not ( Test-Path -Path "${JAVA}" ) ) {
 
 $CLASSPATH = ( Select-String -Path "${GETDOWNTXT}" -AllMatches -Pattern "code\s*=\s*(.*)$" | foreach { Join-Path -Path $APPDIR -ChildPath $($_.Matches.Groups[1].Value ) } ) -join $( If ( $myIsWindows ) { ";" } Else { ":" } )
 
+# get console width
+$CONSOLEWIDTH = $Host.UI.RawUI.WindowSize.Width
+
 # quote the args and the command (in case of spaces) with escape chars (`) and precede with & to indicate command not string
-$myArgsString = '"' + $($myArgs -join '" "') + '"'
-Invoke-Expression -Command "& `"${JAVA}`" -cp `"${CLASSPATH}`" jalview.bin.Launcher ${OPEN} ${myArgsString}"
+if ( $myArgs.count -eq 0 ) {
+  Invoke-Expression -Command "& `"${JAVA}`" `"-DCONSOLEWIDTH=${CONSOLEWIDTH}`" `"-Dgetdownappdir=${APPDIR}`" -cp `"${CLASSPATH}`" jalview.bin.Launcher"
+} else {
+  $myArgsString = '"' + $($myArgs -join '" "') + '"'
+  Invoke-Expression -Command "& `"${JAVA}`" `"-DCONSOLEWIDTH=${CONSOLEWIDTH}`" `"-Dgetdownappdir=${APPDIR}`" -cp `"${CLASSPATH}`" jalview.bin.Launcher ${myArgsString}"
+}
 
index 112c3e6..849d71a 100755 (executable)
@@ -36,18 +36,45 @@ if [ "$( uname -s )" = "Darwin" ]; then
   ISMACOS=1
 fi
 
+# check for headless mode
+HEADLESS=0
+GUI=0
+HELP=0
+DEBUG=0
+for RAWARG in "${@}"; do
+  ARG="${RAWARG%%=*}"
+  case "${ARG}" in
+    --headless|--output|--image|--structureimage)
+      HEADLESS=1
+      ;;
+    --help|--help-*|--version|-h)
+      HELP=1
+      ;;
+    --gui)
+      GUI=1
+      ;;
+    --debug)
+      DEBUG=1
+      ;;
+  esac
+  
+  if [ "${HELP}" = 1 ]; then
+    # --help takes precedence
+    HEADLESS=1
+    GUI=0
+  elif [ "${GUI}" = 1 ]; then
+    # --gui takes precedence over --headless
+    HEADLESS=0
+  fi
+done
+
 declare -a JVMARGS=()
 
 # set vars for being inside the macos App Bundle
 if [ "${ISMACOS}" = 1 ]; then
 # MACOS ONLY
   DIR="$(dirname "$(readlinkf "$0")")"
-  APP="${DIR%.app/Contents/*}".app
-  if [ "${APP}" = "${APP%.app}" ]; then
-    echo "Could not find Jalview.app" >&2
-    exit 2
-  fi
-  APPDIR="${APP}/Contents/Resources/app"
+  APPDIR="${DIR%/bin}"
   JAVA="${APPDIR}/jre/Contents/Home/bin/java"
   JVMARGS=( "${JVMARGS[@]}" "-Xdock:icon=${APPDIR}/resource/jalview_logo.png" )
 else
@@ -57,6 +84,11 @@ else
   JAVA="${APPDIR}/jre/bin/java"
 fi
 
+if [ "${HEADLESS}" = 1 ]; then
+  # this suppresses the Java icon appearing in the macOS Dock and maybe other things in other OSes
+  JVMARGS=( "${JVMARGS[@]}" "-Djava.awt.headless=true" )
+fi
+
 SYSJAVA=java
 GETDOWNTXT="${APPDIR}/getdown.txt"
 
@@ -65,7 +97,8 @@ CLASSPATH=""
 declare -a JARPATHS=()
 if [ -e "${GETDOWNTXT}" ]; then
   # always check grep and sed regexes on macos -- they're not the same
-  for JAR in $(grep -e '^code\s*=\s*' "${GETDOWNTXT}" | sed -e 's/^code\s*=\s*//;'); do
+for JAR in $(grep -e '^code[[:space:]]*=[[:space:]]*' "${GETDOWNTXT}" | while read -r line; do echo $line | sed -E -e 's/code[[:space:]]*=[[:space:]]*//;'; done);
+  do
     [ -n "${CLASSPATH}" ] && CLASSPATH="${CLASSPATH}:"
     CLASSPATH="${CLASSPATH}${APPDIR}/${JAR}"
     JARPATHS=( "${JARPATHS[@]}" "${APPDIR}/${JAR}" )
@@ -77,10 +110,9 @@ fi
 
 # WINDOWS ONLY (Cygwin or WSL)
 # change paths for Cygwin or Windows Subsystem for Linux (WSL)
-if [ "${ISMACOS}" != 1 ]; then # macos doesn't like uname -o, best to avoid
+if [ "${ISMACOS}" != 1 ]; then # older macos doesn't like uname -o, best to avoid
   if [ "$(uname -o)" = "Cygwin" ]; then
   # CYGWIN
-    echo "When using relative paths in args within Cygwin, please start with './' or '../'" >&2
     CLASSPATH=$(cygpath -pw "${CLASSPATH}")
     # now for some arg paths fun. only translating paths starting with './', '../', '/' or '~'
     ARGS=()
@@ -91,9 +123,8 @@ if [ "${ISMACOS}" != 1 ]; then # macos doesn't like uname -o, best to avoid
         ARGS=( "${ARGS[@]}" "${ARG}" )
       fi
     done
-  elif uname -r | grep Microsoft >/dev/null; then
+  elif uname -r | grep -i microsoft | grep -i wsl >/dev/null; then
   # WSL
-    echo "When using relative paths in args within WSL, please start with './' or '../'" >&2
     CLASSPATH=""
     for JARPATH in "${JARPATHS[@]}"; do
       [ -n "${CLASSPATH}" ] && CLASSPATH="${CLASSPATH};"
@@ -115,18 +146,25 @@ if [ "${ISMACOS}" != 1 ]; then # macos doesn't like uname -o, best to avoid
   fi
 fi
 
+# get console width -- three ways to try, just in case
+if command -v tput 2>&1 >/dev/null; then
+  COLUMNS=$(tput cols) 2>/dev/null
+elif command -v stty 2>&1 >/dev/null; then
+  COLUMNS=$(stty size | cut -d" " -f2) 2>/dev/null
+elif command -v resize 2>&1 >/dev/null; then
+  COLUMNS=$(resize -u | grep COLUMNS= | sed -e 's/.*=//;s/;//') 2>/dev/null
+fi
+JVMARGS=( "${JVMARGS[@]}" "-DCONSOLEWIDTH=${COLUMNS}" )
+JVMARGS=( "${JVMARGS[@]}" "-Dgetdownappdir=${APPDIR}" )
+
 # Is there a bundled Java?  If not just try one in the PATH (do need .exe in WSL)
 if [ \! -e "${JAVA}" ]; then
   JAVA=$SYSJAVA
   echo "Cannot find bundled java, using system ${JAVA} and hoping for the best!" >&2
 fi
 
-# check to see if $1 is set and is not start of other cli args
-OPEN=""
-if [ -n "${ARG1}" -a "${ARG1}" = "${ARG1#-}" -a "${ARG1}" != "open" ]; then
- # first argument exists and does not start with a "-" and is not "open"
- OPEN="-open"
+if [ "${DEBUG}" = 1 ]; then
+ echo Shell running: \""${JAVA}"\" \""${JVMARGS[@]}"\" -cp \""${CLASSPATH}"\" jalview.bin.Launcher "${ARGS[@]}"
 fi
 
-# don't quote $OPEN (don't want it accidentally mistaken as an empty string arg!)
-"${JAVA}" "${JVMARGS[@]}" -cp "${CLASSPATH}" jalview.bin.Launcher ${OPEN} "${ARGS[@]}"
+"${JAVA}" "${JVMARGS[@]}" -cp "${CLASSPATH}" jalview.bin.Launcher "${ARGS[@]}"
index 46feaed..b0887e3 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<install4j version="10.0.4" transformSequenceNumber="10">
-  <directoryPresets config="bin/jalview" />
+<install4j version="10.0.6" transformSequenceNumber="10">
+  <directoryPresets config="bin/Jalview" />
   <application name="${compiler:JALVIEW_APPLICATION_NAME}" applicationId="${compiler:WINDOWS_APPLICATION_ID}" mediaDir="${compiler:BUILD_DIR}" lzmaCompression="true" shortName="${compiler:INTERNAL_ID}" publisher="University of Dundee" publisherWeb="https://www.jalview.org/" version="${compiler:JALVIEW_VERSION}" allPathsRelative="true" macVolumeId="5aac4968c304f65" javaMinVersion="${compiler:JAVA_MIN_VERSION}" javaMaxVersion="${compiler:JAVA_MAX_VERSION}" allowBetaVM="true" jdkMode="jdk" jdkName="JDK 11.0">
     <searchSequence>
       <directory location="${compiler:JRE_DIR}" />
       <variable name="APPLICATION_CATEGORIES" value="Science;Biology;Java;" />
       <variable name="APPLICATION_FOLDER" value="Jalview" />
       <variable name="UNIX_APPLICATION_FOLDER" value="jalview" />
-      <variable name="EXECUTABLE_NAME" value="jalview" />
+      <variable name="EXECUTABLE_NAME" value="jalviewg" />
       <variable name="EXTRA_SCHEME" value="jalviewx" />
       <variable name="MAC_ICONS_FILE" value="utils/channels/release/images/jalview_logo.icns" />
       <variable name="WINDOWS_ICONS_FILE" value="utils/channels/release/images/jalview_logo.ico" />
       <variable name="PNG_ICON_FILE" value="utils/channels/release/images/jalview_logo.png" />
       <variable name="BACKGROUND" value="utils/channels/release/images/jalview_logo_background_fade-640x480.png" />
+      <variable name="BATCH_WRAPPER_SCRIPT" value="jalview.bat" />
+      <variable name="POWERSHELL_WRAPPER_SCRIPT" value="jalview.ps1" />
     </variables>
     <codeSigning macEnabled="true" macPkcs12File="${compiler:OSX_KEYSTORE}" macNotarize="true" appleId="${compiler:OSX_APPLEID}">
       <macAdditionalBinaries>
           <versionLine x="85" y="109" text="version ${compiler:sys.version}" />
         </text>
       </splashScreen>
-      <java mainClass="com.threerings.getdown.launcher.GetdownApp" vmParameters="-Dinstaller_template_version=${compiler:INSTALLER_TEMPLATE_VERSION}" arguments="&quot;${launcher:sys.launcherDirectory}&quot; jalview">
+      <java mainClass="com.threerings.getdown.launcher.GetdownApp" vmParameters="-Dinstaller_template_version=${compiler:INSTALLER_TEMPLATE_VERSION} -Dchannel.app_name=&quot;${compiler:JALVIEW_APPLICATION_NAME}&quot;" arguments="&quot;${launcher:sys.launcherDirectory}&quot; jalview">
         <classPath>
           <archive location="getdown-launcher.jar" />
           <archive location="${compiler:GETDOWN_INSTALL_DIR}/getdown-launcher.jar" failOnError="false" />
@@ -472,7 +474,7 @@ return console.askOkCancel(message, true);
           </screen>
           <screen id="15" beanClass="com.install4j.runtime.beans.screens.InstallationScreen" rollbackBarrier="true" rollbackBarrierExitCode="0">
             <actions>
-              <action id="17" beanClass="com.install4j.runtime.beans.actions.InstallFilesAction" actionElevationType="elevated" rollbackBarrierExitCode="0" failureStrategy="quit" errorMessage="${i18n:FileCorrupted}" />
+              <action id="17" beanClass="com.install4j.runtime.beans.actions.InstallFilesAction" rollbackBarrierExitCode="0" failureStrategy="quit" errorMessage="${i18n:FileCorrupted}" />
               <action name="Create program group (RELEASE)" id="18" customizedId="PROGRAM_GROUP_RELEASE" beanClass="com.install4j.runtime.beans.actions.desktop.CreateProgramGroupAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
                 <serializedBean>
                   <property name="allUsers" type="boolean" value="false" />
@@ -593,6 +595,38 @@ return console.askOkCancel(message, true);
           </screen>
           <screen id="20" beanClass="com.install4j.runtime.beans.screens.FinishedScreen" rollbackBarrierExitCode="0" finishScreen="true">
             <actions>
+              <action name="Linux Jalview Appname-&gt;java symlink" id="2813" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+                <serializedBean>
+                  <property name="file">
+                    <object class="java.io.File">
+                      <string>${compiler:JRE_DIR}/bin/java</string>
+                    </object>
+                  </property>
+                  <property name="linkFile">
+                    <object class="java.io.File">
+                      <string>${compiler:JRE_DIR}/bin/${compiler:JALVIEW_APPLICATION_NAME}</string>
+                    </object>
+                  </property>
+                  <property name="removeOnUninstall" type="boolean" value="false" />
+                </serializedBean>
+                <condition>Util.isLinux()</condition>
+              </action>
+              <action name="Linux Jalview-&gt;java symlink" id="2814" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+                <serializedBean>
+                  <property name="file">
+                    <object class="java.io.File">
+                      <string>${compiler:JRE_DIR}/bin/java</string>
+                    </object>
+                  </property>
+                  <property name="linkFile">
+                    <object class="java.io.File">
+                      <string>${compiler:JRE_DIR}/bin/${compiler:JALVIEW_NAME}</string>
+                    </object>
+                  </property>
+                  <property name="removeOnUninstall" type="boolean" value="false" />
+                </serializedBean>
+                <condition>Util.isLinux()</condition>
+              </action>
               <action id="2012" beanClass="com.install4j.runtime.beans.actions.desktop.CreateStartMenuEntryAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
                 <serializedBean>
                   <property name="allUsers" type="boolean" value="false" />
@@ -650,7 +684,7 @@ return console.askOkCancel(message, true);
                 </serializedBean>
                 <condition>context.getBooleanVariable("addToDockAction")</condition>
               </action>
-              <action name="Linux/Unix symlink" id="2733" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+              <action name="Linux/Unix symlink" id="2733" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
                 <serializedBean>
                   <property name="file">
                     <object class="java.io.File">
@@ -673,7 +707,7 @@ return console.askOkCancel(message, true);
                 </serializedBean>
                 <condition>context.getBooleanVariable("appendToPathAction")</condition>
               </action>
-              <action name="Create Linux/Unix symbolic link to jalview.sh in user's local bin" id="2739" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixUserBinDir}">
+              <action name="Create Linux/Unix symbolic link to jalview.sh in user's local bin" id="2739" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixUserBinDir}">
                 <serializedBean>
                   <property name="file">
                     <object class="java.io.File">
@@ -688,7 +722,7 @@ return console.askOkCancel(message, true);
                 </serializedBean>
                 <condition>context.getBooleanVariable("makeSymbolicLinkAction") &amp;&amp; ( Util.isLinux() || Util.isUnixInstaller() ) &amp;&amp; ( context.getVariable("unixUserBinDir") != null )</condition>
               </action>
-              <action name="Create macOS symbolic link to jalview in user's local bin" id="2743" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixUserBinDir}">
+              <action name="Create macOS symbolic link to jalview in user's local bin" id="2743" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixUserBinDir}">
                 <serializedBean>
                   <property name="file">
                     <object class="java.io.File">
@@ -703,6 +737,40 @@ return console.askOkCancel(message, true);
                 </serializedBean>
                 <condition>context.getBooleanVariable("makeSymbolicLinkAction") &amp;&amp; Util.isMacOS() &amp;&amp; ( context.getVariable("unixUserBinDir") != null ) &amp;&amp; ( context.getVariable("macWrapperLinkLocation") != null )</condition>
               </action>
+              <action name="Windows copy BAT file" id="2817" beanClass="com.install4j.runtime.beans.actions.files.CopyFileAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="destinationFile">
+                    <object class="java.io.File">
+                      <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:WRAPPER_LINK}.bat</string>
+                    </object>
+                  </property>
+                  <property name="files" type="array" class="java.io.File" length="1">
+                    <element index="0">
+                      <object class="java.io.File">
+                        <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BATCH_WRAPPER_SCRIPT}</string>
+                      </object>
+                    </element>
+                  </property>
+                </serializedBean>
+                <condition>Util.isWindows() &amp;&amp; !(((String)context.getCompilerVariable("WRAPPER_LINK")+".bat").equals((String)context.getCompilerVariable("BATCH_WRAPPER_SCRIPT")))</condition>
+              </action>
+              <action name="Windows copy PS1 file" id="2818" beanClass="com.install4j.runtime.beans.actions.files.CopyFileAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="destinationFile">
+                    <object class="java.io.File">
+                      <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:WRAPPER_LINK}.ps1</string>
+                    </object>
+                  </property>
+                  <property name="files" type="array" class="java.io.File" length="1">
+                    <element index="0">
+                      <object class="java.io.File">
+                        <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:POWERSHELL_WRAPPER_SCRIPT}</string>
+                      </object>
+                    </element>
+                  </property>
+                </serializedBean>
+                <condition>Util.isWindows() &amp;&amp; !(((String)context.getCompilerVariable("WRAPPER_LINK")+".ps1").equals((String)context.getCompilerVariable("POWERSHELL_WRAPPER_SCRIPT")))</condition>
+              </action>
             </actions>
             <formComponents>
               <formComponent id="21" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
@@ -844,13 +912,13 @@ return console.askYesNo(message, true);
                   <property name="progressChangeType" type="enum" class="com.install4j.runtime.beans.actions.control.ProgressChangeType" value="SET_INDETERMINATE" />
                 </serializedBean>
               </action>
-              <action id="29" beanClass="com.install4j.runtime.beans.actions.UninstallFilesAction" actionElevationType="elevated" rollbackBarrierExitCode="0" />
+              <action id="29" beanClass="com.install4j.runtime.beans.actions.UninstallFilesAction" rollbackBarrierExitCode="0" />
               <action id="660" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" enabled="false" actionElevationType="none" rollbackBarrierExitCode="0">
                 <serializedBean>
                   <property name="percentValue" type="int" value="95" />
                 </serializedBean>
               </action>
-              <action id="1525" beanClass="com.install4j.runtime.beans.actions.files.DeleteFileAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+              <action id="1525" beanClass="com.install4j.runtime.beans.actions.files.DeleteFileAction" rollbackBarrierExitCode="0">
                 <serializedBean>
                   <property name="files" type="array" class="java.io.File" length="40">
                     <element index="0">
@@ -1409,7 +1477,7 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch.</property>
       </exclude>
       <jreBundle jreBundleSource="preCreated" includedJre="${compiler:WINDOWS_X64_JAVA_VM_TGZ}" manualJreEntry="true" />
     </windows>
-    <macosArchive name="macOS x64 Disk Image" id="878" customizedId="MACOS-X64-DMG" mediaFileName="${compiler:APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-x64-java_${compiler:JAVA_INTEGER_VERSION}" volumeName="${compiler:INSTALLER_NAME}" launcherId="737" setupAppId="2746">
+    <macosArchive name="macOS x64 (intel) Disk Image" id="878" customizedId="MACOS-X64-DMG" mediaFileName="${compiler:APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-x64-java_${compiler:JAVA_INTEGER_VERSION}" volumeName="${compiler:INSTALLER_NAME}" launcherId="737" setupAppId="2746">
       <exclude>
         <entry defaultFileset="true" />
         <entry filesetId="2803" />
@@ -1422,9 +1490,11 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch.</property>
         <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/Jalview-File.icns" file="${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/Jalview-File.icns" />
         <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/jvl_file.icns" file="${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/jvl_file.icns" />
         <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/MacOS/${compiler:WRAPPER_LINK}" target="../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/app/jre/Contents/Home/bin/${compiler:JALVIEW_APPLICATION_NAME}" target="java" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/app/jre/Contents/Home/bin/${compiler:JALVIEW_NAME}" target="java" />
       </topLevelFiles>
     </macosArchive>
-    <macosArchive name="macOS aarch64 Disk Image" id="2796" customizedId="MACOS-AARCH64-DMG" mediaFileName="${compiler:APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-aarch64-java_${compiler:JAVA_INTEGER_VERSION}" volumeName="${compiler:INSTALLER_NAME}" architecture="aarch64" launcherId="737" setupAppId="2746">
+    <macosArchive name="macOS aarch64 (Apple Silicon) Disk Image" id="2796" customizedId="MACOS-AARCH64-DMG" mediaFileName="${compiler:APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-aarch64-java_${compiler:JAVA_INTEGER_VERSION}" volumeName="${compiler:INSTALLER_NAME}" architecture="aarch64" launcherId="737" setupAppId="2746">
       <exclude>
         <entry defaultFileset="true" />
         <entry filesetId="2801" />
@@ -1437,6 +1507,8 @@ ${compiler:JALVIEW_APPLICATION_NAME} will now launch.</property>
         <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/Jalview-File.icns" file="${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/Jalview-File.icns" />
         <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/jvl_file.icns" file="${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/jvl_file.icns" />
         <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/MacOS/${compiler:WRAPPER_LINK}" target="../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/app/jre/Contents/Home/bin/${compiler:JALVIEW_APPLICATION_NAME}" target="java" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/app/jre/Contents/Home/bin/${compiler:JALVIEW_NAME}" target="java" />
       </topLevelFiles>
     </macosArchive>
     <unixInstaller name="Linux x64 Shell Installer" id="1595" customizedId="LINUX-X64-SH" mediaFileName="${compiler:UNIX_APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-linux-x64-java_${compiler:JAVA_INTEGER_VERSION}" installDir="${compiler:UNIX_APPLICATION_FOLDER}" customInstallBaseDir="~/opt/">
diff --git a/utils/jalviewjs/chromium_test/jalview_bin_Jalview-stderr.html b/utils/jalviewjs/chromium_test/jalview_bin_Jalview-stderr.html
new file mode 100644 (file)
index 0000000..bf7a678
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>SwingJS test Jalview</title><meta charset="utf-8" />
+<script src="swingjs/swingjs2.js"></script>
+<script>
+if (!self.SwingJS)alert('swingjs2.js was not found. It needs to be in swingjs folder in the same directory as ' + document.location.href)
+Info = {
+  code: null,
+  main: "jalview.bin.Jalview",
+  core: "NONE",
+       width: 850,
+       height: 550,
+  readyFunction: null,
+       serverURL: 'https://chemapps.stolaf.edu/jmol/jsmol/php/jsmol.php',
+       j2sPath: 'swingjs/j2s',
+       console: window.console,
+       allowjavascript: true
+}
+</script>
+</head>
+<body>
+<script>
+// we define console.err because swingjs2.js calls it instead of console.error
+window.console.err = function() {
+       this.error.apply(this,arguments);
+}
+SwingJS.getApplet('testApplet', Info)
+getClassList = function(){J2S._saveFile('_j2sclasslist.txt', Clazz.ClassFilesLoaded.sort().join('\n'))}
+</script>
+<div style="position:absolute;left:900px;top:30px;width:600px;height:300px;">
+<div id="sysoutdiv" contentEditable="true" style="border:1px solid green;width:100%;height:95%;overflow:auto"></div>
+This is System.out. <a href="javascript:testApplet._clearConsole()">clear it</a> <br>Add ?j2snocore to URL to see full class list; ?j2sdebug to use uncompressed j2s/core files <br><a href="javascript:getClassList()">get _j2sClassList.txt</a>
+</div>
+</body>
+</html>