/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2014, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero Public License version 3 as
* published by the Free Software Foundation.
*
* This program 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 Affero Public License for more details.
*
* You should have received a copy of the GNU Affero Public License
* along with this program. If not, see http://www.gnu.org/licenses.
*
* http://numenta.org/licenses/
* ---------------------------------------------------------------------
*/
package org.numenta.nupic.datagen;
import gnu.trove.list.TIntList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import org.numenta.nupic.util.MersenneTwister;
/**
* Utilities for generating and manipulating patterns, for use in
* experimentation and tests.
*
* @author Chetan Surpur
* @author David Ray
*
* @see ConsecutivePatternMachine
* @see SequenceMachine
*/
public class PatternMachine {
protected int numPatterns = 100;
protected int n;
protected int w;
protected TIntList wList;
protected Random random;
protected Map<Integer, LinkedHashSet<Integer>> patterns;
protected static final int SEED = 42;
protected static final int NUM_PATTERNS = 100;
/**
* @param n Number of available bits in pattern
* @param w Number of on bits in pattern
*
* Constructs a new {@code PatternMachine}
*/
public PatternMachine(int n, int w) {
this(n, w, NUM_PATTERNS, SEED);
}
/**
* @param n Number of available bits in pattern
* @param w Number of on bits in pattern
* @param num Number of available patterns
* @param seed Random seed
*
* Constructs a new {@code PatternMachine}
*/
public PatternMachine(int n, int w, int num, int seed) {
this.n = n;
this.w = w;
this.numPatterns = num;
random = new MersenneTwister(new int[] { seed });
patterns = new LinkedHashMap<Integer, LinkedHashSet<Integer>>();
generate();
}
/**
* @param n Number of available bits in pattern
* @param w Number of on bits in pattern, each pattern
* will have a `w` randomly selected from the list.
* @param num Number of available patterns
*
* Constructs a new {@code PatternMachine}
*/
public PatternMachine(int n, TIntList w, int num) {
this(n, w, num, SEED);
}
/**
* @param n Number of available bits in pattern
* @param w Number of on bits in pattern, each pattern
* will have a `w` randomly selected from the list.
* @param num Number of available patterns
* @param seed Random seed
*
* Constructs a new {@code PatternMachine}
*/
public PatternMachine(int n, TIntList w, int num, int seed) {
this.n = n;
this.wList = w;
random = new MersenneTwister(new int[] { seed });
patterns = new LinkedHashMap<Integer, LinkedHashSet<Integer>>();
this.numPatterns = num;
generate();
}
/**
* Generates a canned set of sequences
*
* @param n
* @param w
* @param num
* @param canned
*/
public PatternMachine(int n, int w, int num, boolean canned) {
this.n = n;
this.w = w;
random = new MersenneTwister(new int[] { SEED });
patterns = new LinkedHashMap<Integer, LinkedHashSet<Integer>>();
this.numPatterns = num;
generateCanned();
}
/**
* Instructs the PatternMachine to construct the internal patterns.
*/
public void generate() {
LinkedHashSet<Integer> pattern;
for(int i = 0;i < numPatterns;i++) {
pattern = sample(new ArrayList<Integer>(xrange(0, n)), w);
patterns.put(i, pattern);
}
}
/**
* Gets a value of "w" for use in generating a pattern.
* @return
*/
public int getW() {
if(wList != null) {
return wList.get(random.nextInt(wList.size()));
}
return w;
}
/**
* Returns the ordered set of indices of on bits.
*
* @param key
* @return
*/
public LinkedHashSet<Integer> get(int key) {
return patterns.get(key);
}
/**
* Add noise to pattern
*
* @param bits Indices of on bits
* @param amount Probability of switching an on bit with a random bit
* @return pattern with noise added
*/
public Set<Integer> addNoise(Set<Integer> bits, double amount) {
LinkedHashSet<Integer> newBits = new LinkedHashSet<>();
for(Integer bit : bits) {
if(random.nextDouble() < amount) {
newBits.add(random.nextInt(n));
}else{
newBits.add(bit);
}
}
return newBits;
}
/**
* Returns a {@link Set} of indexes mapped to patterns
* which contain the specified bit.
*
* @param bit
* @return
*/
public LinkedHashSet<Integer> numbersForBit(int bit) {
LinkedHashSet<Integer> retVal = new LinkedHashSet<Integer>();
for(Integer i : patterns.keySet()) {
if(patterns.get(i).contains(bit)) {
retVal.add(i);
}
}
return retVal;
}
/**
* Return a map from number to matching on bits,
* for all numbers that match a set of bits.
*
* @param bits
* @return
*/
public Map<Integer, Set<Integer>> numberMapForBits(Set<Integer> bits) {
Map<Integer, Set<Integer>> numberMap = new TreeMap<Integer, Set<Integer>>();
for(Integer bit : bits) {
Set<Integer> numbers = numbersForBit(bit);
for(Integer number : numbers) {
Set<Integer> set = null;
if((set = numberMap.get(number)) == null) {
numberMap.put(number, set = new HashSet<Integer>());
}
set.add(bit);
}
}
return numberMap;
}
public String prettyPrintPattern(Set<Integer> bits, int verbosity) {
Map<Integer, Set<Integer>> numberMap = numberMapForBits(bits);
String text = null;
List<String> numberList = new ArrayList<String>();
LinkedHashMap<Integer, LinkedHashSet<Integer>> numberItems = sortedMap(numberMap);
for(Integer number : numberItems.keySet()) {
String numberText = null;
if(verbosity > 2) {
numberText = number + " (bits: " + numberItems.get(number) + ")";
}else if(verbosity > 1) {
numberText = number + " (" + numberItems.get(number).size() + "bits)";
}else{
numberText = "" + number;
}
numberList.add(numberText);
}
text = numberList.toString();
return text;
}
/**
* Returns a sorted map whose set entries are also sorted.
*
* @param map
* @return
*/
public LinkedHashMap<Integer, LinkedHashSet<Integer>> sortedMap(final Map<Integer, Set<Integer>> map) {
LinkedHashMap<Integer, LinkedHashSet<Integer>> retVal = new LinkedHashMap<Integer, LinkedHashSet<Integer>>();
List<Integer> sortByKeys = new ArrayList<Integer>(map.keySet());
Collections.sort(sortByKeys, new Comparator<Integer>() {
@Override public int compare(Integer arg0, Integer arg1) {
int len0 = map.get(arg0).size();
int len1 = map.get(arg1).size();
return len0 == len1 ? 0 : len0 > len1 ? -1 : 1;
}
});
for(Integer key : sortByKeys) {
retVal.put(key, new LinkedHashSet<Integer>(map.get(key)));
}
return retVal;
}
/**
* Returns an ordered {@link Set} of Integers starting at
* the specified number (start), and ending with the specified
* number (upperBounds).
*
* @param start
* @param upperBounds
* @return
*/
public LinkedHashSet<Integer> xrange(int start, int upperBounds) {
LinkedHashSet<Integer> retVal = new LinkedHashSet<Integer>();
for(int i = start;i < upperBounds;i++) {
retVal.add(i);
}
return retVal;
}
/**
* Returns a {@link Set} of numbers whose size equals the
* number num and whose values range from 0 to "population".
*
* @param population
* @param num
* @return
*/
public LinkedHashSet<Integer> sample(List<Integer> population, int num) {
List<Integer> retVal = new ArrayList<Integer>();
int len = population.size();
for(int i = 0;i < num;i++) {
int j = (int)(random.nextDouble() * (len - i));
retVal.add(population.get(j));
population.set(j, population.get(len - i - 1));
}
Collections.sort(retVal);
return new LinkedHashSet<Integer>(retVal);
}
public void generateCanned() {
Integer[][] na = new Integer[][] {
{0, 4, 10, 12, 18, 22, 26, 30, 31, 33, 39, 44, 45, 53, 55, 70, 73, 76, 77, 80, 83, 88, 90},
{2, 4, 6, 8, 11, 13, 15, 16, 23, 29, 38, 42, 46, 48, 51, 55, 56, 59, 65, 67, 76, 77, 78, 82, 89},
{2, 7, 10, 12, 19, 25, 38, 39, 44, 46, 49, 52, 56, 72, 77, 78, 79, 83, 84, 88, 94, 97, 98, 99},
{3, 4, 5, 9, 11, 13, 16, 19, 21, 22, 24, 48, 49, 60, 61, 65, 66, 69, 70, 78, 85, 87, 96},
{0, 5, 7, 17, 19, 24, 25, 38, 40, 43, 44, 45, 46, 48, 54, 55, 66, 74, 77, 86, 90, 95},
{0, 4, 5, 9, 12, 17, 25, 34, 38, 39, 41, 42, 44, 56, 65, 68, 69, 74, 76, 77, 83, 88, 93, 96, 99},
{1, 3, 14, 17, 19, 22, 25, 26, 27, 28, 35, 36, 48, 49, 55, 58, 67, 69, 72, 80, 85, 93, 98},
{15, 18, 22, 27, 29, 32, 33, 35, 36, 39, 40, 42, 44, 53, 58, 69, 79, 80, 83, 86, 91, 95, 97},
{2, 6, 8, 13, 15, 16, 27, 33, 37, 41, 48, 52, 61, 62, 64, 68, 73, 74, 75, 79, 89, 91, 96, 98},
{3, 4, 7, 8, 9, 10, 18, 21, 30, 36, 38, 47, 49, 51, 55, 56, 60, 67, 68, 71, 74, 80, 82, 91, 95},
{4, 5, 7, 11, 14, 16, 40, 45, 46, 47, 53, 58, 60, 67, 69, 71, 73, 75, 77, 79, 85, 89, 95, 96},
{4, 14, 18, 20, 21, 25, 28, 35, 38, 44, 50, 51, 59, 60, 62, 63, 70, 73, 75, 79, 85, 93, 97},
{1, 34, 66, 38, 6, 71, 8, 2, 12, 45, 14, 47, 49, 82, 54, 56, 36, 26, 59, 60, 61},
{1, 10, 12, 18, 26, 38, 40, 49, 53, 55, 61, 65, 66, 68, 71, 77, 80, 81, 89, 90, 92, 96},
{96, 2, 3, 4, 40, 73, 12, 61, 78, 47, 16, 50, 51, 46, 86, 26, 44, 28, 90, 30, 95},
{1, 10, 13, 17, 18, 19, 28, 29, 30, 31, 32, 35, 36, 37, 38, 44, 66, 71, 75, 81, 84, 90},
{3, 9, 17, 19, 23, 27, 29, 30, 32, 35, 36, 40, 52, 56, 58, 60, 63, 67, 79, 83, 85, 88, 90, 95},
{67, 35, 4, 6, 92, 41, 43, 76, 77, 78, 47, 48, 19, 21, 86, 55, 58, 27, 60, 94, 95},
{4, 7, 11, 12, 14, 19, 20, 23, 26, 27, 31, 35, 40, 50, 54, 56, 58, 65, 75, 81, 84, 85, 87, 97, 98},
{5, 7, 12, 14, 16, 19, 22, 23, 27, 31, 32, 41, 43, 53, 57, 65, 68, 73, 75, 78, 82, 91, 92, 96, 99},
{4, 10, 29, 36, 43, 44, 50, 53, 57, 58, 63, 64, 66, 72, 75, 78, 79, 80, 86, 91, 97, 99},
{6, 10, 21, 24, 26, 30, 36, 45, 47, 59, 62, 67, 68, 70, 71, 72, 75, 80, 81, 83, 91, 92, 95},
{1, 5, 15, 18, 24, 32, 37, 39, 40, 42, 45, 58, 64, 68, 69, 72, 77, 83, 87, 90, 91, 98},
{1, 7, 12, 13, 22, 25, 26, 31, 38, 40, 44, 58, 61, 62, 67, 70, 71, 73, 84, 85, 92, 97, 98},
{3, 12, 13, 16, 18, 20, 24, 26, 30, 31, 35, 38, 42, 50, 52, 54, 55, 56, 59, 60, 61, 67, 77, 79, 98},
{1, 2, 3, 4, 8, 9, 13, 22, 25, 32, 36, 37, 46, 49, 52, 53, 56, 61, 64, 84, 90, 91, 93, 96},
{0, 34, 99, 69, 6, 39, 31, 11, 44, 77, 78, 81, 82, 20, 22, 55, 23, 52, 91, 62, 95},
{0, 1, 2, 6, 7, 9, 20, 28, 29, 30, 38, 46, 47, 51, 55, 58, 60, 66, 69, 87, 94, 97},
{6, 10, 25, 29, 33, 34, 40, 41, 43, 46, 57, 58, 65, 71, 75, 77, 78, 79, 84, 91, 92, 93, 99},
{1, 7, 12, 21, 23, 25, 27, 28, 36, 38, 43, 50, 51, 61, 66, 70, 75, 83, 84, 94, 97, 99},
{96, 65, 66, 68, 33, 40, 76, 75, 12, 45, 78, 16, 24, 19, 20, 53, 56, 89, 71, 62, 63},
{5, 6, 7, 11, 17, 22, 23, 25, 27, 28, 30, 35, 38, 42, 52, 66, 67, 68, 75, 78, 82, 87, 88, 93, 99},
{5, 7, 15, 22, 23, 25, 27, 40, 42, 47, 49, 56, 58, 59, 61, 62, 69, 77, 82, 89, 92, 96},
{1, 8, 10, 20, 22, 23, 27, 29, 30, 31, 41, 51, 55, 61, 71, 74, 76, 80, 81, 86, 93, 94},
{1, 17, 21, 24, 28, 31, 33, 34, 37, 39, 45, 48, 53, 54, 58, 59, 66, 74, 76, 80, 86, 88, 93, 97},
{5, 6, 8, 12, 17, 25, 29, 31, 33, 34, 35, 46, 53, 56, 57, 63, 67, 71, 78, 79, 87, 88, 95},
{10, 14, 24, 25, 30, 37, 40, 44, 56, 58, 60, 63, 70, 72, 74, 80, 82, 84, 86, 93, 97, 99},
{1, 4, 8, 9, 12, 13, 15, 23, 24, 29, 35, 45, 49, 51, 55, 59, 64, 65, 67, 72, 78, 82, 86, 87, 91},
{1, 3, 5, 10, 16, 23, 30, 35, 39, 46, 47, 50, 52, 54, 60, 68, 72, 79, 83, 84, 85, 88, 92, 99},
{3, 17, 18, 21, 24, 27, 34, 35, 37, 40, 44, 47, 50, 58, 59, 60, 62, 64, 66, 69, 77, 79, 82, 95, 98},
{0, 64, 2, 99, 4, 70, 38, 39, 18, 45, 78, 50, 52, 85, 87, 57, 90, 63, 84, 93, 95},
{0, 4, 6, 8, 10, 11, 18, 22, 30, 35, 37, 43, 44, 47, 53, 58, 60, 61, 66, 69, 74, 75, 80, 90, 94},
{3, 9, 18, 19, 21, 28, 29, 34, 39, 42, 45, 54, 61, 62, 65, 66, 72, 74, 80, 91, 95, 97, 99},
{0, 1, 10, 11, 22, 30, 36, 44, 47, 53, 56, 57, 58, 59, 65, 66, 75, 76, 84, 85, 90, 95, 98},
{5, 13, 19, 23, 25, 26, 29, 35, 36, 37, 42, 48, 57, 59, 60, 67, 73, 77, 92, 95, 96, 98},
{5, 6, 10, 11, 14, 17, 26, 30, 33, 38, 39, 42, 45, 52, 53, 58, 59, 60, 64, 67, 74, 97, 98, 99},
{0, 2, 5, 6, 8, 11, 22, 23, 25, 30, 34, 37, 43, 49, 52, 53, 57, 61, 63, 68, 79, 90, 98},
{2, 3, 10, 12, 17, 19, 22, 26, 28, 35, 37, 41, 45, 47, 48, 50, 51, 64, 66, 82, 85, 86, 88, 94, 97},
{96, 59, 36, 69, 71, 72, 42, 75, 45, 78, 11, 50, 57, 55, 24, 23, 90, 95, 5, 74, 37},
{32, 1, 66, 36, 20, 6, 39, 64, 44, 82, 14, 45, 81, 18, 83, 52, 55, 89, 59, 30, 31},
{2, 10, 13, 15, 17, 19, 20, 24, 26, 38, 39, 40, 43, 46, 51, 58, 59, 61, 74, 78, 81, 82},
{1, 3, 13, 24, 25, 26, 30, 33, 37, 43, 49, 58, 63, 66, 67, 71, 76, 77, 78, 79, 90, 91, 97},
{0, 20, 22, 23, 24, 25, 26, 27, 28, 31, 32, 37, 38, 41, 46, 47, 52, 56, 73, 81, 82, 83, 94, 97, 98},
{0, 1, 4, 10, 15, 16, 23, 28, 31, 40, 46, 48, 50, 58, 62, 67, 71, 77, 79, 90, 92, 93, 97, 99},
{3, 34, 27, 37, 73, 14, 82, 46, 13, 92, 49, 50, 19, 52, 53, 41, 25, 47, 21, 42, 63},
{64, 51, 35, 68, 70, 6, 71, 96, 75, 76, 15, 80, 17, 19, 53, 23, 4, 58, 93, 30, 5},
{0, 97, 83, 96, 6, 7, 73, 10, 43, 76, 12, 16, 18, 19, 84, 54, 23, 88, 92, 29, 31},
{7, 16, 18, 26, 30, 35, 41, 42, 43, 45, 48, 52, 53, 54, 71, 74, 78, 84, 85, 86, 90, 94, 99},
{0, 2, 7, 11, 14, 19, 20, 21, 28, 33, 35, 37, 43, 53, 64, 68, 69, 72, 73, 79, 80, 83, 86, 98},
{0, 11, 13, 18, 19, 22, 29, 30, 31, 32, 36, 42, 44, 50, 52, 63, 72, 79, 91, 92, 96, 99},
{0, 1, 10, 12, 15, 17, 24, 26, 28, 36, 39, 51, 52, 54, 55, 58, 63, 73, 77, 79, 83, 85, 87, 89, 94},
{2, 3, 6, 8, 13, 24, 25, 29, 33, 44, 45, 53, 55, 60, 61, 64, 65, 76, 79, 80, 84, 90, 91, 94, 97},
{1, 3, 6, 7, 11, 12, 17, 18, 21, 25, 30, 33, 45, 50, 75, 76, 77, 78, 79, 81, 84, 91, 95},
{7, 10, 18, 19, 22, 23, 28, 29, 34, 37, 39, 46, 50, 51, 55, 56, 67, 68, 70, 71, 72, 80, 89, 91, 95},
{96, 97, 2, 99, 68, 37, 7, 73, 74, 75, 12, 66, 81, 51, 84, 23, 89, 90, 60, 29, 63},
{0, 97, 66, 35, 33, 72, 28, 10, 11, 78, 49, 50, 19, 57, 54, 73, 83, 89, 60, 29, 63},
{41, 48, 67, 17, 69, 70, 7, 9, 10, 11, 44, 77, 16, 76, 75, 19, 53, 86, 73, 35, 85},
{3, 4, 7, 15, 21, 26, 45, 47, 48, 50, 52, 60, 62, 64, 72, 77, 86, 90, 91, 94, 95, 98},
{7, 10, 11, 12, 18, 21, 22, 24, 35, 36, 41, 45, 46, 47, 49, 52, 55, 58, 60, 64, 74, 81, 85, 90, 94},
{4, 8, 9, 11, 13, 15, 16, 35, 36, 37, 39, 49, 50, 56, 66, 67, 68, 72, 78, 84, 91, 98, 99},
{5, 7, 10, 14, 17, 21, 24, 29, 31, 34, 39, 46, 53, 59, 61, 67, 69, 71, 77, 81, 85, 87, 88, 93, 97},
{15, 17, 19, 23, 26, 27, 33, 34, 45, 46, 47, 49, 51, 53, 62, 63, 68, 69, 72, 74, 80, 81, 84, 94},
{2, 4, 9, 17, 19, 26, 29, 31, 34, 47, 49, 59, 61, 62, 63, 64, 65, 74, 80, 88, 91, 98},
{1, 3, 7, 11, 16, 18, 19, 22, 29, 31, 33, 34, 37, 43, 50, 53, 60, 61, 62, 72, 74, 77, 80, 91},
{4, 15, 19, 23, 33, 34, 35, 37, 44, 46, 57, 59, 62, 69, 70, 71, 73, 77, 81, 82, 86, 91},
{2, 4, 11, 19, 29, 30, 39, 45, 46, 48, 51, 52, 56, 59, 60, 61, 70, 74, 80, 89, 94, 96, 98, 99},
{3, 6, 19, 31, 40, 41, 44, 46, 47, 53, 55, 67, 68, 70, 73, 75, 76, 83, 88, 90, 97, 99},
{4, 9, 16, 19, 21, 23, 37, 43, 45, 46, 47, 55, 62, 72, 74, 79, 81, 89, 93, 94, 98, 99},
{2, 3, 4, 14, 15, 19, 27, 28, 31, 35, 45, 48, 56, 58, 63, 69, 71, 73, 78, 80, 90, 98},
{8, 11, 15, 20, 23, 31, 37, 46, 55, 57, 58, 60, 68, 70, 73, 74, 80, 82, 83, 86, 94, 99},
{1, 12, 15, 22, 23, 24, 25, 36, 37, 38, 50, 55, 56, 63, 65, 66, 70, 72, 74, 81, 82, 87, 92, 95, 99},
{5, 9, 12, 15, 18, 19, 21, 26, 36, 37, 40, 49, 50, 51, 63, 66, 69, 76, 78, 81, 91, 93},
{0, 1, 11, 13, 17, 22, 26, 33, 36, 38, 41, 44, 61, 62, 63, 77, 80, 81, 85, 86, 90, 94},
{96, 1, 66, 35, 33, 16, 71, 10, 43, 44, 79, 48, 49, 19, 20, 89, 52, 58, 63, 74, 31},
{0, 1, 3, 9, 10, 12, 21, 24, 32, 42, 48, 52, 53, 54, 62, 64, 67, 69, 73, 75, 78, 80, 81, 90, 99},
{5, 8, 12, 14, 18, 19, 22, 23, 27, 39, 40, 44, 48, 49, 50, 54, 60, 61, 68, 71, 79, 87, 91, 97},
{0, 2, 67, 69, 49, 73, 12, 45, 28, 16, 76, 18, 83, 84, 41, 23, 56, 63, 5, 62, 31},
{1, 5, 7, 9, 10, 14, 16, 18, 22, 23, 30, 39, 42, 48, 49, 56, 58, 68, 77, 87, 95, 96},
{0, 11, 12, 13, 14, 17, 18, 21, 23, 24, 26, 33, 37, 62, 71, 77, 80, 81, 84, 89, 90, 93, 96},
{84, 97, 67, 4, 16, 71, 72, 95, 7, 12, 13, 46, 80, 49, 20, 53, 23, 88, 89, 27, 31},
{4, 11, 12, 14, 20, 21, 26, 31, 34, 38, 46, 47, 51, 52, 57, 64, 66, 75, 79, 90, 92, 93, 94, 99},
{0, 2, 3, 7, 10, 14, 16, 19, 21, 27, 28, 29, 35, 38, 40, 43, 49, 52, 55, 60, 62, 65, 82, 93, 96},
{1, 3, 5, 8, 14, 15, 22, 23, 26, 33, 35, 43, 48, 59, 61, 68, 74, 77, 79, 80, 90, 98},
{4, 5, 6, 8, 12, 13, 20, 25, 26, 29, 30, 35, 36, 47, 57, 60, 67, 74, 76, 85, 91, 92, 94, 97},
{4, 5, 12, 15, 17, 20, 21, 23, 29, 32, 37, 43, 54, 60, 70, 71, 74, 77, 83, 88, 93, 96},
{0, 65, 98, 75, 66, 39, 40, 12, 7, 76, 45, 14, 79, 81, 67, 25, 26, 27, 92, 44, 63},
{6, 9, 11, 13, 15, 17, 26, 27, 29, 33, 35, 37, 39, 48, 54, 55, 57, 62, 63, 75, 84, 89, 95, 98},
{0, 5, 10, 15, 25, 30, 31, 32, 33, 37, 43, 47, 48, 49, 58, 59, 60, 66, 67, 79, 83, 93, 97},
{5, 19, 22, 26, 37, 38, 40, 41, 45, 48, 49, 51, 55, 58, 60, 64, 70, 74, 75, 78, 89, 92, 96},
{84, 97, 61, 67, 68, 69, 7, 11, 12, 77, 79, 75, 52, 86, 23, 25, 33, 5, 29, 62, 95},
{65, 98, 59, 1, 39, 7, 73, 74, 43, 76, 29, 80, 51, 84, 54, 20, 25, 27, 92, 10, 62},
{32, 96, 67, 68, 69, 71, 72, 42, 77, 78, 80, 81, 18, 52, 85, 54, 88, 90, 10, 92, 29},
{0, 98, 50, 68, 71, 40, 60, 77, 75, 45, 78, 47, 48, 82, 35, 62, 31, 21, 61, 30, 63},
{1, 8, 11, 16, 18, 21, 26, 31, 35, 40, 45, 54, 57, 59, 61, 64, 69, 75, 79, 81, 88, 90, 93, 97},
{8, 10, 18, 22, 25, 26, 30, 31, 33, 35, 36, 37, 51, 53, 55, 63, 65, 71, 73, 77, 80, 81, 82, 90, 99},
{1, 6, 14, 15, 17, 22, 23, 24, 30, 32, 37, 43, 58, 59, 62, 64, 66, 67, 76, 82, 86, 91, 92, 93, 98},
{2, 5, 8, 16, 22, 30, 36, 39, 45, 48, 50, 55, 56, 66, 69, 70, 79, 85, 87, 93, 98, 99},
{0, 2, 6, 7, 15, 23, 25, 27, 35, 36, 37, 41, 44, 59, 67, 70, 73, 78, 81, 82, 87, 93, 94, 95},
{2, 6, 7, 10, 12, 15, 26, 29, 30, 36, 39, 40, 48, 49, 51, 53, 57, 67, 72, 73, 76, 84, 85, 87, 88},
{1, 6, 16, 18, 19, 20, 22, 32, 38, 44, 46, 50, 54, 55, 57, 63, 64, 71, 73, 78, 85, 95, 96, 99},
{0, 2, 7, 9, 18, 25, 29, 31, 32, 33, 50, 52, 53, 54, 58, 60, 61, 76, 79, 81, 83, 85, 93, 97},
{32, 1, 34, 67, 66, 38, 9, 75, 76, 98, 47, 80, 17, 82, 35, 52, 22, 88, 60, 93, 63},
{6, 13, 19, 24, 26, 27, 33, 35, 37, 41, 42, 43, 52, 54, 57, 62, 72, 85, 86, 88, 91, 94, 96},
{1, 2, 5, 24, 29, 32, 35, 50, 59, 60, 66, 73, 75, 77, 78, 79, 80, 81, 82, 90, 95, 97},
{1, 2, 3, 12, 22, 23, 26, 27, 28, 34, 35, 41, 43, 47, 49, 53, 54, 55, 59, 60, 79, 85, 89, 97},
{0, 1, 4, 7, 10, 12, 17, 18, 29, 37, 38, 45, 47, 48, 57, 58, 62, 67, 80, 85, 86, 88, 90, 94, 99},
{33, 34, 67, 22, 65, 42, 75, 13, 14, 79, 48, 49, 19, 54, 87, 56, 2, 90, 60, 23, 63},
{1, 3, 4, 8, 10, 25, 28, 32, 33, 38, 39, 42, 52, 60, 62, 67, 70, 72, 74, 78, 79, 84, 86, 91},
{1, 5, 6, 8, 13, 15, 21, 22, 29, 39, 41, 42, 44, 51, 57, 69, 73, 74, 75, 81, 82, 84, 90},
{4, 5, 6, 9, 12, 13, 15, 19, 21, 22, 29, 32, 48, 49, 51, 55, 58, 61, 64, 74, 83, 85, 88},
{2, 4, 5, 13, 17, 19, 20, 29, 31, 40, 43, 46, 47, 54, 56, 67, 68, 70, 73, 74, 84, 98},
{3, 7, 14, 16, 23, 26, 27, 30, 34, 35, 39, 53, 55, 56, 61, 62, 67, 68, 71, 73, 78, 85, 86, 92, 94},
{2, 11, 16, 19, 22, 27, 30, 33, 37, 40, 44, 45, 46, 48, 55, 59, 62, 77, 82, 89, 92, 93, 96, 97},
{8, 11, 12, 20, 24, 25, 28, 35, 38, 41, 43, 48, 51, 58, 63, 72, 73, 76, 78, 83, 85, 87, 92, 94},
{5, 6, 13, 16, 17, 28, 34, 39, 40, 42, 43, 50, 52, 53, 58, 69, 70, 72, 81, 88, 89, 92, 94, 99},
{19, 97, 34, 67, 36, 39, 65, 41, 75, 2, 49, 83, 90, 87, 7, 89, 26, 31, 93, 94, 63},
{0, 1, 6, 11, 15, 21, 29, 34, 38, 47, 53, 55, 58, 60, 68, 72, 74, 75, 76, 79, 80, 84, 93, 97, 98},
{6, 7, 8, 14, 19, 20, 29, 33, 34, 42, 44, 49, 52, 59, 65, 66, 70, 71, 73, 75, 76, 77, 83, 94, 97},
{2, 8, 11, 12, 15, 21, 22, 25, 37, 40, 44, 45, 52, 57, 60, 66, 72, 80, 82, 87, 89, 93, 96},
{3, 4, 7, 9, 22, 28, 29, 32, 35, 37, 42, 43, 47, 48, 53, 55, 57, 61, 76, 78, 80, 81, 87, 89},
{12, 16, 18, 23, 26, 27, 34, 35, 38, 54, 56, 57, 62, 63, 64, 67, 68, 70, 78, 80, 84, 96},
{4, 18, 23, 31, 33, 35, 36, 41, 43, 44, 45, 52, 53, 57, 60, 70, 74, 79, 80, 84, 88, 91, 94},
{9, 13, 25, 27, 31, 33, 34, 40, 42, 47, 49, 57, 65, 67, 70, 89, 90, 92, 94, 95, 96, 97},
{1, 4, 9, 19, 23, 30, 32, 35, 39, 40, 46, 51, 55, 66, 69, 70, 80, 85, 86, 87, 90, 95},
{2, 10, 14, 15, 18, 21, 29, 30, 32, 35, 38, 44, 51, 52, 59, 63, 64, 72, 75, 76, 77, 84, 98, 99},
{1, 4, 7, 11, 19, 23, 27, 32, 34, 36, 38, 42, 45, 47, 59, 63, 64, 65, 75, 79, 83, 87, 89, 93, 97},
{32, 51, 66, 39, 8, 9, 74, 98, 78, 15, 16, 10, 19, 52, 46, 73, 89, 26, 91, 29, 62},
{51, 34, 3, 69, 6, 8, 42, 45, 77, 99, 24, 82, 19, 53, 54, 88, 37, 60, 93, 94, 95},
{0, 3, 6, 8, 13, 16, 19, 21, 25, 29, 30, 33, 36, 46, 47, 48, 51, 53, 54, 62, 83, 92, 93, 97, 98},
{2, 8, 11, 13, 14, 15, 23, 26, 28, 37, 42, 50, 51, 53, 54, 55, 63, 65, 70, 71, 76, 81, 93},
{4, 7, 11, 16, 21, 23, 26, 27, 28, 30, 34, 45, 46, 51, 57, 62, 64, 71, 73, 75, 80, 81, 93, 98},
{3, 8, 9, 11, 14, 16, 20, 23, 29, 36, 43, 48, 50, 54, 57, 64, 66, 67, 69, 75, 76, 77, 83, 98},
{0, 2, 5, 7, 8, 11, 13, 20, 40, 47, 49, 53, 54, 57, 65, 68, 70, 74, 77, 88, 93, 94},
{97, 98, 35, 36, 33, 38, 39, 41, 10, 43, 13, 46, 79, 80, 49, 83, 34, 4, 86, 93, 95},
{3, 15, 18, 21, 24, 33, 35, 39, 40, 42, 45, 52, 58, 59, 66, 75, 76, 80, 82, 85, 87, 91, 92, 93},
{5, 11, 12, 16, 26, 31, 32, 34, 35, 37, 39, 40, 44, 48, 54, 58, 62, 74, 78, 81, 86, 91, 96, 99},
{7, 14, 24, 28, 32, 47, 63, 69, 70, 73, 74, 75, 76, 77, 85, 87, 88, 89, 91, 95, 97, 98, 99},
{0, 1, 2, 67, 68, 37, 6, 33, 40, 38, 14, 76, 34, 46, 51, 20, 85, 23, 26, 91, 28},
{4, 12, 17, 20, 23, 39, 43, 46, 48, 50, 58, 65, 75, 79, 82, 84, 91, 92, 93, 95, 96, 98},
{0, 5, 7, 8, 13, 32, 33, 35, 38, 41, 44, 55, 62, 69, 71, 76, 83, 84, 92, 93, 94, 97},
{6, 9, 10, 11, 16, 20, 27, 29, 31, 37, 38, 43, 46, 48, 49, 53, 55, 62, 63, 70, 72, 77, 86, 90, 91},
{0, 33, 34, 91, 96, 65, 32, 41, 75, 76, 98, 14, 15, 53, 86, 45, 88, 57, 47, 28, 7},
{3, 6, 9, 10, 14, 15, 25, 31, 33, 49, 53, 56, 57, 63, 71, 77, 80, 85, 89, 91, 95, 97, 99},
{0, 3, 15, 17, 24, 28, 34, 35, 36, 40, 45, 47, 48, 52, 58, 65, 67, 76, 84, 86, 87, 98, 99},
{1, 2, 3, 6, 13, 16, 28, 31, 34, 39, 41, 44, 51, 59, 62, 65, 71, 75, 79, 82, 84, 85, 88, 90, 95},
{1, 20, 26, 29, 33, 37, 39, 40, 43, 46, 51, 53, 60, 61, 63, 67, 69, 70, 78, 80, 90, 92, 99},
{1, 2, 8, 19, 26, 27, 28, 35, 45, 46, 47, 48, 50, 53, 58, 64, 69, 74, 78, 83, 87, 91, 92, 93, 97},
{1, 8, 9, 13, 15, 18, 22, 38, 40, 41, 48, 56, 59, 61, 64, 73, 75, 78, 79, 89, 92, 93, 94, 99},
{0, 9, 12, 15, 24, 28, 29, 30, 33, 41, 45, 48, 49, 50, 54, 73, 76, 79, 81, 91, 92, 95, 96, 98},
{2, 3, 11, 20, 31, 34, 41, 42, 43, 48, 50, 52, 53, 58, 63, 69, 72, 75, 78, 90, 94, 97, 99},
{2, 4, 6, 10, 13, 14, 18, 22, 33, 34, 38, 43, 46, 48, 49, 58, 60, 61, 70, 72, 91, 97},
{0, 7, 11, 15, 16, 19, 24, 32, 38, 41, 46, 48, 49, 56, 59, 69, 76, 79, 84, 88, 92, 94},
{98, 59, 22, 39, 73, 95, 43, 76, 50, 14, 16, 82, 20, 41, 54, 55, 7, 57, 90, 91, 37},
{0, 2, 3, 4, 11, 16, 17, 24, 34, 35, 43, 44, 62, 66, 67, 68, 72, 76, 78, 92, 97, 99},
{1, 4, 15, 19, 21, 22, 23, 24, 25, 27, 29, 30, 37, 44, 45, 48, 51, 54, 56, 57, 63, 65, 93, 99},
{0, 5, 6, 8, 12, 13, 30, 31, 32, 41, 47, 56, 64, 79, 80, 81, 82, 85, 87, 88, 94, 99},
{0, 5, 8, 9, 10, 16, 17, 23, 27, 29, 30, 36, 44, 48, 50, 53, 63, 65, 70, 71, 87, 95},
{0, 64, 22, 32, 69, 3, 7, 54, 63, 10, 39, 83, 94, 86, 89, 56, 57, 90, 27, 30, 5},
{45, 36, 5, 39, 40, 73, 12, 77, 79, 48, 49, 18, 83, 52, 94, 54, 9, 88, 28, 62, 63},
{98, 75, 37, 71, 28, 11, 14, 61, 16, 49, 82, 46, 54, 56, 88, 7, 26, 15, 60, 93, 85},
{0, 1, 7, 13, 22, 27, 28, 40, 43, 44, 46, 55, 65, 66, 70, 77, 82, 83, 89, 92, 95, 97, 98},
{66, 34, 36, 5, 38, 39, 8, 73, 43, 13, 47, 45, 17, 50, 51, 9, 83, 26, 59, 93, 63},
{6, 9, 10, 25, 29, 32, 33, 36, 40, 43, 46, 50, 51, 52, 59, 63, 71, 72, 75, 81, 82, 88, 93, 98},
{0, 3, 6, 9, 14, 17, 28, 29, 30, 33, 36, 42, 44, 45, 51, 54, 59, 71, 82, 86, 88, 91, 95, 96, 98},
{1, 2, 5, 6, 13, 18, 33, 36, 37, 38, 40, 43, 44, 45, 49, 64, 72, 74, 79, 85, 86, 92, 96},
{3, 4, 6, 7, 10, 11, 15, 24, 26, 38, 40, 41, 44, 51, 52, 53, 54, 56, 62, 69, 70, 77, 78, 85, 94},
{2, 3, 17, 32, 33, 37, 38, 41, 43, 46, 49, 55, 65, 67, 68, 74, 77, 82, 83, 84, 85, 89, 92, 98},
{1, 4, 14, 15, 16, 21, 22, 29, 34, 41, 43, 50, 52, 54, 60, 68, 73, 76, 89, 92, 96, 98},
{68, 98, 67, 4, 37, 39, 74, 75, 78, 93, 15, 16, 95, 52, 53, 23, 25, 31, 42, 62, 21},
{7, 9, 11, 16, 18, 22, 26, 28, 29, 38, 48, 59, 62, 69, 79, 80, 86, 89, 90, 95, 96, 97},
{4, 9, 13, 15, 16, 18, 22, 23, 30, 38, 42, 43, 45, 46, 51, 55, 57, 58, 61, 65, 68, 84, 88, 97},
{6, 7, 8, 16, 17, 24, 27, 30, 31, 32, 33, 38, 39, 48, 63, 71, 72, 82, 88, 90, 96, 98},
{0, 2, 5, 11, 17, 32, 33, 38, 39, 41, 43, 49, 50, 51, 53, 57, 58, 60, 68, 72, 74, 77, 93, 95},
{10, 12, 14, 15, 18, 22, 33, 38, 40, 47, 55, 56, 63, 64, 70, 73, 75, 84, 85, 86, 87, 94},
{4, 8, 10, 23, 24, 28, 39, 47, 48, 51, 55, 60, 62, 64, 70, 72, 74, 76, 78, 86, 93, 99},
{1, 7, 8, 9, 10, 20, 27, 37, 39, 42, 47, 48, 52, 54, 56, 57, 60, 76, 87, 90, 95, 97},
{2, 3, 16, 17, 19, 30, 31, 33, 34, 42, 46, 48, 50, 51, 64, 66, 71, 72, 73, 75, 79, 83, 86, 93, 94},
{0, 5, 10, 12, 19, 24, 30, 31, 36, 39, 42, 43, 48, 51, 57, 61, 79, 81, 83, 85, 94, 95},
{96, 52, 99, 69, 71, 8, 60, 44, 13, 14, 18, 3, 20, 85, 86, 88, 25, 22, 92, 93, 21},
{1, 2, 15, 20, 23, 26, 29, 30, 34, 40, 42, 48, 50, 58, 60, 62, 63, 70, 75, 78, 80, 86, 87, 92},
{0, 33, 34, 36, 7, 8, 9, 60, 21, 78, 15, 48, 17, 19, 46, 88, 25, 91, 28, 72, 85},
{4, 9, 10, 11, 14, 30, 31, 37, 42, 45, 46, 48, 49, 50, 51, 52, 60, 64, 72, 79, 86, 87, 88, 95, 99},
{64, 97, 2, 43, 69, 10, 75, 45, 11, 49, 18, 51, 27, 56, 89, 90, 91, 60, 37, 62, 31},
{0, 2, 3, 18, 23, 25, 31, 35, 36, 40, 44, 46, 47, 49, 50, 52, 60, 61, 68, 69, 76, 77, 80, 81},
{1, 2, 3, 10, 15, 22, 29, 37, 50, 54, 58, 60, 71, 74, 79, 86, 88, 90, 92, 94, 97, 99},
{1, 3, 20, 25, 40, 41, 47, 50, 51, 54, 55, 62, 66, 67, 76, 77, 81, 83, 89, 90, 92, 93},
{2, 47, 69, 71, 54, 73, 95, 76, 45, 78, 79, 17, 18, 77, 20, 46, 22, 89, 27, 94, 31},
{2, 3, 4, 12, 27, 29, 32, 33, 37, 38, 42, 50, 53, 57, 64, 66, 68, 70, 74, 81, 83, 85, 87, 88},
{1, 7, 13, 14, 15, 26, 29, 39, 45, 46, 53, 60, 72, 73, 79, 82, 85, 87, 90, 92, 95, 98},
{5, 7, 8, 11, 13, 16, 17, 19, 20, 21, 37, 41, 42, 49, 50, 54, 65, 68, 73, 74, 77, 85, 86, 88, 89},
{2, 6, 12, 13, 21, 22, 27, 30, 43, 47, 48, 50, 53, 56, 60, 61, 74, 80, 83, 88, 90, 98},
{96, 1, 99, 36, 6, 65, 40, 7, 14, 80, 81, 39, 97, 23, 24, 72, 90, 60, 93, 94, 63},
{2, 7, 8, 9, 12, 21, 23, 26, 29, 31, 35, 36, 38, 40, 44, 62, 63, 66, 70, 80, 85, 98},
{65, 27, 68, 6, 71, 40, 53, 42, 76, 47, 10, 83, 1, 86, 24, 57, 91, 28, 29, 62, 85},
{0, 1, 2, 7, 9, 18, 30, 33, 39, 51, 52, 54, 55, 60, 62, 65, 66, 77, 78, 83, 85, 86, 92, 99},
{19, 96, 3, 68, 40, 30, 11, 77, 29, 16, 26, 83, 53, 23, 88, 90, 47, 21, 58, 62, 31},
{6, 9, 14, 18, 20, 24, 30, 32, 36, 43, 45, 48, 60, 63, 67, 70, 71, 78, 80, 89, 90, 95},
{2, 6, 19, 22, 27, 28, 31, 35, 36, 37, 41, 42, 49, 53, 61, 63, 68, 75, 79, 80, 85, 89, 94, 98},
{5, 6, 9, 12, 15, 16, 24, 25, 29, 30, 36, 39, 41, 44, 49, 54, 62, 69, 72, 74, 75, 76, 82, 97},
{33, 34, 3, 69, 39, 40, 41, 42, 46, 79, 48, 17, 21, 24, 89, 56, 57, 58, 54, 86, 26},
{0, 5, 7, 15, 16, 19, 28, 36, 37, 41, 52, 64, 66, 67, 68, 79, 81, 84, 85, 87, 89, 93},
{6, 24, 25, 26, 27, 35, 36, 43, 45, 48, 55, 62, 72, 74, 75, 78, 80, 84, 85, 86, 88, 93, 95, 98, 99},
{2, 7, 16, 17, 22, 28, 30, 38, 40, 49, 50, 68, 70, 71, 72, 77, 78, 79, 82, 85, 88, 90, 94, 96, 98},
{1, 4, 7, 13, 21, 22, 27, 32, 33, 34, 39, 41, 46, 47, 57, 59, 69, 70, 71, 77, 83, 87, 89, 93},
{1, 5, 15, 19, 21, 22, 28, 29, 30, 38, 41, 43, 55, 61, 64, 67, 71, 72, 76, 78, 83, 84, 85, 87, 95},
{32, 33, 2, 67, 36, 49, 70, 39, 11, 46, 79, 48, 17, 18, 21, 24, 56, 88, 90, 28, 30},
{1, 4, 5, 11, 14, 17, 18, 20, 22, 26, 39, 44, 45, 50, 54, 56, 62, 63, 67, 86, 87, 91, 92, 94},
{32, 1, 99, 38, 7, 9, 42, 43, 76, 46, 15, 48, 81, 18, 3, 84, 87, 58, 29, 94, 95},
{3, 5, 11, 14, 15, 28, 31, 36, 41, 46, 48, 51, 57, 63, 66, 73, 74, 75, 77, 85, 88, 92, 97, 98, 99},
{3, 7, 11, 13, 14, 16, 19, 26, 27, 42, 47, 49, 50, 52, 54, 56, 59, 62, 63, 65, 77, 87, 88, 92},
{0, 4, 5, 10, 14, 21, 25, 26, 32, 40, 41, 46, 48, 49, 51, 53, 55, 56, 60, 61, 70, 84, 93, 95, 96},
{1, 3, 7, 9, 10, 13, 19, 23, 34, 37, 43, 44, 51, 60, 63, 64, 74, 79, 87, 91, 93, 99},
{0, 5, 7, 9, 13, 16, 17, 18, 27, 30, 37, 38, 41, 43, 49, 52, 66, 74, 88, 90, 92, 95, 96, 97},
{2, 3, 16, 18, 24, 26, 28, 29, 32, 35, 57, 60, 66, 74, 76, 80, 81, 83, 84, 87, 88, 89, 93},
{2, 4, 8, 12, 17, 23, 29, 30, 37, 38, 56, 60, 62, 64, 65, 68, 70, 73, 82, 91, 93, 99},
{1, 6, 11, 13, 16, 18, 22, 29, 41, 44, 49, 52, 53, 57, 60, 65, 66, 67, 85, 87, 89, 97},
{2, 7, 10, 12, 14, 25, 28, 30, 32, 33, 38, 44, 46, 49, 54, 55, 56, 69, 75, 87, 88, 95, 97, 99},
{2, 5, 10, 13, 14, 19, 32, 34, 36, 43, 47, 51, 58, 60, 63, 64, 69, 77, 78, 84, 91, 92, 99},
{12, 13, 14, 23, 26, 29, 31, 38, 42, 48, 49, 56, 61, 62, 63, 68, 75, 79, 82, 84, 86, 90},
{0, 7, 14, 19, 20, 29, 31, 32, 46, 48, 56, 57, 62, 65, 70, 77, 79, 81, 82, 84, 89, 92, 94, 98},
{2, 5, 8, 11, 12, 15, 20, 27, 30, 44, 45, 47, 51, 55, 60, 62, 64, 66, 69, 72, 73, 77, 79, 86, 99},
{0, 97, 38, 71, 40, 92, 74, 44, 13, 78, 79, 18, 19, 52, 85, 56, 20, 59, 60, 93, 31},
{0, 4, 16, 21, 23, 38, 40, 41, 42, 45, 50, 53, 56, 59, 69, 75, 79, 85, 86, 87, 91, 93, 99},
{5, 6, 15, 19, 30, 35, 36, 37, 46, 47, 52, 55, 57, 60, 69, 71, 72, 74, 84, 93, 95, 98},
{2, 4, 6, 9, 11, 12, 18, 21, 23, 35, 36, 39, 42, 53, 55, 57, 60, 61, 62, 72, 77, 83, 88, 90, 92},
{97, 66, 68, 93, 40, 41, 74, 43, 12, 13, 14, 79, 8, 19, 9, 21, 86, 23, 57, 59, 10},
{1, 5, 12, 15, 16, 33, 37, 43, 45, 49, 54, 60, 66, 68, 70, 71, 77, 81, 87, 91, 96, 97},
{0, 2, 4, 7, 17, 23, 32, 36, 37, 39, 44, 56, 61, 66, 67, 69, 76, 78, 82, 86, 88, 91, 97, 98},
{1, 6, 21, 23, 29, 31, 32, 35, 39, 44, 50, 52, 61, 63, 66, 75, 78, 80, 82, 83, 85, 88, 92, 96, 98},
{10, 32, 33, 35, 38, 40, 43, 50, 56, 60, 66, 71, 73, 74, 75, 78, 82, 83, 88, 89, 91, 96},
{1, 2, 6, 8, 12, 15, 17, 18, 20, 35, 39, 46, 57, 58, 63, 64, 65, 66, 77, 79, 81, 93, 97},
{0, 4, 6, 10, 14, 15, 16, 25, 27, 32, 36, 37, 44, 50, 53, 59, 60, 64, 66, 74, 77, 82, 90, 96},
{19, 42, 98, 35, 68, 6, 9, 74, 11, 77, 93, 15, 83, 30, 22, 87, 25, 28, 61, 4, 63},
{1, 2, 3, 6, 7, 12, 24, 25, 26, 27, 28, 32, 34, 35, 37, 44, 55, 65, 68, 74, 76, 94, 96, 97, 99},
{0, 4, 15, 23, 29, 31, 32, 38, 44, 49, 50, 55, 60, 66, 67, 68, 73, 78, 86, 87, 88, 94, 99},
{5, 35, 17, 37, 71, 72, 10, 23, 76, 13, 8, 19, 89, 57, 2, 25, 59, 92, 93, 62, 31},
{1, 5, 10, 13, 26, 28, 29, 32, 33, 35, 41, 43, 44, 49, 50, 59, 62, 66, 69, 70, 71, 75, 81, 98, 99},
{3, 4, 7, 14, 23, 24, 29, 30, 44, 48, 52, 55, 67, 68, 74, 75, 77, 88, 89, 91, 95, 97, 98, 99},
{10, 11, 12, 21, 22, 27, 29, 30, 31, 33, 43, 49, 56, 58, 66, 68, 69, 77, 80, 83, 85, 89, 91, 94},
{8, 13, 14, 15, 16, 19, 23, 27, 38, 40, 42, 49, 52, 53, 54, 57, 63, 67, 71, 72, 73, 75, 85, 86},
{2, 4, 9, 10, 25, 26, 27, 30, 33, 35, 36, 50, 54, 57, 63, 65, 66, 73, 80, 86, 88, 92, 93, 98},
{1, 8, 14, 17, 25, 28, 30, 32, 35, 45, 46, 54, 57, 59, 67, 68, 71, 74, 83, 85, 92, 94, 95},
{1, 3, 7, 9, 21, 26, 29, 36, 37, 39, 52, 56, 59, 60, 67, 75, 76, 77, 81, 83, 84, 92, 98, 99},
{0, 2, 5, 20, 29, 31, 38, 41, 44, 62, 63, 64, 65, 74, 76, 77, 78, 81, 85, 87, 91, 98, 99},
{5, 13, 15, 17, 19, 27, 31, 35, 43, 44, 45, 52, 67, 69, 75, 79, 80, 81, 82, 86, 93, 95, 96},
{0, 6, 11, 20, 22, 24, 25, 27, 32, 34, 35, 49, 55, 60, 66, 72, 73, 76, 84, 91, 92, 95},
{13, 26, 27, 31, 34, 35, 39, 44, 47, 49, 51, 62, 67, 68, 72, 79, 86, 87, 90, 92, 93, 94, 99},
{3, 7, 8, 13, 14, 16, 17, 22, 29, 40, 42, 44, 45, 47, 49, 52, 56, 57, 62, 73, 75, 80, 95},
{4, 5, 7, 10, 16, 17, 27, 28, 30, 38, 43, 46, 49, 55, 60, 62, 65, 69, 74, 82, 90, 97, 98, 99},
{0, 8, 11, 13, 14, 23, 25, 29, 30, 32, 34, 36, 51, 52, 53, 64, 65, 74, 81, 82, 87, 90, 93, 95},
{9, 14, 24, 27, 28, 31, 32, 33, 34, 44, 50, 58, 62, 64, 66, 68, 73, 74, 76, 78, 79, 86, 90},
{1, 2, 6, 7, 8, 14, 17, 37, 41, 43, 49, 51, 54, 55, 59, 63, 70, 73, 74, 75, 89, 90, 91, 93, 94},
{3, 13, 15, 17, 21, 43, 44, 45, 46, 51, 57, 58, 60, 67, 70, 72, 73, 81, 83, 88, 89, 90},
{16, 98, 4, 65, 33, 80, 87, 12, 77, 46, 48, 49, 50, 30, 55, 25, 95, 28, 93, 62, 85},
{15, 17, 19, 21, 23, 28, 30, 33, 39, 60, 62, 64, 65, 73, 74, 75, 87, 90, 92, 94, 96, 97, 98, 99},
{0, 1, 5, 6, 10, 15, 16, 19, 30, 31, 32, 41, 50, 51, 52, 57, 60, 69, 70, 75, 82, 94, 97, 99},
{1, 3, 4, 6, 7, 11, 14, 17, 21, 24, 25, 26, 34, 35, 38, 44, 45, 52, 67, 75, 77, 79, 84, 87, 90},
{4, 6, 7, 14, 15, 18, 21, 27, 29, 30, 31, 38, 47, 49, 51, 53, 56, 64, 72, 77, 81, 87},
{2, 3, 4, 11, 13, 14, 16, 27, 28, 32, 35, 39, 45, 46, 53, 56, 60, 62, 69, 71, 72, 82, 91, 97, 99},
{6, 8, 10, 15, 20, 23, 25, 26, 32, 34, 43, 49, 51, 55, 60, 62, 82, 86, 90, 93, 97, 98},
{32, 2, 99, 69, 39, 72, 12, 74, 11, 78, 46, 47, 48, 49, 14, 30, 23, 89, 42, 62, 95},
{0, 34, 35, 38, 6, 7, 60, 74, 98, 77, 50, 20, 57, 23, 88, 84, 26, 5, 61, 94, 95},
{6, 8, 11, 17, 21, 25, 26, 28, 33, 36, 40, 41, 52, 57, 60, 61, 65, 68, 75, 85, 86, 91, 94, 95},
{65, 2, 35, 1, 22, 7, 72, 42, 77, 29, 16, 21, 86, 25, 89, 90, 27, 92, 93, 4, 63},
{4, 5, 9, 13, 25, 31, 34, 35, 40, 42, 45, 49, 50, 62, 64, 65, 70, 76, 83, 86, 91, 92, 96, 97},
{4, 8, 14, 15, 30, 32, 36, 38, 43, 47, 48, 49, 50, 59, 60, 61, 71, 73, 74, 76, 81, 82, 83, 92, 93},
{0, 1, 5, 13, 16, 19, 25, 31, 37, 43, 47, 51, 52, 53, 54, 55, 64, 67, 69, 70, 73, 81, 85, 90},
{0, 65, 35, 36, 71, 40, 7, 76, 46, 47, 48, 27, 82, 99, 56, 53, 23, 24, 68, 59, 30},
{5, 13, 18, 28, 33, 34, 45, 49, 56, 58, 59, 61, 64, 66, 67, 73, 74, 75, 79, 80, 87, 89, 90, 93},
{32, 97, 66, 68, 6, 1, 9, 74, 46, 47, 80, 50, 84, 21, 22, 56, 4, 26, 91, 65, 63},
{0, 5, 10, 14, 16, 19, 20, 23, 28, 32, 33, 36, 41, 44, 45, 50, 56, 59, 60, 64, 66, 75, 86, 90, 99},
{1, 3, 7, 8, 14, 15, 23, 27, 30, 34, 41, 54, 56, 57, 65, 72, 75, 78, 84, 85, 87, 88, 91, 95},
{3, 5, 12, 13, 20, 24, 25, 30, 38, 39, 42, 46, 50, 51, 62, 63, 71, 72, 75, 77, 82, 88, 90, 93},
{6, 14, 15, 17, 18, 23, 29, 39, 43, 52, 56, 57, 61, 73, 78, 83, 85, 90, 92, 94, 95, 96},
{7, 10, 13, 18, 19, 21, 26, 42, 44, 45, 48, 55, 64, 65, 69, 70, 76, 77, 80, 88, 94, 99},
{97, 2, 99, 68, 70, 72, 74, 14, 80, 49, 50, 52, 21, 20, 89, 90, 27, 92, 58, 94, 63},
{9, 11, 12, 15, 25, 28, 31, 38, 39, 46, 51, 52, 57, 60, 61, 73, 83, 85, 86, 87, 89, 94, 95},
{4, 6, 18, 19, 20, 22, 23, 25, 35, 42, 49, 51, 57, 66, 67, 71, 75, 77, 84, 87, 90, 93, 95, 97, 98},
{64, 34, 11, 68, 22, 39, 72, 74, 7, 12, 2, 8, 17, 84, 54, 87, 20, 49, 27, 92, 13},
{3, 5, 8, 11, 12, 13, 14, 17, 18, 19, 27, 28, 29, 34, 42, 43, 73, 75, 77, 79, 86, 87, 90, 92, 93},
{9, 10, 11, 13, 19, 20, 21, 38, 49, 50, 56, 59, 60, 66, 67, 76, 77, 79, 88, 89, 90, 93, 97, 99},
{5, 9, 10, 15, 16, 22, 28, 31, 32, 37, 44, 51, 54, 57, 64, 70, 71, 72, 74, 78, 79, 85, 86, 94},
{1, 3, 8, 31, 34, 48, 52, 57, 58, 59, 60, 61, 70, 73, 75, 76, 77, 79, 82, 83, 84, 89, 95},
{1, 7, 9, 13, 22, 24, 28, 31, 32, 37, 38, 40, 41, 49, 50, 51, 61, 68, 69, 72, 75, 87, 93},
{98, 3, 37, 6, 49, 40, 9, 74, 66, 61, 81, 51, 84, 86, 25, 90, 79, 5, 58, 30, 63},
{0, 1, 4, 7, 12, 14, 18, 23, 25, 26, 31, 32, 35, 45, 47, 50, 61, 72, 74, 80, 81, 91, 97},
{5, 9, 11, 14, 17, 19, 20, 24, 32, 35, 41, 42, 44, 50, 51, 57, 66, 67, 69, 71, 78, 83, 85, 92},
{0, 2, 6, 8, 14, 15, 18, 24, 25, 31, 33, 50, 57, 58, 68, 74, 75, 80, 86, 87, 90, 91, 96, 97},
{0, 1, 4, 12, 13, 15, 16, 19, 20, 27, 30, 39, 43, 48, 50, 58, 61, 64, 65, 69, 87, 95, 96, 97, 98},
{0, 3, 8, 12, 13, 15, 16, 17, 24, 32, 37, 39, 49, 54, 56, 57, 59, 69, 72, 76, 77, 83, 89, 94, 98}
};
int[] i = { 0 };
Arrays.asList(na).stream().map(ia -> { Arrays.sort(ia); return ia; }).forEach((Integer[] a) -> {
patterns.put(i[0]++, new LinkedHashSet<Integer>(Arrays.asList(a)));
});
}
}