Index: src/test/org/apache/lucene/util/automaton/TestLevenshteinAutomata.java
===================================================================
--- src/test/org/apache/lucene/util/automaton/TestLevenshteinAutomata.java	(revision 0)
+++ src/test/org/apache/lucene/util/automaton/TestLevenshteinAutomata.java	(revision 0)
@@ -0,0 +1,179 @@
+package org.apache.lucene.util.automaton;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.automaton.Automaton;
+import org.apache.lucene.util.automaton.BasicAutomata;
+import org.apache.lucene.util.automaton.BasicOperations;
+import org.apache.lucene.util.automaton.MinimizationOperations;
+
+public class TestLevenshteinAutomata extends LuceneTestCase {
+  private Random random;
+ 
+  /**
+   * Some simple tests for Distance 1.
+   * We exercise all possible 3-profiles.
+   */
+  public void testLev1() throws Exception {
+    assertLev1("otter");
+    assertLev1("atlas");
+    assertLev1("aaabbb");
+    assertLev1("aaabb");
+    assertLev1("aaab");
+    assertLev1("aabb");
+    assertLev1("abab");
+    assertLev1("b");
+    assertLev1("");
+  }
+  
+  /**
+   * Some random tests for Distance 1.
+   * Generate random strings (from doubles) and ensure the automaton is correct.
+   */
+  public void testLev1Random() throws Exception {
+    random = newRandom(System.nanoTime());
+    for (int i = 0; i < 25; i++) {
+      assertLev1("" + random.nextDouble());
+    }
+  }
+  
+  /**
+   * for now, simply test the Lev 1 is a subset of Lev 2
+   */
+  public void testLev2() throws Exception {
+    assertSubsetOf("otter", 1, 2);
+    assertSubsetOf("atlas", 1, 2);
+    assertSubsetOf("aaabbb", 1, 2);
+    assertSubsetOf("aaabb", 1, 2);
+    assertSubsetOf("aaab", 1, 2);
+    assertSubsetOf("aabb", 1, 2);
+    assertSubsetOf("abab", 1, 2);
+    assertSubsetOf("b", 1, 2);
+    assertSubsetOf("", 1, 2);
+  }
+  
+  /**
+   * Test that the language accepted for Lev<n1>(s) is a subset of
+   * the language accepted for Lev<n2>(s), where n2 > n1
+   */
+  private void assertSubsetOf(String s, int n1, int n2) {
+    Automaton a1 = LevAutomatonFast(s, n1);
+    Automaton a2 = LevAutomatonFast(s, n2);
+    assertTrue(a1.subsetOf(a2));
+    assertNotSame(a1, a2); // shows that a2.subSetOf(a1) is false, too
+  }
+  
+  /**
+   * Test that the DFA generated for degree 1 matches one generated with the naive algorithm.
+   */
+  private void assertLev1(String s) {
+    Automaton a1 = Lev1AutomatonSlow(s);
+    Automaton a2 = LevAutomatonFast(s, 1);
+    // Automaton .equals() means they accept the same language.
+    assertEquals(a1, a2);
+  }
+  
+  /**
+   * Return an automata that accepts all strings within an edit distance of n from s.
+   */
+  private Automaton LevAutomatonFast(String s, int n) {
+    LevenshteinAutomata a = new LevenshteinAutomata(s);
+    return a.toAutomaton(n);
+  }
+  
+  /**
+   * Return an automaton that accepts all 1-character insertions, deletions, and
+   * substitutions of s.
+   */
+  private Automaton Lev1AutomatonSlow(String s) {
+    Automaton a = BasicAutomata.makeString(s);
+    a = BasicOperations.union(a, insertionsOf(s));
+    MinimizationOperations.minimize(a);
+    a = BasicOperations.union(a, deletionsOf(s));
+    MinimizationOperations.minimize(a);
+    a = BasicOperations.union(a, substitutionsOf(s));
+    MinimizationOperations.minimize(a);
+    
+    return a;
+  }
+  
+  /**
+   * Return an automaton that accepts all 1-character insertions of s (inserting
+   * one character)
+   */
+  private Automaton insertionsOf(String s) {
+    List<Automaton> list = new ArrayList<Automaton>();
+    
+    for (int i = 0; i <= s.length(); i++) {
+      Automaton a = BasicAutomata.makeString(s.substring(0, i));
+      a = BasicOperations.concatenate(a, BasicAutomata.makeAnyChar());
+      a = BasicOperations.concatenate(a, BasicAutomata.makeString(s
+          .substring(i)));
+      list.add(a);
+    }
+    
+    Automaton a = BasicOperations.union(list);
+    MinimizationOperations.minimize(a);
+    return a;
+  }
+  
+  /**
+   * Return an automaton that accepts all 1-character deletions of s (deleting
+   * one character).
+   */
+  private Automaton deletionsOf(String s) {
+    List<Automaton> list = new ArrayList<Automaton>();
+    
+    for (int i = 0; i < s.length(); i++) {
+      Automaton a = BasicAutomata.makeString(s.substring(0, i));
+      a = BasicOperations.concatenate(a, BasicAutomata.makeString(s
+          .substring(i + 1)));
+      a.expandSingleton();
+      list.add(a);
+    }
+    
+    Automaton a = BasicOperations.union(list);
+    MinimizationOperations.minimize(a);
+    return a;
+  }
+  
+  /**
+   * Return an automaton that accepts all 1-character substitutions of s
+   * (replacing one character)
+   */
+  private Automaton substitutionsOf(String s) {
+    List<Automaton> list = new ArrayList<Automaton>();
+    
+    for (int i = 0; i < s.length(); i++) {
+      Automaton a = BasicAutomata.makeString(s.substring(0, i));
+      a = BasicOperations.concatenate(a, BasicAutomata.makeAnyChar());
+      a = BasicOperations.concatenate(a, BasicAutomata.makeString(s
+          .substring(i + 1)));
+      list.add(a);
+    }
+    
+    Automaton a = BasicOperations.union(list);
+    MinimizationOperations.minimize(a);
+    return a;
+  }
+}

Property changes on: src\test\org\apache\lucene\util\automaton\TestLevenshteinAutomata.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/java/org/apache/lucene/search/FuzzyTermsEnum.java
===================================================================
--- src/java/org/apache/lucene/search/FuzzyTermsEnum.java	(revision 912384)
+++ src/java/org/apache/lucene/search/FuzzyTermsEnum.java	(working copy)
@@ -17,22 +17,262 @@
  * limitations under the License.
  */
 
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.DocsEnum;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.UnicodeUtil;
+import org.apache.lucene.util.BytesRef.Comparator;
+import org.apache.lucene.util.automaton.Automaton;
+import org.apache.lucene.util.automaton.BasicAutomata;
+import org.apache.lucene.util.automaton.BasicOperations;
+import org.apache.lucene.util.automaton.LevenshteinAutomata;
+import org.apache.lucene.util.automaton.RunAutomaton;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
-/** Subclass of FilteredTermEnum for enumerating all terms that are similar
+/** Subclass of TermsEnum for enumerating all terms that are similar
  * to the specified filter term.
  *
  * <p>Term enumerations are always ordered by
  * {@link #getTermComparator}.  Each term in the enumeration is
  * greater than all that precede it.</p>
  */
-public final class FuzzyTermsEnum extends FilteredTermsEnum {
+public final class FuzzyTermsEnum extends TermsEnum {
+  private TermsEnum actualEnum;
+  private MultiTermQuery.BoostAttribute actualBoostAtt;
+  
+  private final MultiTermQuery.BoostAttribute boostAtt =
+    attributes().addAttribute(MultiTermQuery.BoostAttribute.class);
+  // nocommit bad variable naming, its the max nonLowerBound... 
+  private float lowerBound = boostAtt.getMaxNonCompetitiveBoost();
+  
+  private final float minSimilarity;
+  private final float scale_factor;
+  
+  private final int termLength;
+  
+  private int maxEdits;
+  private List<Automaton> automata;
+  private List<RunAutomaton> runAutomata;
+  
+  private final IndexReader reader;
+  private final Term term;
+  private final int realPrefixLength;
+  
+  public FuzzyTermsEnum(IndexReader reader, Term term, 
+      final float minSimilarity, final int prefixLength) throws IOException {
+    this.reader = reader;
+    this.term = term;
+    //The prefix could be longer than the word.
+    //It's kind of silly though.  It means we must match the entire word.
+    this.termLength = term.text().length();
+    this.realPrefixLength = prefixLength > termLength ? termLength : prefixLength;
+    this.minSimilarity = minSimilarity;
+    this.scale_factor = 1.0f / (1.0f - minSimilarity);
+    
+    // calculate the maximum k edits for this similarity, and build automata for 0..n, where n<=k
+    maxEdits = initialMaxDistance(minSimilarity, termLength);
+    // constant prefix
+    Automaton prefix = BasicAutomata.makeString(term.text().substring(0, realPrefixLength));
+    String text = term.text().substring(realPrefixLength);
+    LevenshteinAutomata la = new LevenshteinAutomata(text);
+    automata = new ArrayList<Automaton>(maxEdits);
+    runAutomata = new ArrayList<RunAutomaton>(maxEdits);
+    for (int i = 0; i <= maxEdits; i++) {
+      Automaton a = la.toAutomaton(i);
+      if (a == null)
+        break;
+      a = BasicOperations.concatenate(prefix, a);
+      automata.add(a);
+      runAutomata.add(new RunAutomaton(a));
+    }
+    TermsEnum subEnum = getActualEnum(maxEdits, null);
+    setEnum(subEnum != null ? subEnum : 
+      new LinearFuzzyTermsEnum(reader, term, minSimilarity, prefixLength));
+  }
+  
+  private TermsEnum getActualEnum(int editDistance, BytesRef lastTerm) throws IOException {
+    if (editDistance < automata.size()) {
+      return new AutomatonFuzzyTermsEnum(automata.get(editDistance), term, reader, 
+          minSimilarity, 
+          runAutomata.subList(0, editDistance + 1).toArray(new RunAutomaton[0]), lastTerm);
+    } else {
+      return null;
+    }
+  }
+ 
+  void setEnum(TermsEnum actualEnum) {
+    this.actualEnum = actualEnum;
+    this.actualBoostAtt = actualEnum.attributes().addAttribute(MultiTermQuery.BoostAttribute.class);
+  }
+  
+  /** fired when the max non-competitive boost has changed.
+   *  this is the hook to swap in a smarter actualEnum
+   */
+  void minBoostChanged(float boostValue, BytesRef lastTerm) throws IOException {
+    int oldMaxEdits = maxEdits;
+    
+    // as long as the max non-competitive boost is >= the max boost for some edit distance,
+    // keep dropping the max edit distance.
+    while (maxEdits > 0 && boostValue >= calculateMaxBoost(maxEdits))
+      maxEdits--;
+    
+    if (oldMaxEdits != maxEdits) { // the maximum n has changed
+      TermsEnum newEnum = getActualEnum(maxEdits, lastTerm);
+      if (newEnum != null) {
+        setEnum(newEnum);
+      }
+    }
+    // TODO, besides changing linear -> automaton, and swapping in a smaller automaton,
+    // we can also use this information to optimize the linear case itself:
+    // re-init maxDistances so the fast-fail happens for more terms due to the now
+    // stricter constraints.
+  }
+   
+  // for some raw minimum similarity and input term length, what is the maximum # of edits?
+  static int initialMaxDistance(float minimumSimilarity, int termLen) {
+    return (int) ((1-minimumSimilarity) * termLen);
+  }
+  
+  // for some number of edits, what is the maximum possible scaled boost?
+  float calculateMaxBoost(int nEdits) {
+    final float similarity = 1.0f - ((float) nEdits / (float) (termLength));
+    return (similarity - minSimilarity) * scale_factor;
+  }
 
+  @Override
+  public BytesRef next() throws IOException {
+    BytesRef term = actualEnum.next();
+    boostAtt.setBoost(actualBoostAtt.getBoost());
+    
+    final float lowerBound = boostAtt.getMaxNonCompetitiveBoost();
+    if (lowerBound != this.lowerBound) {
+      this.lowerBound = lowerBound;
+      // clone the term before potentially doing something with it
+      minBoostChanged(lowerBound, term == null ? null : (BytesRef) term.clone());
+    }
+    
+    return term;
+  }
+  
+  // proxy all other enum calls to the actual enum
+  @Override
+  public int docFreq() {
+    return actualEnum.docFreq();
+  }
+  
+  @Override
+  public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException {
+    return actualEnum.docs(skipDocs, reuse);
+  }
+  
+  @Override
+  public DocsAndPositionsEnum docsAndPositions(Bits skipDocs,
+      DocsAndPositionsEnum reuse) throws IOException {
+    return actualEnum.docsAndPositions(skipDocs, reuse);
+  }
+  
+  @Override
+  public Comparator getComparator() throws IOException {
+    return actualEnum.getComparator();
+  }
+  
+  @Override
+  public long ord() throws IOException {
+    return actualEnum.ord();
+  }
+  
+  @Override
+  public SeekStatus seek(BytesRef text) throws IOException {
+    return actualEnum.seek(text);
+  }
+  
+  @Override
+  public SeekStatus seek(long ord) throws IOException {
+    return actualEnum.seek(ord);
+  }
+  
+  @Override
+  public BytesRef term() throws IOException {
+    return actualEnum.term();
+  }
+}
+
+/**
+ * Implement fuzzy enumeration with automaton.
+ * <p>
+ * This is the fastest method as opposed to LinearFuzzyTermsEnum:
+ *  as enumeration is logarithmic to the number of terms (instead of linear)
+ * and comparison is linear to length of the term (rather than quadratic)
+ */
+final class AutomatonFuzzyTermsEnum extends AutomatonTermsEnum {
+  private final RunAutomaton matchers[];
+  // used for unicode conversion from BytesRef byte[] to char[]
+  private final UnicodeUtil.UTF16Result utf16 = new UnicodeUtil.UTF16Result();
+  
+  private final float minimumSimilarity;
+  private final float scale_factor;
+  
+  private final int fullSearchTermLength;
+  private final BytesRef termRef;
+  
+  private final BytesRef lastTerm;
+  private final MultiTermQuery.BoostAttribute boostAtt =
+    attributes().addAttribute(MultiTermQuery.BoostAttribute.class);
+  
+  public AutomatonFuzzyTermsEnum(Automaton automaton, Term queryTerm,
+      IndexReader reader, float minSimilarity, RunAutomaton matchers[], BytesRef lastTerm) throws IOException {
+    super(automaton, queryTerm, reader, false);
+    this.minimumSimilarity = minSimilarity;
+    this.scale_factor = 1.0f / (1.0f - minimumSimilarity);
+    this.matchers = matchers;
+    this.lastTerm = lastTerm;
+    termRef = new BytesRef(queryTerm.text());
+    fullSearchTermLength = queryTerm.text().length();
+  }
+  
+  @Override
+  protected AcceptStatus accept(BytesRef term) {
+    if (term.equals(termRef)) { // ed = 0
+      boostAtt.setBoost(1.0F);
+      return AcceptStatus.YES_AND_SEEK;
+    }
+    
+    UnicodeUtil.UTF8toUTF16(term.bytes, term.offset, term.length, utf16);
+    
+    for (int i = 1; i < matchers.length; i++)
+      if (matchers[i].run(utf16.result, 0, utf16.length)) {
+        final float similarity = 1.0f - ((float) i / (float) 
+            (Math.min(utf16.length, fullSearchTermLength)));
+        if (similarity > minimumSimilarity) {
+          boostAtt.setBoost((float) ((similarity - minimumSimilarity) * scale_factor));
+          return AcceptStatus.YES_AND_SEEK;
+        } else {
+          // TODO: optimize and intersect automata with length restrictions up
+          // front so this can't happen.
+          return AcceptStatus.NO_AND_SEEK;
+        }
+      }
+
+    return AcceptStatus.NO_AND_SEEK;
+  }
+
+  @Override
+  protected BytesRef nextSeekTerm(BytesRef term) throws IOException {
+    if (term == null)
+      term = lastTerm;
+    return super.nextSeekTerm(term);
+  }
+}
+
+final class LinearFuzzyTermsEnum extends FilteredTermsEnum {
+
   /* This should be somewhere around the average long word.
    * If it is longer, we waste time and space. If it is shorter, we waste a
    * little bit of time growing the array as we encounter longer words.
@@ -68,7 +308,7 @@
    * @param prefixLength Length of required common prefix. Default value is 0.
    * @throws IOException
    */
-  public FuzzyTermsEnum(IndexReader reader, Term term, final float minSimilarity, final int prefixLength) throws IOException {
+  public LinearFuzzyTermsEnum(IndexReader reader, Term term, final float minSimilarity, final int prefixLength) throws IOException {
     super(reader, term.field());
     
     if (minSimilarity >= 1.0f)
Index: src/java/org/apache/lucene/util/automaton/LevenshteinAutomata.java
===================================================================
--- src/java/org/apache/lucene/util/automaton/LevenshteinAutomata.java	(revision 0)
+++ src/java/org/apache/lucene/util/automaton/LevenshteinAutomata.java	(revision 0)
@@ -0,0 +1,231 @@
+package org.apache.lucene.util.automaton;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.BitSet;
+import java.util.Iterator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.lucene.util.automaton.Automaton;
+import org.apache.lucene.util.automaton.BasicAutomata;
+import org.apache.lucene.util.automaton.State;
+import org.apache.lucene.util.automaton.Transition;
+
+/**
+ * Class to construct DFAs that match a word within some edit distance.
+ * <p>
+ * Implements the algorithm described in:
+ * Schulz and Mihov: Fast String Correction with Levenshtein Automata
+ * <p>
+ * @lucene.experimental
+ */
+public class LevenshteinAutomata {
+  /* input word */
+  final String input;
+  final char word[];
+  /* the automata alphabet. */
+  final char alphabet[];
+  /* X(x, V) for all x in alphabet */
+  final BitSet charvectors[];
+
+  /* the unicode ranges outside of alphabet */
+  final char rangeLower[];
+  final char rangeUpper[];
+  int numRanges = 0;
+  
+  ParametricDescription descriptions[]; 
+  
+  /**
+   * Create a new LevenshteinAutomata for some input String.
+   */
+  public LevenshteinAutomata(String input) {
+    this.input = input;
+    this.word = input.toCharArray();
+    
+    // calculate the alphabet
+    SortedSet<Character> set = new TreeSet<Character>();
+    for (int i = 0; i < word.length; i++)
+      set.add(word[i]);
+    alphabet = new char[set.size()];
+    Iterator<Character> iterator = set.iterator();
+    for (int i = 0; i < alphabet.length; i++)
+      alphabet[i] = iterator.next();
+    
+    // calculate all characteristic vectors
+    charvectors = new BitSet[Character.MAX_VALUE];
+    for (char c : set)
+      charvectors[c] = calcFullVector(c, word);
+    
+    rangeLower = new char[alphabet.length + 2];
+    rangeUpper = new char[alphabet.length + 2];
+    // calculate the unicode range intervals that exclude the alphabet
+    // these are the ranges for all unicode characters not in the alphabet
+    int lower = 0;
+    for (int i = 0; i < alphabet.length; i++) {
+      char higher = alphabet[i];
+      if (higher > lower) {
+        rangeLower[numRanges] = (char) lower;
+        rangeUpper[numRanges] = (char) (higher - 1);
+        numRanges++;
+      }
+      lower = higher + 1;
+    }
+    /* add the final endpoint */
+    if (lower <= 0xFFFF) {
+      rangeLower[numRanges] = (char) lower;
+      rangeUpper[numRanges] = '\uFFFF';
+      numRanges++;
+    }
+    
+    descriptions = new ParametricDescription[] {
+        null, /* for n=0, we do not need to go through the trouble */
+        new Lev1ParametricDescription(input.length()),
+        new Lev2ParametricDescription(input.length())
+    };
+  }
+  
+  /**
+   * Compute a DFA that accepts all strings within an edit distance of <code>n</code>.
+   * <p>
+   * All automata have the following properties:
+   * <ul>
+   * <li>They are deterministic (DFA).
+   * <li>There are no transitions to dead states.
+   * <li>They are not minimal (some transitions could be combined).
+   * </ul>
+   * </p>
+   */
+  public Automaton toAutomaton(int n) {
+    if (n == 0)
+      return BasicAutomata.makeString(input);
+    
+    if (n >= descriptions.length)
+      return null;
+    
+    final int range = 2*n+1;
+    ParametricDescription description = descriptions[n];
+    // the number of states is based on the length of the word and n
+    State states[] = new State[description.size()];
+    // create all states, and mark as accept states if appropriate
+    for (int i = 0; i < states.length; i++) {
+      states[i] = new State();
+      states[i].setAccept(description.isAccept(i));
+    }
+    // create transitions from state to state
+    for (int k = 0; k < states.length; k++) {
+      final int xpos = description.getPosition(k);
+      if (xpos < 0)
+        continue;
+      final int end = xpos + Math.min(word.length - xpos, range);
+      
+      for (int x = 0; x < alphabet.length; x++) {
+        final char ch = alphabet[x];
+        // get the characteristic vector at this position wrt ch
+        final int cvec = getVector(ch, xpos, end);
+        int dest = description.transition(k, xpos, cvec);
+        if (dest >= 0)
+          states[k].addTransition(new Transition(ch, states[dest]));
+      }
+      // add transitions for all other chars in unicode
+      // by definition, their characteristic vectors are always 0,
+      // because they do not exist in the input string.
+      int dest = description.transition(k, xpos, 0); // by definition
+      if (dest >= 0)
+        for (int r = 0; r < numRanges; r++)
+          states[k].addTransition(new Transition(rangeLower[r], rangeUpper[r], states[dest]));      
+    }
+
+    Automaton a = new Automaton();
+    a.setInitialState(states[0]);
+    a.setDeterministic(true);
+    // we should not need to trim transitions to dead states, we do not create these?
+    //
+    //a.restoreInvariant();
+    return a;
+  }
+  
+  /**
+   * Get the characteristic vector <code>X(x, V)</code> 
+   * where V is <code>substring(pos, end)</code>
+   */
+  int getVector(char x, int pos, int end) {
+    int vector = 0;
+    for (int i = pos; i < end; i++) {
+      vector <<= 1;
+      if (word[i] == x)
+        vector |= 1;
+    }
+    return vector;
+  }
+  
+  /**
+   * Precompute all characteristic vectors <code>X(x, V)</code>
+   * for some x where V is the entire word.
+   * This makes retrieving the vectors for some k-profile sequence
+   * at any position in {@link #getVector(char, int, int)}
+   * simply a bit substring operation.
+   */
+  static BitSet calcFullVector(char x, char word[]) {
+    BitSet charvector = new BitSet(word.length);
+    for (int i = 0; i < word.length; i++)
+      charvector.set(i, word[i] == x);
+    return charvector;
+  }
+  
+  /**
+   * A ParametricDescription describes the structure of a Levenshtein DFA for some degree n.
+   * <p>
+   * There are four components of a parametric description, all parameterized on the length
+   * of the word <code>w</code>:
+   * <ol>
+   * <li>The number of states: {@link #size()}
+   * <li>The set of final states: {@link #isAccept(int)}
+   * <li>The transition function: {@link #transition(int, int, int)}
+   * <li>Minimal boundary function: {@link #getPosition(int)}
+   * </ol>
+   */
+  static abstract class ParametricDescription {
+    protected int w;
+    
+    ParametricDescription(int w) {
+      this.w = w;
+    }
+    
+    /**
+     * Return the number of states needed to compute a Levenshtein DFA
+     */
+    abstract int size();
+    /**
+     * Returns true if the <code>state</code> in any Levenshtein DFA is an accept state (final state).
+     */
+    abstract boolean isAccept(int state);
+    /**
+     * Returns the position in the input word for a given <code>state</code>.
+     * This is the minimal boundary for the state.
+     */
+    abstract int getPosition(int state);
+    
+    /**
+     * Returns the state number for a transition from the given <code>state</code>,
+     * assuming <code>position</code> and characteristic vector <code>vector</code>
+     */
+    abstract int transition(int state, int position, int vector);
+  }
+
+}

Property changes on: src\java\org\apache\lucene\util\automaton\LevenshteinAutomata.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/java/org/apache/lucene/util/automaton/Lev1ParametricDescription.java
===================================================================
--- src/java/org/apache/lucene/util/automaton/Lev1ParametricDescription.java	(revision 0)
+++ src/java/org/apache/lucene/util/automaton/Lev1ParametricDescription.java	(revision 0)
@@ -0,0 +1,391 @@
+package org.apache.lucene.util.automaton;
+
+// The following code was generated with the moman/finenight pkg
+// This package is available under the MIT License, see NOTICE
+// for more details.
+
+import org.apache.lucene.util.automaton.LevenshteinAutomata.ParametricDescription;
+
+class Lev1ParametricDescription extends ParametricDescription {
+  
+  @Override
+  int transition(int absState, int position, int vector) {
+    
+    // decode absState -> state, offset
+    int state = absToState[absState];
+    int offset = absState - stateToAbs[state];
+    assert offset >= 0;
+    
+    // null state should never be passed in
+    assert state != -1;
+    if (position == w) {
+      switch(state) {
+        case 0: // (0, 0)
+          state = 1; // (0, 1)
+          break;
+        case 1: // (0, 1)
+          state = -1; // 
+          break;
+      }
+    } else if (position == w-1) {
+      switch(vector) {
+        case 0: // <0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 2; // (0, 1), (1, 1)
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = -1; // 
+              break;
+            case 1: // (0, 1)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 1: // <1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+          }
+          break;
+      }
+    } else if (position == w-2) {
+      switch(vector) {
+        case 0: // <0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 2; // (0, 1), (1, 1)
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = -1; // 
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = -1; // 
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = -1; // 
+              break;
+            case 1: // (0, 1)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 1: // <0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 2;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 2;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = -1; // 
+              break;
+            case 1: // (0, 1)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 2: // <1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+          }
+          break;
+        case 3: // <1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 2; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 2; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+          }
+          break;
+      }
+    } else {
+      switch(vector) {
+        case 0: // <0,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 2; // (0, 1), (1, 1)
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = -1; // 
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = -1; // 
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = -1; // 
+              break;
+            case 1: // (0, 1)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 1: // <0,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 2; // (0, 1), (1, 1)
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = -1; // 
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 1: // (0, 1)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 2: // <0,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 2;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 2;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = -1; // 
+              break;
+            case 1: // (0, 1)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 3: // <0,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 2; // (0, 1), (1, 1)
+              offset += 2;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 2;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 1: // (0, 1)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 4: // <1,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+          }
+          break;
+        case 5: // <1,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 4; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = 4; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+          }
+          break;
+        case 6: // <1,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 2; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 2; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+          }
+          break;
+        case 7: // <1,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1), (2, 1)
+              offset += 1;
+              break;
+            case 2: // (0, 1), (1, 1)
+              state = 2; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 4: // (0, 1), (2, 1)
+              state = 4; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+          }
+          break;
+      }
+    }
+    
+    if (state == -1) {
+      // null state
+      return -1;
+    } else {
+      // translate back to abs
+      return stateToAbs[state] + offset;
+    }
+  }
+  
+  // state map
+  //   0 -> [(0, 0)]
+  //   1 -> [(0, 1)]
+  //   2 -> [(0, 1), (1, 1)]
+  //   3 -> [(0, 1), (1, 1), (2, 1)]
+  //   4 -> [(0, 1), (2, 1)]
+  
+  private final static int[] stateSizes = new int[] {1,1,2,3,2};
+  private final static int[] minErrors = new int[] {0,1,0,-1,-1};
+  private final int[] stateToAbs;
+  private final int[] absToState;
+  
+  public Lev1ParametricDescription(int w) {
+    super(w);
+    stateToAbs = new int[5];
+    absToState = new int[(w+1)*9];
+    int upto = 0;
+    for(int i=0;i<stateSizes.length;i++) {
+      stateToAbs[i] = upto;
+      for(int j=0;j<((w+1)*stateSizes[i]);j++) {
+        absToState[upto++] = i;
+      }
+    }
+  }
+  
+  @Override
+  public int size() {
+    return absToState.length;
+  }
+  
+  @Override
+  public int getPosition(int absState) {
+    int state = absToState[absState];
+    int offset = absState - stateToAbs[state];
+    return offset;
+  }
+  
+  @Override
+  public boolean isAccept(int absState) {
+    // decode absState -> state, offset
+    int state = absToState[absState];
+    int offset = absState - stateToAbs[state];
+    assert offset >= 0;
+    return w - offset + minErrors[state] <= 1;
+  }
+}

Property changes on: src\java\org\apache\lucene\util\automaton\Lev1ParametricDescription.java
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/java/org/apache/lucene/util/automaton/Lev2ParametricDescription.java
===================================================================
--- src/java/org/apache/lucene/util/automaton/Lev2ParametricDescription.java	(revision 0)
+++ src/java/org/apache/lucene/util/automaton/Lev2ParametricDescription.java	(revision 0)
@@ -0,0 +1,6597 @@
+package org.apache.lucene.util.automaton;
+
+// The following code was generated with the moman/finenight pkg
+// This package is available under the MIT License, see NOTICE
+// for more details.
+
+import org.apache.lucene.util.automaton.LevenshteinAutomata.ParametricDescription;
+
+class Lev2ParametricDescription extends ParametricDescription {
+  
+  @Override
+  int transition(int absState, int position, int vector) {
+    
+    // decode absState -> state, offset
+    int state = absToState[absState];
+    int offset = absState - stateToAbs[state];
+    assert offset >= 0;
+    
+    // null state should never be passed in
+    assert state != -1;
+    if (position == w) {
+      switch(state) {
+        case 0: // (0, 0)
+          state = 1; // (0, 1)
+          break;
+        case 1: // (0, 1)
+          state = 2; // (0, 2)
+          break;
+        case 2: // (0, 2)
+          state = -1; // 
+          break;
+      }
+    } else if (position == w-1) {
+      switch(vector) {
+        case 0: // <0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 1: // <1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+      }
+    } else if (position == w-2) {
+      switch(vector) {
+        case 0: // <0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 1: // <0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 2: // <1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 3: // <1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+      }
+    } else if (position == w-3) {
+      switch(vector) {
+        case 0: // <0,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 1: // <0,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 2: // <0,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 3: // <0,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 4: // <1,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 5: // <1,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 6: // <1,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 7: // <1,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+      }
+    } else if (position == w-4) {
+      switch(vector) {
+        case 0: // <0,0,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 1: // <0,0,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 2: // <0,0,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 3: // <0,0,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 23; // (0, 2), (1, 2), (3, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 4: // <0,1,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 5: // <0,1,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 6: // <0,1,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 7: // <0,1,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 21; // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 8: // <1,0,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 9: // <1,0,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 10: // <1,0,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 11: // <1,0,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 13; // (0, 1), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 12: // <1,1,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 13: // <1,1,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 14: // <1,1,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 15: // <1,1,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 13; // (0, 1), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+      }
+    } else {
+      switch(vector) {
+        case 0: // <0,0,0,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 1: // <0,0,0,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 2: // <0,0,0,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 3: // <0,0,0,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 3; // (0, 1), (1, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 4: // <0,0,1,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 5: // <0,0,1,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 6: // <0,0,1,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 23; // (0, 2), (1, 2), (3, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 7: // <0,0,1,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 23; // (0, 2), (1, 2), (3, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 4; // (0, 2), (1, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 3;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = -1; // 
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 8: // <0,1,0,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 9: // <0,1,0,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 10: // <0,1,0,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 11: // <0,1,0,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 2;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = -1; // 
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 12: // <0,1,1,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 13: // <0,1,1,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = -1; // 
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 14: // <0,1,1,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 21; // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = -1; // 
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 15: // <0,1,1,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 9; // (0, 2), (2, 1)
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 21; // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              break;
+            case 1: // (0, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 2;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 2;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 2;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 2;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 2;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 2;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 2;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 2;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 2;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 3;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 3;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 1; // (0, 1)
+              offset += 3;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 3;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 3;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 3;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 3;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 1; // (0, 1)
+              offset += 4;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 4;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 4;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 5;
+              break;
+            case 2: // (0, 2)
+              state = -1; // 
+              break;
+          }
+          break;
+        case 16: // <1,0,0,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 17: // <1,0,0,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 18: // <1,0,0,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 19: // <1,0,0,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 20: // <1,0,1,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 21: // <1,0,1,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 22: // <1,0,1,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 13; // (0, 1), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 23: // <1,0,1,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 13; // (0, 1), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 26; // (0, 2), (2, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 26; // (0, 2), (2, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 24: // <1,1,0,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 25: // <1,1,0,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 26: // <1,1,0,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 27: // <1,1,0,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 23; // (0, 2), (1, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 23; // (0, 2), (1, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 28: // <1,1,1,0,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 29: // <1,1,1,0,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 30: // <1,1,1,1,0>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 13; // (0, 1), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+        case 31: // <1,1,1,1,1>
+          switch(state) {
+            case 0: // (0, 0)
+              state = 0; // (0, 0)
+              offset += 1;
+              break;
+            case 5: // (0, 1), (1, 1), (2, 1)
+              state = 5; // (0, 1), (1, 1), (2, 1)
+              offset += 1;
+              break;
+            case 12: // (0, 1), (1, 1), (3, 2)
+              state = 12; // (0, 1), (1, 1), (3, 2)
+              offset += 1;
+              break;
+            case 3: // (0, 1), (1, 1)
+              state = 3; // (0, 1), (1, 1)
+              offset += 1;
+              break;
+            case 7: // (0, 1), (2, 1)
+              state = 7; // (0, 1), (2, 1)
+              offset += 1;
+              break;
+            case 13: // (0, 1), (2, 2), (3, 2)
+              state = 13; // (0, 1), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 8: // (0, 1), (2, 2)
+              state = 8; // (0, 1), (2, 2)
+              offset += 1;
+              break;
+            case 14: // (0, 1), (3, 2)
+              state = 14; // (0, 1), (3, 2)
+              offset += 1;
+              break;
+            case 1: // (0, 1)
+              state = 1; // (0, 1)
+              offset += 1;
+              break;
+            case 21: // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              state = 21; // (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 11: // (0, 2), (1, 2), (2, 2), (3, 2)
+              state = 11; // (0, 2), (1, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 22: // (0, 2), (1, 2), (2, 2), (4, 2)
+              state = 22; // (0, 2), (1, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 6: // (0, 2), (1, 2), (2, 2)
+              state = 6; // (0, 2), (1, 2), (2, 2)
+              offset += 1;
+              break;
+            case 15: // (0, 2), (1, 2), (3, 1)
+              state = 15; // (0, 2), (1, 2), (3, 1)
+              offset += 1;
+              break;
+            case 23: // (0, 2), (1, 2), (3, 2), (4, 2)
+              state = 23; // (0, 2), (1, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 16: // (0, 2), (1, 2), (3, 2)
+              state = 16; // (0, 2), (1, 2), (3, 2)
+              offset += 1;
+              break;
+            case 24: // (0, 2), (1, 2), (4, 2)
+              state = 24; // (0, 2), (1, 2), (4, 2)
+              offset += 1;
+              break;
+            case 4: // (0, 2), (1, 2)
+              state = 4; // (0, 2), (1, 2)
+              offset += 1;
+              break;
+            case 17: // (0, 2), (2, 1), (3, 1)
+              state = 17; // (0, 2), (2, 1), (3, 1)
+              offset += 1;
+              break;
+            case 25: // (0, 2), (2, 1), (4, 2)
+              state = 25; // (0, 2), (2, 1), (4, 2)
+              offset += 1;
+              break;
+            case 9: // (0, 2), (2, 1)
+              state = 9; // (0, 2), (2, 1)
+              offset += 1;
+              break;
+            case 26: // (0, 2), (2, 2), (3, 2), (4, 2)
+              state = 26; // (0, 2), (2, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 18: // (0, 2), (2, 2), (3, 2)
+              state = 18; // (0, 2), (2, 2), (3, 2)
+              offset += 1;
+              break;
+            case 27: // (0, 2), (2, 2), (4, 2)
+              state = 27; // (0, 2), (2, 2), (4, 2)
+              offset += 1;
+              break;
+            case 10: // (0, 2), (2, 2)
+              state = 10; // (0, 2), (2, 2)
+              offset += 1;
+              break;
+            case 19: // (0, 2), (3, 1)
+              state = 19; // (0, 2), (3, 1)
+              offset += 1;
+              break;
+            case 28: // (0, 2), (3, 2), (4, 2)
+              state = 28; // (0, 2), (3, 2), (4, 2)
+              offset += 1;
+              break;
+            case 20: // (0, 2), (3, 2)
+              state = 20; // (0, 2), (3, 2)
+              offset += 1;
+              break;
+            case 29: // (0, 2), (4, 2)
+              state = 29; // (0, 2), (4, 2)
+              offset += 1;
+              break;
+            case 2: // (0, 2)
+              state = 2; // (0, 2)
+              offset += 1;
+              break;
+          }
+          break;
+      }
+    }
+    
+    if (state == -1) {
+      // null state
+      return -1;
+    } else {
+      // translate back to abs
+      return stateToAbs[state] + offset;
+    }
+  }
+  
+  // state map
+  //   0 -> [(0, 0)]
+  //   1 -> [(0, 1)]
+  //   2 -> [(0, 2)]
+  //   3 -> [(0, 1), (1, 1)]
+  //   4 -> [(0, 2), (1, 2)]
+  //   5 -> [(0, 1), (1, 1), (2, 1)]
+  //   6 -> [(0, 2), (1, 2), (2, 2)]
+  //   7 -> [(0, 1), (2, 1)]
+  //   8 -> [(0, 1), (2, 2)]
+  //   9 -> [(0, 2), (2, 1)]
+  //   10 -> [(0, 2), (2, 2)]
+  //   11 -> [(0, 2), (1, 2), (2, 2), (3, 2)]
+  //   12 -> [(0, 1), (1, 1), (3, 2)]
+  //   13 -> [(0, 1), (2, 2), (3, 2)]
+  //   14 -> [(0, 1), (3, 2)]
+  //   15 -> [(0, 2), (1, 2), (3, 1)]
+  //   16 -> [(0, 2), (1, 2), (3, 2)]
+  //   17 -> [(0, 2), (2, 1), (3, 1)]
+  //   18 -> [(0, 2), (2, 2), (3, 2)]
+  //   19 -> [(0, 2), (3, 1)]
+  //   20 -> [(0, 2), (3, 2)]
+  //   21 -> [(0, 2), (1, 2), (2, 2), (3, 2), (4, 2)]
+  //   22 -> [(0, 2), (1, 2), (2, 2), (4, 2)]
+  //   23 -> [(0, 2), (1, 2), (3, 2), (4, 2)]
+  //   24 -> [(0, 2), (1, 2), (4, 2)]
+  //   25 -> [(0, 2), (2, 1), (4, 2)]
+  //   26 -> [(0, 2), (2, 2), (3, 2), (4, 2)]
+  //   27 -> [(0, 2), (2, 2), (4, 2)]
+  //   28 -> [(0, 2), (3, 2), (4, 2)]
+  //   29 -> [(0, 2), (4, 2)]
+  
+  private final static int[] stateSizes = new int[] {1,1,1,2,2,3,3,2,2,2,2,4,3,3,2,3,3,3,3,2,2,5,4,4,3,3,4,3,3,2};
+  private final static int[] minErrors = new int[] {0,1,2,0,1,-1,0,-1,0,-1,0,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-2,-2,-2,-2,-2,-2,-2,-2};
+  private final int[] stateToAbs;
+  private final int[] absToState;
+  
+  public Lev2ParametricDescription(int w) {
+    super(w);
+    stateToAbs = new int[30];
+    absToState = new int[(w+1)*80];
+    int upto = 0;
+    for(int i=0;i<stateSizes.length;i++) {
+      stateToAbs[i] = upto;
+      for(int j=0;j<((w+1)*stateSizes[i]);j++) {
+        absToState[upto++] = i;
+      }
+    }
+  }
+  
+  @Override
+  public int size() {
+    return absToState.length;
+  }
+  
+  @Override
+  public int getPosition(int absState) {
+    int state = absToState[absState];
+    int offset = absState - stateToAbs[state];
+    return offset;
+  }
+  
+  @Override
+  public boolean isAccept(int absState) {
+    // decode absState -> state, offset
+    int state = absToState[absState];
+    int offset = absState - stateToAbs[state];
+    assert offset >= 0;
+    return w - offset + minErrors[state] <= 2;
+  }
+}

Property changes on: src\java\org\apache\lucene\util\automaton\Lev2ParametricDescription.java
___________________________________________________________________
Added: svn:eol-style
   + native

