Repository: FHIR/sushi
Pull request #818 (2021-05-20 13:24:05)

Support indentation in CodeSystem rules
Completes task [CIMPL-709](https://standardhealthrecord.atlassian.net/browse/CIMPL-709).

The features for CodeSystems added by #809 were developed at around the same time as the support for indentation added in #797, so this PR adds the power of indentation to concept rules and code caret value rules in code systems. These rules make use of a code path context, which is distinct from a regular path context. Additionally, there is a small but important change in the FSH grammar that allows for the code path equivalent of a path rule, where a code path context is set without creating any new rules. Because the grammar for this is indistinguishable for defining a new concept, this somewhat overlaps with detecting duplicate codes being added to the code system. Thus, a duplicate code will _not_ be detected as an error if the definitions after the first do not include a display or definition. There are test cases to demonstrate this behavior. I think that this is the best way to allow for the setting of code path contexts without requiring additional FSH that would distinguish between defining a code and referring to an existing code.

A somewhat odd but very convenient side effect of supporting code path contexts is that a code caret value rule can now legally be written without any codes at all, if it makes use of a code path context. As such, the grammar for code system rules no longer accepts regular caret value rules. The actual `FshCodeSystem` class still uses `CaretValueRule` the same way it did before. Logic in the visitor for code caret value rule determines whether to construct a `CodeCaretValueRule` or `CaretValueRule`.

All the rules from code hierarchies still apply, of course. The indentation simply allows for some amount of saved typing by using an established code path context.

cmoesel: One CI is stuck on checking out the code -- and this has already been approved by Nick and Julian -- so I am merging!

Patch:
diff --git a/antlr/src/main/antlr/FSH.g4 b/antlr/src/main/antlr/FSH.g4
index 336fb7a..27e9eff 100644
--- a/antlr/src/main/antlr/FSH.g4
+++ b/antlr/src/main/antlr/FSH.g4
@@ -27,7 +27,7 @@ vsMetadata:         id | title | description;
 vsRule:             vsComponent | caretValueRule | insertRule;
 codeSystem:         KW_CODESYSTEM name csMetadata* csRule*;
 csMetadata:         id | title | description;
-csRule:             concept | caretValueRule | codeCaretValueRule | insertRule;
+csRule:             concept | codeCaretValueRule | insertRule;
 
 ruleSet:            KW_RULESET RULESET_REFERENCE ruleSetRule+;
 ruleSetRule:        sdRule | concept | codeCaretValueRule | vsComponent;
@@ -71,7 +71,7 @@ containsRule:       STAR path KW_CONTAINS item (KW_AND item)*;
 onlyRule:           STAR path KW_ONLY targetType (KW_OR targetType)*;
 obeysRule:          STAR path? KW_OBEYS name (KW_AND name)*;
 caretValueRule:     STAR path? caretPath EQUAL value;
-codeCaretValueRule: STAR (CODE)+ caretPath EQUAL value;
+codeCaretValueRule: STAR CODE* caretPath EQUAL value;
 mappingRule:        STAR path? ARROW STRING STRING? CODE?;
 insertRule:         STAR KW_INSERT (RULESET_REFERENCE | PARAM_RULESET_REFERENCE);
 addElementRule:     STAR path CARD flag* targetType (KW_OR targetType)* STRING? STRING?;
diff --git a/src/export/CodeSystemExporter.ts b/src/export/CodeSystemExporter.ts
index 3e16141..f37e2fb 100644
--- a/src/export/CodeSystemExporter.ts
+++ b/src/export/CodeSystemExporter.ts
@@ -59,36 +59,34 @@ export class CodeSystemExporter {
     }
   }
 
-  private setCaretRules(
+  private setCaretPathRules(
     codeSystem: CodeSystem,
     csStructureDefinition: StructureDefinition,
-    rules: CaretValueRule[]
-  ): void {
-    resolveSoftIndexing(rules);
-    for (const rule of rules) {
+    rules: (CaretValueRule | CodeCaretValueRule)[]
+  ) {
+    // soft index resolution relies on the rule's path attribute.
+    // a CodeCaretValueRule is created with an empty path, so first
+    // transform its codePath into a path.
+    // Because this.findConceptPath can potentially throw an error,
+    // build a list of successful rules that will actually be applied.
+    const successfulRules: (CaretValueRule | CodeCaretValueRule)[] = [];
+    rules.forEach(rule => {
       try {
-        const { assignedValue, pathParts } = csStructureDefinition.validateValueAtPath(
-          rule.caretPath,
-          rule.value,
-          this.fisher
-        );
-        setPropertyOnInstance(codeSystem, pathParts, assignedValue, this.fisher);
+        if (rule instanceof CodeCaretValueRule) {
+          rule.path = this.findConceptPath(codeSystem, rule.codePath);
+          successfulRules.push(rule);
+        } else {
+          successfulRules.push(rule);
+        }
       } catch (e) {
         logger.error(e.message, rule.sourceInfo);
       }
-    }
-  }
-
-  private setCodeCaretRules(
-    codeSystem: CodeSystem,
-    csStructureDefinition: StructureDefinition,
-    rules: CodeCaretValueRule[]
-  ) {
-    for (const rule of rules) {
+    });
+    resolveSoftIndexing(successfulRules);
+    for (const rule of successfulRules) {
       try {
-        const conceptPath = this.findConceptPath(codeSystem, rule.codePath);
         const { assignedValue, pathParts } = csStructureDefinition.validateValueAtPath(
-          `${conceptPath}.${rule.caretPath}`,
+          rule.path.length > 1 ? `${rule.path}.${rule.caretPath}` : rule.caretPath,
           rule.value,
           this.fisher
         );
@@ -160,19 +158,16 @@ export class CodeSystemExporter {
     const csStructureDefinition = StructureDefinition.fromJSON(
       this.fisher.fishForFHIR('CodeSystem', Type.Resource)
     );
-    this.setCaretRules(
-      codeSystem,
-      csStructureDefinition,
-      fshDefinition.rules.filter(rule => rule instanceof CaretValueRule) as CaretValueRule[]
-    );
     this.setConcepts(
       codeSystem,
       fshDefinition.rules.filter(rule => rule instanceof ConceptRule) as ConceptRule[]
     );
-    this.setCodeCaretRules(
+    this.setCaretPathRules(
       codeSystem,
       csStructureDefinition,
-      fshDefinition.rules.filter(rule => rule instanceof CodeCaretValueRule) as CodeCaretValueRule[]
+      fshDefinition.rules.filter(
+        rule => rule instanceof CaretValueRule || rule instanceof CodeCaretValueRule
+      ) as (CaretValueRule | CodeCaretValueRule)[]
     );
 
     // check for another code system with the same id
diff --git a/src/fshtypes/FshCodeSystem.ts b/src/fshtypes/FshCodeSystem.ts
index 666089b..ab425f9 100644
--- a/src/fshtypes/FshCodeSystem.ts
+++ b/src/fshtypes/FshCodeSystem.ts
@@ -27,8 +27,22 @@ export class FshCodeSystem extends FshEntity {
   }
 
   addConcept(newConcept: ConceptRule) {
-    if (this.rules.find(rule => rule instanceof ConceptRule && rule.code == newConcept.code)) {
-      throw new CodeSystemDuplicateCodeError(this.id, newConcept.code);
+    const existingConcept = this.rules.find(
+      rule => rule instanceof ConceptRule && rule.code == newConcept.code
+    ) as ConceptRule;
+    if (existingConcept) {
+      // if the new ConceptRule has only a code and a hierarchy,
+      // and the existing ConceptRule with that code has a matching hierarchy,
+      // the user may simply be referencing the existing concept to establish context.
+      if (
+        newConcept.display == null &&
+        newConcept.definition == null &&
+        isEqual(existingConcept.hierarchy, newConcept.hierarchy)
+      ) {
+        return;
+      } else {
+        throw new CodeSystemDuplicateCodeError(this.id, newConcept.code);
+      }
     }
     // check the hierarchy, if applicable
     // for each predecessor element in the new concept's hierarchy, we should be able to find a rule that
diff --git a/src/import/FSHImporter.ts b/src/import/FSHImporter.ts
index 4d161bb..94db789 100644
--- a/src/import/FSHImporter.ts
+++ b/src/import/FSHImporter.ts
@@ -137,6 +137,7 @@ export class FSHImporter extends FSHVisitor {
   paramRuleSets: Map<string, ParamRuleSet>;
   private topLevelParse: boolean;
   private pathContext: string[];
+  private codePathContext: string[][];
   private baseIndent: number;
 
   constructor() {
@@ -236,8 +237,9 @@ export class FSHImporter extends FSHVisitor {
   }
 
   visitEntity(ctx: pc.EntityContext): void {
-    // Reset the pathContext and baseIndent level for each entity
+    // Reset the pathContext, codePathContext, and baseIndent level for each entity
     this.pathContext = [];
+    this.codePathContext = [];
     this.baseIndent = this.extractStartStop(ctx).startColumn;
 
     if (ctx.profile()) {
@@ -955,16 +957,6 @@ export class FSHImporter extends FSHVisitor {
       return this.visitConcept(ctx.concept());
     } else if (ctx.codeCaretValueRule()) {
       return this.visitCodeCaretValueRule(ctx.codeCaretValueRule());
-    } else if (ctx.caretValueRule()) {
-      const rule = this.visitCaretValueRule(ctx.caretValueRule());
-      if (rule.path) {
-        logger.error(
-          'Caret rule on CodeSystem cannot contain path before ^, skipping rule.',
-          rule.sourceInfo
-        );
-      } else {
-        return rule;
-      }
     } else if (ctx.insertRule()) {
       return this.visitInsertRule(ctx.insertRule());
     }
@@ -995,6 +987,10 @@ export class FSHImporter extends FSHVisitor {
     return this.prependPathContext(path, parentCtx);
   }
 
+  getCodePathWithContext(codePath: string[], parentCtx: ParserRuleContext) {
+    return this.prependCodePathContext(codePath, parentCtx);
+  }
+
   visitPath(ctx: pc.PathContext): string {
     if (ctx?.KW_SYSTEM()) {
       return ctx.KW_SYSTEM().getText();
@@ -1194,15 +1190,22 @@ export class FSHImporter extends FSHVisitor {
   }
 
   visitConcept(ctx: pc.ConceptContext): ConceptRule {
-    const allCodes = ctx.CODE().map(codeCtx => this.parseCodeLexeme(codeCtx.getText(), codeCtx));
+    const localCodePath = ctx
+      .CODE()
+      .map(codeCtx => this.parseCodeLexeme(codeCtx.getText(), codeCtx));
     // the last code in allCodes is the one we are actually defining.
     // the rest are the hierarchy, which may be empty.
-    const codePart = allCodes.slice(-1)[0];
+    // indentation may also be used to define the hierarchy, which is what the code path with context is for.
+    const fullCodePath = this.getCodePathWithContext(
+      localCodePath.map(localCode => localCode.code),
+      ctx
+    );
+    const codePart = localCodePath.slice(-1)[0];
     const availableStrings = ctx.STRING().map(strCtx => this.extractString(strCtx));
     const concept = new ConceptRule(codePart.code)
       .withLocation(this.extractStartStop(ctx))
       .withFile(this.currentFile);
-    concept.hierarchy = allCodes.slice(0, -1).map(code => code.code);
+    concept.hierarchy = fullCodePath.slice(0, -1);
     if (availableStrings.length > 0) {
       concept.display = availableStrings[0];
     }
@@ -1211,7 +1214,7 @@ export class FSHImporter extends FSHVisitor {
     } else if (ctx.MULTILINE_STRING()) {
       concept.definition = this.extractMultilineString(ctx.MULTILINE_STRING());
     }
-    if (allCodes.some(listedConcept => listedConcept.system)) {
+    if (localCodePath.some(listedConcept => listedConcept.system)) {
       logger.error(
         'Do not include the system when listing concepts for a code system.',
         concept.sourceInfo
@@ -1401,18 +1404,22 @@ export class FSHImporter extends FSHVisitor {
   }
 
   visitCodeCaretValueRule(ctx: pc.CodeCaretValueRuleContext): CodeCaretValueRule {
-    const codePath = ctx.CODE().map(code => {
-      return this.parseCodeLexeme(code.getText(), ctx).code;
-    });
-    const codeCaretValueRule = new CodeCaretValueRule(codePath)
+    const localCodePath = ctx.CODE()
+      ? ctx.CODE().map(code => {
+          return this.parseCodeLexeme(code.getText(), ctx).code;
+        })
+      : [];
+    const fullCodePath = this.getCodePathWithContext(localCodePath, ctx);
+    // It's fine to make a CodeCaretValueRule with an empty code path.
+    const caretRule = new CodeCaretValueRule(fullCodePath)
       .withLocation(this.extractStartStop(ctx))
       .withFile(this.currentFile);
     // Get the caret path, but slice off the starting ^
-    codeCaretValueRule.caretPath = this.visitCaretPath(ctx.caretPath()).slice(1);
-    codeCaretValueRule.value = this.visitValue(ctx.value());
-    codeCaretValueRule.isInstance =
+    caretRule.caretPath = this.visitCaretPath(ctx.caretPath()).slice(1);
+    caretRule.value = this.visitValue(ctx.value());
+    caretRule.isInstance =
       ctx.value()?.name() != null && !this.allAliases.has(ctx.value().name().getText());
-    return codeCaretValueRule;
+    return caretRule;
   }
 
   visitObeysRule(ctx: pc.ObeysRuleContext): ObeysRule[] {
@@ -1847,30 +1854,9 @@ export class FSHImporter extends FSHVisitor {
   private prependPathContext(path: string, parentCtx: any): string {
     const location = this.extractStartStop(parentCtx);
     const currentIndent = location.startColumn - this.baseIndent;
-
-    if (currentIndent > 0 && this.pathContext.length === 0) {
-      logger.error(
-        'The first rule of a definition cannot be indented. The rule will be processed as if it is not indented.',
-        { location, file: this.currentFile }
-      );
-      return path;
-    }
-
-    if (currentIndent % INDENT_WIDTH !== 0 || currentIndent < 0) {
-      logger.error(
-        `Unable to determine path context for rule indented ${currentIndent} space(s). Rules must be indented in multiples of ${INDENT_WIDTH} space(s).`,
-        { location, file: this.currentFile }
-      );
-      return path;
-    }
-
-    // And we require that rules are not indented too deeply
     const contextIndex = currentIndent / INDENT_WIDTH;
-    if (contextIndex > this.pathContext.length) {
-      logger.error(
-        `Cannot determine path context of rule since it is indented too deeply. Rules must be indented in increments of ${INDENT_WIDTH} space(s).`,
-        { location, file: this.currentFile }
-      );
+
+    if (!this.isValidContext(location, currentIndent, this.pathContext)) {
       return path;
     }
 
@@ -1902,6 +1888,79 @@ export class FSHImporter extends FSHVisitor {
     return path ? `${currentContext}.${path}` : currentContext;
   }
 
+  /**
+   * Given a code path and the context containing it, apply the code path context indicated by the code path's indent
+   * @param codePath - The code path to apply context to
+   * @param parentCtx - The parent element containing the code path
+   * @returns {string[]} - The code path with context prepended
+   */
+  private prependCodePathContext(codePath: string[], parentCtx: ParserRuleContext): string[] {
+    const location = this.extractStartStop(parentCtx);
+    const currentIndent = location.startColumn - this.baseIndent;
+    const contextIndex = currentIndent / INDENT_WIDTH;
+
+    if (!this.isValidContext(location, currentIndent, this.codePathContext)) {
+      return codePath;
+    }
+
+    // A PathRule can set a path, but there's no equivalent for a code path.
+    // And, there's no need to check for soft indexing either.
+    // If there's no indent, use the codePath as-is, and make it the only available context.
+    if (contextIndex === 0) {
+      this.codePathContext = [codePath];
+      return codePath;
+    }
+    // Otherwise, get the context based on the indent level.
+    const currentContext = this.codePathContext[contextIndex - 1];
+    if (currentContext.length === 0) {
+      logger.error(
+        'Rule cannot be indented below rule which has no code path. The rule will be processed as if it is not indented.',
+        { location, file: this.currentFile }
+      );
+      return codePath;
+    }
+
+    // Trim out-of-scope contexts
+    this.codePathContext.splice(contextIndex);
+    const fullCodePath = currentContext.concat(codePath);
+    this.codePathContext.push(fullCodePath);
+
+    return fullCodePath;
+  }
+
+  private isValidContext(
+    location: TextLocation,
+    currentIndent: number,
+    existingContext: string[] | string[][]
+  ): boolean {
+    if (currentIndent > 0 && existingContext.length === 0) {
+      logger.error(
+        'The first rule of a definition cannot be indented. The rule will be processed as if it is not indented.',
+        { location, file: this.currentFile }
+      );
+      return false;
+    }
+
+    if (currentIndent % INDENT_WIDTH !== 0 || currentIndent < 0) {
+      logger.error(
+        `Unable to determine path context for rule indented ${currentIndent} space(s). Rules must be indented in multiples of ${INDENT_WIDTH} space(s).`,
+        { location, file: this.currentFile }
+      );
+      return false;
+    }
+
+    // And we require that rules are not indented too deeply
+    const contextIndex = currentIndent / INDENT_WIDTH;
+    if (contextIndex > existingContext.length) {
+      logger.error(
+        `Cannot determine path context of rule since it is indented too deeply. Rules must be indented in increments of ${INDENT_WIDTH} space(s).`,
+        { location, file: this.currentFile }
+      );
+      return false;
+    }
+    return true;
+  }
+
   private extractString(stringCtx: ParserRuleContext): string {
     const str = stringCtx?.getText() ?? '""'; // default to empty string if stringCtx is null
     const strNoQuotes = str.slice(1, str.length - 1); // Strip surrounding quotes
@@ -1977,7 +2036,10 @@ export class FSHImporter extends FSHVisitor {
         endLine: ctx.stop.line,
         endColumn: ctx.stop.stop - ctx.stop.start + ctx.stop.column + 1
       };
-      if (!pc.containsPathContext(ctx) && location.startColumn - this.baseIndent > 0) {
+      if (
+        !(pc.containsPathContext(ctx) || pc.containsCodePathContext(ctx)) &&
+        location.startColumn - this.baseIndent > 0
+      ) {
         logger.error(
           'A rule that does not use a path cannot be indented to indicate context. The rule will be processed as if it is not indented.',
           { location, file: this.currentFile }
diff --git a/src/import/generated/FSH.interp b/src/import/generated/FSH.interp
index 4c924ea..3777289 100644
--- a/src/import/generated/FSH.interp
+++ b/src/import/generated/FSH.interp
@@ -234,4 +234,4 @@ targetType
 
 
 atn:
-[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 76, 715, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 3, 2, 7, 2, 160, 10, 2, 12, 2, 14, 2, 163, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 179, 10, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 6, 5, 189, 10, 5, 13, 5, 14, 5, 190, 3, 5, 7, 5, 194, 10, 5, 12, 5, 14, 5, 197, 11, 5, 3, 6, 3, 6, 3, 6, 7, 6, 202, 10, 6, 12, 6, 14, 6, 205, 11, 6, 3, 6, 7, 6, 208, 10, 6, 12, 6, 14, 6, 211, 11, 6, 3, 7, 3, 7, 3, 7, 7, 7, 216, 10, 7, 12, 7, 14, 7, 219, 11, 7, 3, 7, 7, 7, 222, 10, 7, 12, 7, 14, 7, 225, 11, 7, 3, 8, 3, 8, 3, 8, 7, 8, 230, 10, 8, 12, 8, 14, 8, 233, 11, 8, 3, 8, 7, 8, 236, 10, 8, 12, 8, 14, 8, 239, 11, 8, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 245, 10, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 257, 10, 10, 3, 11, 3, 11, 5, 11, 261, 10, 11, 3, 12, 3, 12, 3, 12, 7, 12, 266, 10, 12, 12, 12, 14, 12, 269, 11, 12, 3, 12, 7, 12, 272, 10, 12, 12, 12, 14, 12, 275, 11, 12, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 281, 10, 13, 3, 14, 3, 14, 3, 14, 5, 14, 286, 10, 14, 3, 15, 3, 15, 3, 15, 6, 15, 291, 10, 15, 13, 15, 14, 15, 292, 3, 16, 3, 16, 3, 16, 3, 16, 5, 16, 299, 10, 16, 3, 17, 3, 17, 3, 17, 7, 17, 304, 10, 17, 12, 17, 14, 17, 307, 11, 17, 3, 17, 7, 17, 310, 10, 17, 12, 17, 14, 17, 313, 11, 17, 3, 18, 3, 18, 3, 18, 5, 18, 318, 10, 18, 3, 19, 3, 19, 3, 19, 5, 19, 323, 10, 19, 3, 20, 3, 20, 3, 20, 7, 20, 328, 10, 20, 12, 20, 14, 20, 331, 11, 20, 3, 20, 7, 20, 334, 10, 20, 12, 20, 14, 20, 337, 11, 20, 3, 21, 3, 21, 3, 21, 5, 21, 342, 10, 21, 3, 22, 3, 22, 3, 22, 3, 22, 5, 22, 348, 10, 22, 3, 23, 3, 23, 3, 23, 6, 23, 353, 10, 23, 13, 23, 14, 23, 354, 3, 24, 3, 24, 3, 24, 3, 24, 5, 24, 361, 10, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 7, 26, 369, 10, 26, 12, 26, 14, 26, 372, 11, 26, 3, 27, 3, 27, 3, 27, 7, 27, 377, 10, 27, 12, 27, 14, 27, 380, 11, 27, 3, 27, 7, 27, 383, 10, 27, 12, 27, 14, 27, 386, 11, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 393, 10, 28, 3, 29, 3, 29, 3, 29, 5, 29, 398, 10, 29, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 7, 41, 437, 10, 41, 12, 41, 14, 41, 440, 11, 41, 3, 42, 3, 42, 3, 42, 3, 42, 7, 42, 446, 10, 42, 12, 42, 14, 42, 449, 11, 42, 3, 42, 6, 42, 452, 10, 42, 13, 42, 14, 42, 453, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 5, 43, 461, 10, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 5, 44, 468, 10, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 7, 45, 476, 10, 45, 12, 45, 14, 45, 479, 11, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 487, 10, 46, 12, 46, 14, 46, 490, 11, 46, 3, 47, 3, 47, 5, 47, 494, 10, 47, 3, 47, 3, 47, 3, 47, 3, 47, 7, 47, 500, 10, 47, 12, 47, 14, 47, 503, 11, 47, 3, 48, 3, 48, 5, 48, 507, 10, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 6, 49, 515, 10, 49, 13, 49, 14, 49, 516, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 5, 50, 525, 10, 50, 3, 50, 3, 50, 3, 50, 5, 50, 530, 10, 50, 3, 50, 5, 50, 533, 10, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 7, 52, 543, 10, 52, 12, 52, 14, 52, 546, 11, 52, 3, 52, 3, 52, 3, 52, 7, 52, 551, 10, 52, 12, 52, 14, 52, 554, 11, 52, 3, 52, 5, 52, 557, 10, 52, 3, 52, 5, 52, 560, 10, 52, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 5, 54, 567, 10, 54, 3, 54, 3, 54, 5, 54, 571, 10, 54, 3, 55, 3, 55, 5, 55, 575, 10, 55, 3, 55, 3, 55, 3, 55, 6, 55, 580, 10, 55, 13, 55, 14, 55, 581, 3, 55, 3, 55, 3, 55, 5, 55, 587, 10, 55, 3, 56, 3, 56, 3, 56, 3, 56, 5, 56, 593, 10, 56, 3, 57, 3, 57, 3, 57, 3, 57, 5, 57, 599, 10, 57, 3, 57, 3, 57, 3, 57, 5, 57, 604, 10, 57, 5, 57, 606, 10, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 7, 59, 615, 10, 59, 12, 59, 14, 59, 618, 11, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 5, 61, 627, 10, 61, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 5, 63, 636, 10, 63, 3, 64, 3, 64, 3, 65, 3, 65, 3, 66, 3, 66, 3, 67, 3, 67, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 5, 69, 660, 10, 69, 3, 70, 3, 70, 3, 70, 5, 70, 665, 10, 70, 3, 70, 3, 70, 7, 70, 669, 10, 70, 12, 70, 14, 70, 672, 11, 70, 3, 71, 3, 71, 5, 71, 676, 10, 71, 3, 72, 3, 72, 6, 72, 680, 10, 72, 13, 72, 14, 72, 681, 3, 72, 5, 72, 685, 10, 72, 3, 72, 5, 72, 688, 10, 72, 3, 73, 3, 73, 3, 73, 5, 73, 693, 10, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 5, 75, 701, 10, 75, 3, 76, 3, 76, 3, 77, 3, 77, 5, 77, 707, 10, 77, 3, 78, 3, 78, 3, 79, 3, 79, 5, 79, 713, 10, 79, 3, 79, 2, 2, 80, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 2, 13, 4, 2, 3, 6, 8, 12, 3, 2, 57, 58, 3, 2, 75, 76, 3, 2, 44, 45, 4, 2, 52, 52, 72, 72, 7, 2, 26, 30, 46, 46, 48, 49, 59, 59, 72, 72, 4, 2, 49, 49, 72, 72, 3, 2, 25, 30, 3, 2, 32, 35, 3, 2, 60, 61, 3, 2, 42, 43, 2, 760, 2, 161, 3, 2, 2, 2, 4, 178, 3, 2, 2, 2, 6, 180, 3, 2, 2, 2, 8, 185, 3, 2, 2, 2, 10, 198, 3, 2, 2, 2, 12, 212, 3, 2, 2, 2, 14, 226, 3, 2, 2, 2, 16, 244, 3, 2, 2, 2, 18, 256, 3, 2, 2, 2, 20, 260, 3, 2, 2, 2, 22, 262, 3, 2, 2, 2, 24, 280, 3, 2, 2, 2, 26, 285, 3, 2, 2, 2, 28, 287, 3, 2, 2, 2, 30, 298, 3, 2, 2, 2, 32, 300, 3, 2, 2, 2, 34, 317, 3, 2, 2, 2, 36, 322, 3, 2, 2, 2, 38, 324, 3, 2, 2, 2, 40, 341, 3, 2, 2, 2, 42, 347, 3, 2, 2, 2, 44, 349, 3, 2, 2, 2, 46, 360, 3, 2, 2, 2, 48, 362, 3, 2, 2, 2, 50, 366, 3, 2, 2, 2, 52, 373, 3, 2, 2, 2, 54, 392, 3, 2, 2, 2, 56, 397, 3, 2, 2, 2, 58, 399, 3, 2, 2, 2, 60, 402, 3, 2, 2, 2, 62, 405, 3, 2, 2, 2, 64, 408, 3, 2, 2, 2, 66, 411, 3, 2, 2, 2, 68, 414, 3, 2, 2, 2, 70, 417, 3, 2, 2, 2, 72, 420, 3, 2, 2, 2, 74, 423, 3, 2, 2, 2, 76, 426, 3, 2, 2, 2, 78, 429, 3, 2, 2, 2, 80, 432, 3, 2, 2, 2, 82, 441, 3, 2, 2, 2, 84, 455, 3, 2, 2, 2, 86, 462, 3, 2, 2, 2, 88, 469, 3, 2, 2, 2, 90, 480, 3, 2, 2, 2, 92, 491, 3, 2, 2, 2, 94, 504, 3, 2, 2, 2, 96, 512, 3, 2, 2, 2, 98, 522, 3, 2, 2, 2, 100, 534, 3, 2, 2, 2, 102, 538, 3, 2, 2, 2, 104, 561, 3, 2, 2, 2, 106, 564, 3, 2, 2, 2, 108, 586, 3, 2, 2, 2, 110, 588, 3, 2, 2, 2, 112, 594, 3, 2, 2, 2, 114, 607, 3, 2, 2, 2, 116, 610, 3, 2, 2, 2, 118, 619, 3, 2, 2, 2, 120, 623, 3, 2, 2, 2, 122, 628, 3, 2, 2, 2, 124, 635, 3, 2, 2, 2, 126, 637, 3, 2, 2, 2, 128, 639, 3, 2, 2, 2, 130, 641, 3, 2, 2, 2, 132, 643, 3, 2, 2, 2, 134, 645, 3, 2, 2, 2, 136, 659, 3, 2, 2, 2, 138, 661, 3, 2, 2, 2, 140, 673, 3, 2, 2, 2, 142, 677, 3, 2, 2, 2, 144, 689, 3, 2, 2, 2, 146, 694, 3, 2, 2, 2, 148, 698, 3, 2, 2, 2, 150, 702, 3, 2, 2, 2, 152, 706, 3, 2, 2, 2, 154, 708, 3, 2, 2, 2, 156, 712, 3, 2, 2, 2, 158, 160, 5, 4, 3, 2, 159, 158, 3, 2, 2, 2, 160, 163, 3, 2, 2, 2, 161, 159, 3, 2, 2, 2, 161, 162, 3, 2, 2, 2, 162, 164, 3, 2, 2, 2, 163, 161, 3, 2, 2, 2, 164, 165, 7, 2, 2, 3, 165, 3, 3, 2, 2, 2, 166, 179, 5, 6, 4, 2, 167, 179, 5, 8, 5, 2, 168, 179, 5, 10, 6, 2, 169, 179, 5, 28, 15, 2, 170, 179, 5, 22, 12, 2, 171, 179, 5, 32, 17, 2, 172, 179, 5, 38, 20, 2, 173, 179, 5, 44, 23, 2, 174, 179, 5, 48, 25, 2, 175, 179, 5, 52, 27, 2, 176, 179, 5, 12, 7, 2, 177, 179, 5, 14, 8, 2, 178, 166, 3, 2, 2, 2, 178, 167, 3, 2, 2, 2, 178, 168, 3, 2, 2, 2, 178, 169, 3, 2, 2, 2, 178, 170, 3, 2, 2, 2, 178, 171, 3, 2, 2, 2, 178, 172, 3, 2, 2, 2, 178, 173, 3, 2, 2, 2, 178, 174, 3, 2, 2, 2, 178, 175, 3, 2, 2, 2, 178, 176, 3, 2, 2, 2, 178, 177, 3, 2, 2, 2, 179, 5, 3, 2, 2, 2, 180, 181, 7, 3, 2, 2, 181, 182, 7, 72, 2, 2, 182, 183, 7, 52, 2, 2, 183, 184, 7, 72, 2, 2, 184, 7, 3, 2, 2, 2, 185, 186, 7, 4, 2, 2, 186, 188, 5, 126, 64, 2, 187, 189, 5, 16, 9, 2, 188, 187, 3, 2, 2, 2, 189, 190, 3, 2, 2, 2, 190, 188, 3, 2, 2, 2, 190, 191, 3, 2, 2, 2, 191, 195, 3, 2, 2, 2, 192, 194, 5, 18, 10, 2, 193, 192, 3, 2, 2, 2, 194, 197, 3, 2, 2, 2, 195, 193, 3, 2, 2, 2, 195, 196, 3, 2, 2, 2, 196, 9, 3, 2, 2, 2, 197, 195, 3, 2, 2, 2, 198, 199, 7, 5, 2, 2, 199, 203, 5, 126, 64, 2, 200, 202, 5, 16, 9, 2, 201, 200, 3, 2, 2, 2, 202, 205, 3, 2, 2, 2, 203, 201, 3, 2, 2, 2, 203, 204, 3, 2, 2, 2, 204, 209, 3, 2, 2, 2, 205, 203, 3, 2, 2, 2, 206, 208, 5, 18, 10, 2, 207, 206, 3, 2, 2, 2, 208, 211, 3, 2, 2, 2, 209, 207, 3, 2, 2, 2, 209, 210, 3, 2, 2, 2, 210, 11, 3, 2, 2, 2, 211, 209, 3, 2, 2, 2, 212, 213, 7, 13, 2, 2, 213, 217, 5, 126, 64, 2, 214, 216, 5, 16, 9, 2, 215, 214, 3, 2, 2, 2, 216, 219, 3, 2, 2, 2, 217, 215, 3, 2, 2, 2, 217, 218, 3, 2, 2, 2, 218, 223, 3, 2, 2, 2, 219, 217, 3, 2, 2, 2, 220, 222, 5, 20, 11, 2, 221, 220, 3, 2, 2, 2, 222, 225, 3, 2, 2, 2, 223, 221, 3, 2, 2, 2, 223, 224, 3, 2, 2, 2, 224, 13, 3, 2, 2, 2, 225, 223, 3, 2, 2, 2, 226, 227, 7, 14, 2, 2, 227, 231, 5, 126, 64, 2, 228, 230, 5, 16, 9, 2, 229, 228, 3, 2, 2, 2, 230, 233, 3, 2, 2, 2, 231, 229, 3, 2, 2, 2, 231, 232, 3, 2, 2, 2, 232, 237, 3, 2, 2, 2, 233, 231, 3, 2, 2, 2, 234, 236, 5, 20, 11, 2, 235, 234, 3, 2, 2, 2, 236, 239, 3, 2, 2, 2, 237, 235, 3, 2, 2, 2, 237, 238, 3, 2, 2, 2, 238, 15, 3, 2, 2, 2, 239, 237, 3, 2, 2, 2, 240, 245, 5, 58, 30, 2, 241, 245, 5, 60, 31, 2, 242, 245, 5, 62, 32, 2, 243, 245, 5, 64, 33, 2, 244, 240, 3, 2, 2, 2, 244, 241, 3, 2, 2, 2, 244, 242, 3, 2, 2, 2, 244, 243, 3, 2, 2, 2, 245, 17, 3, 2, 2, 2, 246, 257, 5, 80, 41, 2, 247, 257, 5, 82, 42, 2, 248, 257, 5, 84, 43, 2, 249, 257, 5, 86, 44, 2, 250, 257, 5, 88, 45, 2, 251, 257, 5, 90, 46, 2, 252, 257, 5, 92, 47, 2, 253, 257, 5, 94, 48, 2, 254, 257, 5, 100, 51, 2, 255, 257, 5, 104, 53, 2, 256, 246, 3, 2, 2, 2, 256, 247, 3, 2, 2, 2, 256, 248, 3, 2, 2, 2, 256, 249, 3, 2, 2, 2, 256, 250, 3, 2, 2, 2, 256, 251, 3, 2, 2, 2, 256, 252, 3, 2, 2, 2, 256, 253, 3, 2, 2, 2, 256, 254, 3, 2, 2, 2, 256, 255, 3, 2, 2, 2, 257, 19, 3, 2, 2, 2, 258, 261, 5, 18, 10, 2, 259, 261, 5, 102, 52, 2, 260, 258, 3, 2, 2, 2, 260, 259, 3, 2, 2, 2, 261, 21, 3, 2, 2, 2, 262, 263, 7, 6, 2, 2, 263, 267, 5, 126, 64, 2, 264, 266, 5, 24, 13, 2, 265, 264, 3, 2, 2, 2, 266, 269, 3, 2, 2, 2, 267, 265, 3, 2, 2, 2, 267, 268, 3, 2, 2, 2, 268, 273, 3, 2, 2, 2, 269, 267, 3, 2, 2, 2, 270, 272, 5, 26, 14, 2, 271, 270, 3, 2, 2, 2, 272, 275, 3, 2, 2, 2, 273, 271, 3, 2, 2, 2, 273, 274, 3, 2, 2, 2, 274, 23, 3, 2, 2, 2, 275, 273, 3, 2, 2, 2, 276, 281, 5, 72, 37, 2, 277, 281, 5, 62, 32, 2, 278, 281, 5, 64, 33, 2, 279, 281, 5, 74, 38, 2, 280, 276, 3, 2, 2, 2, 280, 277, 3, 2, 2, 2, 280, 278, 3, 2, 2, 2, 280, 279, 3, 2, 2, 2, 281, 25, 3, 2, 2, 2, 282, 286, 5, 86, 44, 2, 283, 286, 5, 100, 51, 2, 284, 286, 5, 104, 53, 2, 285, 282, 3, 2, 2, 2, 285, 283, 3, 2, 2, 2, 285, 284, 3, 2, 2, 2, 286, 27, 3, 2, 2, 2, 287, 288, 7, 8, 2, 2, 288, 290, 5, 126, 64, 2, 289, 291, 5, 30, 16, 2, 290, 289, 3, 2, 2, 2, 291, 292, 3, 2, 2, 2, 292, 290, 3, 2, 2, 2, 292, 293, 3, 2, 2, 2, 293, 29, 3, 2, 2, 2, 294, 299, 5, 64, 33, 2, 295, 299, 5, 66, 34, 2, 296, 299, 5, 68, 35, 2, 297, 299, 5, 70, 36, 2, 298, 294, 3, 2, 2, 2, 298, 295, 3, 2, 2, 2, 298, 296, 3, 2, 2, 2, 298, 297, 3, 2, 2, 2, 299, 31, 3, 2, 2, 2, 300, 301, 7, 9, 2, 2, 301, 305, 5, 126, 64, 2, 302, 304, 5, 34, 18, 2, 303, 302, 3, 2, 2, 2, 304, 307, 3, 2, 2, 2, 305, 303, 3, 2, 2, 2, 305, 306, 3, 2, 2, 2, 306, 311, 3, 2, 2, 2, 307, 305, 3, 2, 2, 2, 308, 310, 5, 36, 19, 2, 309, 308, 3, 2, 2, 2, 310, 313, 3, 2, 2, 2, 311, 309, 3, 2, 2, 2, 311, 312, 3, 2, 2, 2, 312, 33, 3, 2, 2, 2, 313, 311, 3, 2, 2, 2, 314, 318, 5, 60, 31, 2, 315, 318, 5, 62, 32, 2, 316, 318, 5, 64, 33, 2, 317, 314, 3, 2, 2, 2, 317, 315, 3, 2, 2, 2, 317, 316, 3, 2, 2, 2, 318, 35, 3, 2, 2, 2, 319, 323, 5, 106, 54, 2, 320, 323, 5, 94, 48, 2, 321, 323, 5, 100, 51, 2, 322, 319, 3, 2, 2, 2, 322, 320, 3, 2, 2, 2, 322, 321, 3, 2, 2, 2, 323, 37, 3, 2, 2, 2, 324, 325, 7, 10, 2, 2, 325, 329, 5, 126, 64, 2, 326, 328, 5, 40, 21, 2, 327, 326, 3, 2, 2, 2, 328, 331, 3, 2, 2, 2, 329, 327, 3, 2, 2, 2, 329, 330, 3, 2, 2, 2, 330, 335, 3, 2, 2, 2, 331, 329, 3, 2, 2, 2, 332, 334, 5, 42, 22, 2, 333, 332, 3, 2, 2, 2, 334, 337, 3, 2, 2, 2, 335, 333, 3, 2, 2, 2, 335, 336, 3, 2, 2, 2, 336, 39, 3, 2, 2, 2, 337, 335, 3, 2, 2, 2, 338, 342, 5, 60, 31, 2, 339, 342, 5, 62, 32, 2, 340, 342, 5, 64, 33, 2, 341, 338, 3, 2, 2, 2, 341, 339, 3, 2, 2, 2, 341, 340, 3, 2, 2, 2, 342, 41, 3, 2, 2, 2, 343, 348, 5, 142, 72, 2, 344, 348, 5, 94, 48, 2, 345, 348, 5, 96, 49, 2, 346, 348, 5, 100, 51, 2, 347, 343, 3, 2, 2, 2, 347, 344, 3, 2, 2, 2, 347, 345, 3, 2, 2, 2, 347, 346, 3, 2, 2, 2, 348, 43, 3, 2, 2, 2, 349, 350, 7, 11, 2, 2, 350, 352, 7, 76, 2, 2, 351, 353, 5, 46, 24, 2, 352, 351, 3, 2, 2, 2, 353, 354, 3, 2, 2, 2, 354, 352, 3, 2, 2, 2, 354, 355, 3, 2, 2, 2, 355, 45, 3, 2, 2, 2, 356, 361, 5, 18, 10, 2, 357, 361, 5, 142, 72, 2, 358, 361, 5, 96, 49, 2, 359, 361, 5, 106, 54, 2, 360, 356, 3, 2, 2, 2, 360, 357, 3, 2, 2, 2, 360, 358, 3, 2, 2, 2, 360, 359, 3, 2, 2, 2, 361, 47, 3, 2, 2, 2, 362, 363, 7, 11, 2, 2, 363, 364, 7, 75, 2, 2, 364, 365, 5, 50, 26, 2, 365, 49, 3, 2, 2, 2, 366, 370, 7, 53, 2, 2, 367, 369, 10, 2, 2, 2, 368, 367, 3, 2, 2, 2, 369, 372, 3, 2, 2, 2, 370, 368, 3, 2, 2, 2, 370, 371, 3, 2, 2, 2, 371, 51, 3, 2, 2, 2, 372, 370, 3, 2, 2, 2, 373, 374, 7, 12, 2, 2, 374, 378, 5, 126, 64, 2, 375, 377, 5, 54, 28, 2, 376, 375, 3, 2, 2, 2, 377, 380, 3, 2, 2, 2, 378, 376, 3, 2, 2, 2, 378, 379, 3, 2, 2, 2, 379, 384, 3, 2, 2, 2, 380, 378, 3, 2, 2, 2, 381, 383, 5, 56, 29, 2, 382, 381, 3, 2, 2, 2, 383, 386, 3, 2, 2, 2, 384, 382, 3, 2, 2, 2, 384, 385, 3, 2, 2, 2, 385, 53, 3, 2, 2, 2, 386, 384, 3, 2, 2, 2, 387, 393, 5, 60, 31, 2, 388, 393, 5, 76, 39, 2, 389, 393, 5, 78, 40, 2, 390, 393, 5, 64, 33, 2, 391, 393, 5, 62, 32, 2, 392, 387, 3, 2, 2, 2, 392, 388, 3, 2, 2, 2, 392, 389, 3, 2, 2, 2, 392, 390, 3, 2, 2, 2, 392, 391, 3, 2, 2, 2, 393, 55, 3, 2, 2, 2, 394, 398, 5, 98, 50, 2, 395, 398, 5, 100, 51, 2, 396, 398, 5, 104, 53, 2, 397, 394, 3, 2, 2, 2, 397, 395, 3, 2, 2, 2, 397, 396, 3, 2, 2, 2, 398, 57, 3, 2, 2, 2, 399, 400, 7, 15, 2, 2, 400, 401, 5, 126, 64, 2, 401, 59, 3, 2, 2, 2, 402, 403, 7, 16, 2, 2, 403, 404, 5, 126, 64, 2, 404, 61, 3, 2, 2, 2, 405, 406, 7, 17, 2, 2, 406, 407, 7, 57, 2, 2, 407, 63, 3, 2, 2, 2, 408, 409, 7, 18, 2, 2, 409, 410, 9, 3, 2, 2, 410, 65, 3, 2, 2, 2, 411, 412, 7, 19, 2, 2, 412, 413, 7, 57, 2, 2, 413, 67, 3, 2, 2, 2, 414, 415, 7, 20, 2, 2, 415, 416, 7, 57, 2, 2, 416, 69, 3, 2, 2, 2, 417, 418, 7, 21, 2, 2, 418, 419, 7, 61, 2, 2, 419, 71, 3, 2, 2, 2, 420, 421, 7, 7, 2, 2, 421, 422, 5, 126, 64, 2, 422, 73, 3, 2, 2, 2, 423, 424, 7, 22, 2, 2, 424, 425, 7, 61, 2, 2, 425, 75, 3, 2, 2, 2, 426, 427, 7, 23, 2, 2, 427, 428, 5, 126, 64, 2, 428, 77, 3, 2, 2, 2, 429, 430, 7, 24, 2, 2, 430, 431, 7, 57, 2, 2, 431, 79, 3, 2, 2, 2, 432, 433, 7, 53, 2, 2, 433, 434, 5, 128, 65, 2, 434, 438, 7, 65, 2, 2, 435, 437, 5, 132, 67, 2, 436, 435, 3, 2, 2, 2, 437, 440, 3, 2, 2, 2, 438, 436, 3, 2, 2, 2, 438, 439, 3, 2, 2, 2, 439, 81, 3, 2, 2, 2, 440, 438, 3, 2, 2, 2, 441, 442, 7, 53, 2, 2, 442, 447, 5, 128, 65, 2, 443, 444, 7, 38, 2, 2, 444, 446, 5, 128, 65, 2, 445, 443, 3, 2, 2, 2, 446, 449, 3, 2, 2, 2, 447, 445, 3, 2, 2, 2, 447, 448, 3, 2, 2, 2, 448, 451, 3, 2, 2, 2, 449, 447, 3, 2, 2, 2, 450, 452, 5, 132, 67, 2, 451, 450, 3, 2, 2, 2, 452, 453, 3, 2, 2, 2, 453, 451, 3, 2, 2, 2, 453, 454, 3, 2, 2, 2, 454, 83, 3, 2, 2, 2, 455, 456, 7, 53, 2, 2, 456, 457, 5, 128, 65, 2, 457, 458, 7, 31, 2, 2, 458, 460, 5, 126, 64, 2, 459, 461, 5, 134, 68, 2, 460, 459, 3, 2, 2, 2, 460, 461, 3, 2, 2, 2, 461, 85, 3, 2, 2, 2, 462, 463, 7, 53, 2, 2, 463, 464, 5, 128, 65, 2, 464, 465, 7, 52, 2, 2, 465, 467, 5, 136, 69, 2, 466, 468, 7, 50, 2, 2, 467, 466, 3, 2, 2, 2, 467, 468, 3, 2, 2, 2, 468, 87, 3, 2, 2, 2, 469, 470, 7, 53, 2, 2, 470, 471, 5, 128, 65, 2, 471, 472, 7, 36, 2, 2, 472, 477, 5, 138, 70, 2, 473, 474, 7, 38, 2, 2, 474, 476, 5, 138, 70, 2, 475, 473, 3, 2, 2, 2, 476, 479, 3, 2, 2, 2, 477, 475, 3, 2, 2, 2, 477, 478, 3, 2, 2, 2, 478, 89, 3, 2, 2, 2, 479, 477, 3, 2, 2, 2, 480, 481, 7, 53, 2, 2, 481, 482, 5, 128, 65, 2, 482, 483, 7, 39, 2, 2, 483, 488, 5, 156, 79, 2, 484, 485, 7, 40, 2, 2, 485, 487, 5, 156, 79, 2, 486, 484, 3, 2, 2, 2, 487, 490, 3, 2, 2, 2, 488, 486, 3, 2, 2, 2, 488, 489, 3, 2, 2, 2, 489, 91, 3, 2, 2, 2, 490, 488, 3, 2, 2, 2, 491, 493, 7, 53, 2, 2, 492, 494, 5, 128, 65, 2, 493, 492, 3, 2, 2, 2, 493, 494, 3, 2, 2, 2, 494, 495, 3, 2, 2, 2, 495, 496, 7, 41, 2, 2, 496, 501, 5, 126, 64, 2, 497, 498, 7, 38, 2, 2, 498, 500, 5, 126, 64, 2, 499, 497, 3, 2, 2, 2, 500, 503, 3, 2, 2, 2, 501, 499, 3, 2, 2, 2, 501, 502, 3, 2, 2, 2, 502, 93, 3, 2, 2, 2, 503, 501, 3, 2, 2, 2, 504, 506, 7, 53, 2, 2, 505, 507, 5, 128, 65, 2, 506, 505, 3, 2, 2, 2, 506, 507, 3, 2, 2, 2, 507, 508, 3, 2, 2, 2, 508, 509, 5, 130, 66, 2, 509, 510, 7, 52, 2, 2, 510, 511, 5, 136, 69, 2, 511, 95, 3, 2, 2, 2, 512, 514, 7, 53, 2, 2, 513, 515, 7, 61, 2, 2, 514, 513, 3, 2, 2, 2, 515, 516, 3, 2, 2, 2, 516, 514, 3, 2, 2, 2, 516, 517, 3, 2, 2, 2, 517, 518, 3, 2, 2, 2, 518, 519, 5, 130, 66, 2, 519, 520, 7, 52, 2, 2, 520, 521, 5, 136, 69, 2, 521, 97, 3, 2, 2, 2, 522, 524, 7, 53, 2, 2, 523, 525, 5, 128, 65, 2, 524, 523, 3, 2, 2, 2, 524, 525, 3, 2, 2, 2, 525, 526, 3, 2, 2, 2, 526, 527, 7, 56, 2, 2, 527, 529, 7, 57, 2, 2, 528, 530, 7, 57, 2, 2, 529, 528, 3, 2, 2, 2, 529, 530, 3, 2, 2, 2, 530, 532, 3, 2, 2, 2, 531, 533, 7, 61, 2, 2, 532, 531, 3, 2, 2, 2, 532, 533, 3, 2, 2, 2, 533, 99, 3, 2, 2, 2, 534, 535, 7, 53, 2, 2, 535, 536, 7, 51, 2, 2, 536, 537, 9, 4, 2, 2, 537, 101, 3, 2, 2, 2, 538, 539, 7, 53, 2, 2, 539, 540, 5, 128, 65, 2, 540, 544, 7, 65, 2, 2, 541, 543, 5, 132, 67, 2, 542, 541, 3, 2, 2, 2, 543, 546, 3, 2, 2, 2, 544, 542, 3, 2, 2, 2, 544, 545, 3, 2, 2, 2, 545, 547, 3, 2, 2, 2, 546, 544, 3, 2, 2, 2, 547, 552, 5, 156, 79, 2, 548, 549, 7, 40, 2, 2, 549, 551, 5, 156, 79, 2, 550, 548, 3, 2, 2, 2, 551, 554, 3, 2, 2, 2, 552, 550, 3, 2, 2, 2, 552, 553, 3, 2, 2, 2, 553, 556, 3, 2, 2, 2, 554, 552, 3, 2, 2, 2, 555, 557, 7, 57, 2, 2, 556, 555, 3, 2, 2, 2, 556, 557, 3, 2, 2, 2, 557, 559, 3, 2, 2, 2, 558, 560, 7, 57, 2, 2, 559, 558, 3, 2, 2, 2, 559, 560, 3, 2, 2, 2, 560, 103, 3, 2, 2, 2, 561, 562, 7, 53, 2, 2, 562, 563, 5, 128, 65, 2, 563, 105, 3, 2, 2, 2, 564, 566, 7, 53, 2, 2, 565, 567, 9, 5, 2, 2, 566, 565, 3, 2, 2, 2, 566, 567, 3, 2, 2, 2, 567, 570, 3, 2, 2, 2, 568, 571, 5, 108, 55, 2, 569, 571, 5, 110, 56, 2, 570, 568, 3, 2, 2, 2, 570, 569, 3, 2, 2, 2, 571, 107, 3, 2, 2, 2, 572, 574, 5, 140, 71, 2, 573, 575, 5, 112, 57, 2, 574, 573, 3, 2, 2, 2, 574, 575, 3, 2, 2, 2, 575, 587, 3, 2, 2, 2, 576, 577, 5, 140, 71, 2, 577, 578, 7, 38, 2, 2, 578, 580, 3, 2, 2, 2, 579, 576, 3, 2, 2, 2, 580, 581, 3, 2, 2, 2, 581, 579, 3, 2, 2, 2, 581, 582, 3, 2, 2, 2, 582, 583, 3, 2, 2, 2, 583, 584, 5, 140, 71, 2, 584, 585, 5, 112, 57, 2, 585, 587, 3, 2, 2, 2, 586, 572, 3, 2, 2, 2, 586, 579, 3, 2, 2, 2, 587, 109, 3, 2, 2, 2, 588, 589, 7, 46, 2, 2, 589, 592, 5, 112, 57, 2, 590, 591, 7, 47, 2, 2, 591, 593, 5, 118, 60, 2, 592, 590, 3, 2, 2, 2, 592, 593, 3, 2, 2, 2, 593, 111, 3, 2, 2, 2, 594, 605, 7, 31, 2, 2, 595, 598, 5, 114, 58, 2, 596, 597, 7, 38, 2, 2, 597, 599, 5, 116, 59, 2, 598, 596, 3, 2, 2, 2, 598, 599, 3, 2, 2, 2, 599, 606, 3, 2, 2, 2, 600, 603, 5, 116, 59, 2, 601, 602, 7, 38, 2, 2, 602, 604, 5, 114, 58, 2, 603, 601, 3, 2, 2, 2, 603, 604, 3, 2, 2, 2, 604, 606, 3, 2, 2, 2, 605, 595, 3, 2, 2, 2, 605, 600, 3, 2, 2, 2, 606, 113, 3, 2, 2, 2, 607, 608, 7, 49, 2, 2, 608, 609, 5, 126, 64, 2, 609, 115, 3, 2, 2, 2, 610, 611, 7, 48, 2, 2, 611, 616, 5, 126, 64, 2, 612, 613, 7, 38, 2, 2, 613, 615, 5, 126, 64, 2, 614, 612, 3, 2, 2, 2, 615, 618, 3, 2, 2, 2, 616, 614, 3, 2, 2, 2, 616, 617, 3, 2, 2, 2, 617, 117, 3, 2, 2, 2, 618, 616, 3, 2, 2, 2, 619, 620, 5, 120, 61, 2, 620, 621, 7, 38, 2, 2, 621, 622, 5, 120, 61, 2, 622, 119, 3, 2, 2, 2, 623, 624, 5, 126, 64, 2, 624, 626, 5, 122, 62, 2, 625, 627, 5, 124, 63, 2, 626, 625, 3, 2, 2, 2, 626, 627, 3, 2, 2, 2, 627, 121, 3, 2, 2, 2, 628, 629, 9, 6, 2, 2, 629, 123, 3, 2, 2, 2, 630, 636, 5, 140, 71, 2, 631, 636, 7, 42, 2, 2, 632, 636, 7, 43, 2, 2, 633, 636, 7, 69, 2, 2, 634, 636, 7, 57, 2, 2, 635, 630, 3, 2, 2, 2, 635, 631, 3, 2, 2, 2, 635, 632, 3, 2, 2, 2, 635, 633, 3, 2, 2, 2, 635, 634, 3, 2, 2, 2, 636, 125, 3, 2, 2, 2, 637, 638, 9, 7, 2, 2, 638, 127, 3, 2, 2, 2, 639, 640, 9, 8, 2, 2, 640, 129, 3, 2, 2, 2, 641, 642, 7, 68, 2, 2, 642, 131, 3, 2, 2, 2, 643, 644, 9, 9, 2, 2, 644, 133, 3, 2, 2, 2, 645, 646, 9, 10, 2, 2, 646, 135, 3, 2, 2, 2, 647, 660, 7, 57, 2, 2, 648, 660, 7, 58, 2, 2, 649, 660, 7, 59, 2, 2, 650, 660, 7, 63, 2, 2, 651, 660, 7, 64, 2, 2, 652, 660, 5, 148, 75, 2, 653, 660, 5, 150, 76, 2, 654, 660, 5, 140, 71, 2, 655, 660, 5, 144, 73, 2, 656, 660, 5, 146, 74, 2, 657, 660, 5, 154, 78, 2, 658, 660, 5, 126, 64, 2, 659, 647, 3, 2, 2, 2, 659, 648, 3, 2, 2, 2, 659, 649, 3, 2, 2, 2, 659, 650, 3, 2, 2, 2, 659, 651, 3, 2, 2, 2, 659, 652, 3, 2, 2, 2, 659, 653, 3, 2, 2, 2, 659, 654, 3, 2, 2, 2, 659, 655, 3, 2, 2, 2, 659, 656, 3, 2, 2, 2, 659, 657, 3, 2, 2, 2, 659, 658, 3, 2, 2, 2, 660, 137, 3, 2, 2, 2, 661, 664, 5, 126, 64, 2, 662, 663, 7, 37, 2, 2, 663, 665, 5, 126, 64, 2, 664, 662, 3, 2, 2, 2, 664, 665, 3, 2, 2, 2, 665, 666, 3, 2, 2, 2, 666, 670, 7, 65, 2, 2, 667, 669, 5, 132, 67, 2, 668, 667, 3, 2, 2, 2, 669, 672, 3, 2, 2, 2, 670, 668, 3, 2, 2, 2, 670, 671, 3, 2, 2, 2, 671, 139, 3, 2, 2, 2, 672, 670, 3, 2, 2, 2, 673, 675, 7, 61, 2, 2, 674, 676, 7, 57, 2, 2, 675, 674, 3, 2, 2, 2, 675, 676, 3, 2, 2, 2, 676, 141, 3, 2, 2, 2, 677, 679, 7, 53, 2, 2, 678, 680, 7, 61, 2, 2, 679, 678, 3, 2, 2, 2, 680, 681, 3, 2, 2, 2, 681, 679, 3, 2, 2, 2, 681, 682, 3, 2, 2, 2, 682, 684, 3, 2, 2, 2, 683, 685, 7, 57, 2, 2, 684, 683, 3, 2, 2, 2, 684, 685, 3, 2, 2, 2, 685, 687, 3, 2, 2, 2, 686, 688, 9, 3, 2, 2, 687, 686, 3, 2, 2, 2, 687, 688, 3, 2, 2, 2, 688, 143, 3, 2, 2, 2, 689, 690, 7, 59, 2, 2, 690, 692, 9, 11, 2, 2, 691, 693, 7, 57, 2, 2, 692, 691, 3, 2, 2, 2, 692, 693, 3, 2, 2, 2, 693, 145, 3, 2, 2, 2, 694, 695, 5, 152, 77, 2, 695, 696, 7, 54, 2, 2, 696, 697, 5, 152, 77, 2, 697, 147, 3, 2, 2, 2, 698, 700, 7, 66, 2, 2, 699, 701, 7, 57, 2, 2, 700, 699, 3, 2, 2, 2, 700, 701, 3, 2, 2, 2, 701, 149, 3, 2, 2, 2, 702, 703, 7, 67, 2, 2, 703, 151, 3, 2, 2, 2, 704, 707, 7, 59, 2, 2, 705, 707, 5, 144, 73, 2, 706, 704, 3, 2, 2, 2, 706, 705, 3, 2, 2, 2, 707, 153, 3, 2, 2, 2, 708, 709, 9, 12, 2, 2, 709, 155, 3, 2, 2, 2, 710, 713, 5, 126, 64, 2, 711, 713, 5, 148, 75, 2, 712, 710, 3, 2, 2, 2, 712, 711, 3, 2, 2, 2, 713, 157, 3, 2, 2, 2, 77, 161, 178, 190, 195, 203, 209, 217, 223, 231, 237, 244, 256, 260, 267, 273, 280, 285, 292, 298, 305, 311, 317, 322, 329, 335, 341, 347, 354, 360, 370, 378, 384, 392, 397, 438, 447, 453, 460, 467, 477, 488, 493, 501, 506, 516, 524, 529, 532, 544, 552, 556, 559, 566, 570, 574, 581, 586, 592, 598, 603, 605, 616, 626, 635, 659, 664, 670, 675, 681, 684, 687, 692, 700, 706, 712]
\ No newline at end of file
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 76, 715, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 3, 2, 7, 2, 160, 10, 2, 12, 2, 14, 2, 163, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 179, 10, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 6, 5, 189, 10, 5, 13, 5, 14, 5, 190, 3, 5, 7, 5, 194, 10, 5, 12, 5, 14, 5, 197, 11, 5, 3, 6, 3, 6, 3, 6, 7, 6, 202, 10, 6, 12, 6, 14, 6, 205, 11, 6, 3, 6, 7, 6, 208, 10, 6, 12, 6, 14, 6, 211, 11, 6, 3, 7, 3, 7, 3, 7, 7, 7, 216, 10, 7, 12, 7, 14, 7, 219, 11, 7, 3, 7, 7, 7, 222, 10, 7, 12, 7, 14, 7, 225, 11, 7, 3, 8, 3, 8, 3, 8, 7, 8, 230, 10, 8, 12, 8, 14, 8, 233, 11, 8, 3, 8, 7, 8, 236, 10, 8, 12, 8, 14, 8, 239, 11, 8, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 245, 10, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 257, 10, 10, 3, 11, 3, 11, 5, 11, 261, 10, 11, 3, 12, 3, 12, 3, 12, 7, 12, 266, 10, 12, 12, 12, 14, 12, 269, 11, 12, 3, 12, 7, 12, 272, 10, 12, 12, 12, 14, 12, 275, 11, 12, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 281, 10, 13, 3, 14, 3, 14, 3, 14, 5, 14, 286, 10, 14, 3, 15, 3, 15, 3, 15, 6, 15, 291, 10, 15, 13, 15, 14, 15, 292, 3, 16, 3, 16, 3, 16, 3, 16, 5, 16, 299, 10, 16, 3, 17, 3, 17, 3, 17, 7, 17, 304, 10, 17, 12, 17, 14, 17, 307, 11, 17, 3, 17, 7, 17, 310, 10, 17, 12, 17, 14, 17, 313, 11, 17, 3, 18, 3, 18, 3, 18, 5, 18, 318, 10, 18, 3, 19, 3, 19, 3, 19, 5, 19, 323, 10, 19, 3, 20, 3, 20, 3, 20, 7, 20, 328, 10, 20, 12, 20, 14, 20, 331, 11, 20, 3, 20, 7, 20, 334, 10, 20, 12, 20, 14, 20, 337, 11, 20, 3, 21, 3, 21, 3, 21, 5, 21, 342, 10, 21, 3, 22, 3, 22, 3, 22, 5, 22, 347, 10, 22, 3, 23, 3, 23, 3, 23, 6, 23, 352, 10, 23, 13, 23, 14, 23, 353, 3, 24, 3, 24, 3, 24, 3, 24, 5, 24, 360, 10, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 7, 26, 368, 10, 26, 12, 26, 14, 26, 371, 11, 26, 3, 27, 3, 27, 3, 27, 7, 27, 376, 10, 27, 12, 27, 14, 27, 379, 11, 27, 3, 27, 7, 27, 382, 10, 27, 12, 27, 14, 27, 385, 11, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 392, 10, 28, 3, 29, 3, 29, 3, 29, 5, 29, 397, 10, 29, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 7, 41, 436, 10, 41, 12, 41, 14, 41, 439, 11, 41, 3, 42, 3, 42, 3, 42, 3, 42, 7, 42, 445, 10, 42, 12, 42, 14, 42, 448, 11, 42, 3, 42, 6, 42, 451, 10, 42, 13, 42, 14, 42, 452, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 5, 43, 460, 10, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 5, 44, 467, 10, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 7, 45, 475, 10, 45, 12, 45, 14, 45, 478, 11, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 486, 10, 46, 12, 46, 14, 46, 489, 11, 46, 3, 47, 3, 47, 5, 47, 493, 10, 47, 3, 47, 3, 47, 3, 47, 3, 47, 7, 47, 499, 10, 47, 12, 47, 14, 47, 502, 11, 47, 3, 48, 3, 48, 5, 48, 506, 10, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 7, 49, 514, 10, 49, 12, 49, 14, 49, 517, 11, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 5, 50, 525, 10, 50, 3, 50, 3, 50, 3, 50, 5, 50, 530, 10, 50, 3, 50, 5, 50, 533, 10, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 7, 52, 543, 10, 52, 12, 52, 14, 52, 546, 11, 52, 3, 52, 3, 52, 3, 52, 7, 52, 551, 10, 52, 12, 52, 14, 52, 554, 11, 52, 3, 52, 5, 52, 557, 10, 52, 3, 52, 5, 52, 560, 10, 52, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 5, 54, 567, 10, 54, 3, 54, 3, 54, 5, 54, 571, 10, 54, 3, 55, 3, 55, 5, 55, 575, 10, 55, 3, 55, 3, 55, 3, 55, 6, 55, 580, 10, 55, 13, 55, 14, 55, 581, 3, 55, 3, 55, 3, 55, 5, 55, 587, 10, 55, 3, 56, 3, 56, 3, 56, 3, 56, 5, 56, 593, 10, 56, 3, 57, 3, 57, 3, 57, 3, 57, 5, 57, 599, 10, 57, 3, 57, 3, 57, 3, 57, 5, 57, 604, 10, 57, 5, 57, 606, 10, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 7, 59, 615, 10, 59, 12, 59, 14, 59, 618, 11, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 5, 61, 627, 10, 61, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 5, 63, 636, 10, 63, 3, 64, 3, 64, 3, 65, 3, 65, 3, 66, 3, 66, 3, 67, 3, 67, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 5, 69, 660, 10, 69, 3, 70, 3, 70, 3, 70, 5, 70, 665, 10, 70, 3, 70, 3, 70, 7, 70, 669, 10, 70, 12, 70, 14, 70, 672, 11, 70, 3, 71, 3, 71, 5, 71, 676, 10, 71, 3, 72, 3, 72, 6, 72, 680, 10, 72, 13, 72, 14, 72, 681, 3, 72, 5, 72, 685, 10, 72, 3, 72, 5, 72, 688, 10, 72, 3, 73, 3, 73, 3, 73, 5, 73, 693, 10, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 5, 75, 701, 10, 75, 3, 76, 3, 76, 3, 77, 3, 77, 5, 77, 707, 10, 77, 3, 78, 3, 78, 3, 79, 3, 79, 5, 79, 713, 10, 79, 3, 79, 2, 2, 80, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 2, 13, 4, 2, 3, 6, 8, 12, 3, 2, 57, 58, 3, 2, 75, 76, 3, 2, 44, 45, 4, 2, 52, 52, 72, 72, 7, 2, 26, 30, 46, 46, 48, 49, 59, 59, 72, 72, 4, 2, 49, 49, 72, 72, 3, 2, 25, 30, 3, 2, 32, 35, 3, 2, 60, 61, 3, 2, 42, 43, 2, 759, 2, 161, 3, 2, 2, 2, 4, 178, 3, 2, 2, 2, 6, 180, 3, 2, 2, 2, 8, 185, 3, 2, 2, 2, 10, 198, 3, 2, 2, 2, 12, 212, 3, 2, 2, 2, 14, 226, 3, 2, 2, 2, 16, 244, 3, 2, 2, 2, 18, 256, 3, 2, 2, 2, 20, 260, 3, 2, 2, 2, 22, 262, 3, 2, 2, 2, 24, 280, 3, 2, 2, 2, 26, 285, 3, 2, 2, 2, 28, 287, 3, 2, 2, 2, 30, 298, 3, 2, 2, 2, 32, 300, 3, 2, 2, 2, 34, 317, 3, 2, 2, 2, 36, 322, 3, 2, 2, 2, 38, 324, 3, 2, 2, 2, 40, 341, 3, 2, 2, 2, 42, 346, 3, 2, 2, 2, 44, 348, 3, 2, 2, 2, 46, 359, 3, 2, 2, 2, 48, 361, 3, 2, 2, 2, 50, 365, 3, 2, 2, 2, 52, 372, 3, 2, 2, 2, 54, 391, 3, 2, 2, 2, 56, 396, 3, 2, 2, 2, 58, 398, 3, 2, 2, 2, 60, 401, 3, 2, 2, 2, 62, 404, 3, 2, 2, 2, 64, 407, 3, 2, 2, 2, 66, 410, 3, 2, 2, 2, 68, 413, 3, 2, 2, 2, 70, 416, 3, 2, 2, 2, 72, 419, 3, 2, 2, 2, 74, 422, 3, 2, 2, 2, 76, 425, 3, 2, 2, 2, 78, 428, 3, 2, 2, 2, 80, 431, 3, 2, 2, 2, 82, 440, 3, 2, 2, 2, 84, 454, 3, 2, 2, 2, 86, 461, 3, 2, 2, 2, 88, 468, 3, 2, 2, 2, 90, 479, 3, 2, 2, 2, 92, 490, 3, 2, 2, 2, 94, 503, 3, 2, 2, 2, 96, 511, 3, 2, 2, 2, 98, 522, 3, 2, 2, 2, 100, 534, 3, 2, 2, 2, 102, 538, 3, 2, 2, 2, 104, 561, 3, 2, 2, 2, 106, 564, 3, 2, 2, 2, 108, 586, 3, 2, 2, 2, 110, 588, 3, 2, 2, 2, 112, 594, 3, 2, 2, 2, 114, 607, 3, 2, 2, 2, 116, 610, 3, 2, 2, 2, 118, 619, 3, 2, 2, 2, 120, 623, 3, 2, 2, 2, 122, 628, 3, 2, 2, 2, 124, 635, 3, 2, 2, 2, 126, 637, 3, 2, 2, 2, 128, 639, 3, 2, 2, 2, 130, 641, 3, 2, 2, 2, 132, 643, 3, 2, 2, 2, 134, 645, 3, 2, 2, 2, 136, 659, 3, 2, 2, 2, 138, 661, 3, 2, 2, 2, 140, 673, 3, 2, 2, 2, 142, 677, 3, 2, 2, 2, 144, 689, 3, 2, 2, 2, 146, 694, 3, 2, 2, 2, 148, 698, 3, 2, 2, 2, 150, 702, 3, 2, 2, 2, 152, 706, 3, 2, 2, 2, 154, 708, 3, 2, 2, 2, 156, 712, 3, 2, 2, 2, 158, 160, 5, 4, 3, 2, 159, 158, 3, 2, 2, 2, 160, 163, 3, 2, 2, 2, 161, 159, 3, 2, 2, 2, 161, 162, 3, 2, 2, 2, 162, 164, 3, 2, 2, 2, 163, 161, 3, 2, 2, 2, 164, 165, 7, 2, 2, 3, 165, 3, 3, 2, 2, 2, 166, 179, 5, 6, 4, 2, 167, 179, 5, 8, 5, 2, 168, 179, 5, 10, 6, 2, 169, 179, 5, 28, 15, 2, 170, 179, 5, 22, 12, 2, 171, 179, 5, 32, 17, 2, 172, 179, 5, 38, 20, 2, 173, 179, 5, 44, 23, 2, 174, 179, 5, 48, 25, 2, 175, 179, 5, 52, 27, 2, 176, 179, 5, 12, 7, 2, 177, 179, 5, 14, 8, 2, 178, 166, 3, 2, 2, 2, 178, 167, 3, 2, 2, 2, 178, 168, 3, 2, 2, 2, 178, 169, 3, 2, 2, 2, 178, 170, 3, 2, 2, 2, 178, 171, 3, 2, 2, 2, 178, 172, 3, 2, 2, 2, 178, 173, 3, 2, 2, 2, 178, 174, 3, 2, 2, 2, 178, 175, 3, 2, 2, 2, 178, 176, 3, 2, 2, 2, 178, 177, 3, 2, 2, 2, 179, 5, 3, 2, 2, 2, 180, 181, 7, 3, 2, 2, 181, 182, 7, 72, 2, 2, 182, 183, 7, 52, 2, 2, 183, 184, 7, 72, 2, 2, 184, 7, 3, 2, 2, 2, 185, 186, 7, 4, 2, 2, 186, 188, 5, 126, 64, 2, 187, 189, 5, 16, 9, 2, 188, 187, 3, 2, 2, 2, 189, 190, 3, 2, 2, 2, 190, 188, 3, 2, 2, 2, 190, 191, 3, 2, 2, 2, 191, 195, 3, 2, 2, 2, 192, 194, 5, 18, 10, 2, 193, 192, 3, 2, 2, 2, 194, 197, 3, 2, 2, 2, 195, 193, 3, 2, 2, 2, 195, 196, 3, 2, 2, 2, 196, 9, 3, 2, 2, 2, 197, 195, 3, 2, 2, 2, 198, 199, 7, 5, 2, 2, 199, 203, 5, 126, 64, 2, 200, 202, 5, 16, 9, 2, 201, 200, 3, 2, 2, 2, 202, 205, 3, 2, 2, 2, 203, 201, 3, 2, 2, 2, 203, 204, 3, 2, 2, 2, 204, 209, 3, 2, 2, 2, 205, 203, 3, 2, 2, 2, 206, 208, 5, 18, 10, 2, 207, 206, 3, 2, 2, 2, 208, 211, 3, 2, 2, 2, 209, 207, 3, 2, 2, 2, 209, 210, 3, 2, 2, 2, 210, 11, 3, 2, 2, 2, 211, 209, 3, 2, 2, 2, 212, 213, 7, 13, 2, 2, 213, 217, 5, 126, 64, 2, 214, 216, 5, 16, 9, 2, 215, 214, 3, 2, 2, 2, 216, 219, 3, 2, 2, 2, 217, 215, 3, 2, 2, 2, 217, 218, 3, 2, 2, 2, 218, 223, 3, 2, 2, 2, 219, 217, 3, 2, 2, 2, 220, 222, 5, 20, 11, 2, 221, 220, 3, 2, 2, 2, 222, 225, 3, 2, 2, 2, 223, 221, 3, 2, 2, 2, 223, 224, 3, 2, 2, 2, 224, 13, 3, 2, 2, 2, 225, 223, 3, 2, 2, 2, 226, 227, 7, 14, 2, 2, 227, 231, 5, 126, 64, 2, 228, 230, 5, 16, 9, 2, 229, 228, 3, 2, 2, 2, 230, 233, 3, 2, 2, 2, 231, 229, 3, 2, 2, 2, 231, 232, 3, 2, 2, 2, 232, 237, 3, 2, 2, 2, 233, 231, 3, 2, 2, 2, 234, 236, 5, 20, 11, 2, 235, 234, 3, 2, 2, 2, 236, 239, 3, 2, 2, 2, 237, 235, 3, 2, 2, 2, 237, 238, 3, 2, 2, 2, 238, 15, 3, 2, 2, 2, 239, 237, 3, 2, 2, 2, 240, 245, 5, 58, 30, 2, 241, 245, 5, 60, 31, 2, 242, 245, 5, 62, 32, 2, 243, 245, 5, 64, 33, 2, 244, 240, 3, 2, 2, 2, 244, 241, 3, 2, 2, 2, 244, 242, 3, 2, 2, 2, 244, 243, 3, 2, 2, 2, 245, 17, 3, 2, 2, 2, 246, 257, 5, 80, 41, 2, 247, 257, 5, 82, 42, 2, 248, 257, 5, 84, 43, 2, 249, 257, 5, 86, 44, 2, 250, 257, 5, 88, 45, 2, 251, 257, 5, 90, 46, 2, 252, 257, 5, 92, 47, 2, 253, 257, 5, 94, 48, 2, 254, 257, 5, 100, 51, 2, 255, 257, 5, 104, 53, 2, 256, 246, 3, 2, 2, 2, 256, 247, 3, 2, 2, 2, 256, 248, 3, 2, 2, 2, 256, 249, 3, 2, 2, 2, 256, 250, 3, 2, 2, 2, 256, 251, 3, 2, 2, 2, 256, 252, 3, 2, 2, 2, 256, 253, 3, 2, 2, 2, 256, 254, 3, 2, 2, 2, 256, 255, 3, 2, 2, 2, 257, 19, 3, 2, 2, 2, 258, 261, 5, 18, 10, 2, 259, 261, 5, 102, 52, 2, 260, 258, 3, 2, 2, 2, 260, 259, 3, 2, 2, 2, 261, 21, 3, 2, 2, 2, 262, 263, 7, 6, 2, 2, 263, 267, 5, 126, 64, 2, 264, 266, 5, 24, 13, 2, 265, 264, 3, 2, 2, 2, 266, 269, 3, 2, 2, 2, 267, 265, 3, 2, 2, 2, 267, 268, 3, 2, 2, 2, 268, 273, 3, 2, 2, 2, 269, 267, 3, 2, 2, 2, 270, 272, 5, 26, 14, 2, 271, 270, 3, 2, 2, 2, 272, 275, 3, 2, 2, 2, 273, 271, 3, 2, 2, 2, 273, 274, 3, 2, 2, 2, 274, 23, 3, 2, 2, 2, 275, 273, 3, 2, 2, 2, 276, 281, 5, 72, 37, 2, 277, 281, 5, 62, 32, 2, 278, 281, 5, 64, 33, 2, 279, 281, 5, 74, 38, 2, 280, 276, 3, 2, 2, 2, 280, 277, 3, 2, 2, 2, 280, 278, 3, 2, 2, 2, 280, 279, 3, 2, 2, 2, 281, 25, 3, 2, 2, 2, 282, 286, 5, 86, 44, 2, 283, 286, 5, 100, 51, 2, 284, 286, 5, 104, 53, 2, 285, 282, 3, 2, 2, 2, 285, 283, 3, 2, 2, 2, 285, 284, 3, 2, 2, 2, 286, 27, 3, 2, 2, 2, 287, 288, 7, 8, 2, 2, 288, 290, 5, 126, 64, 2, 289, 291, 5, 30, 16, 2, 290, 289, 3, 2, 2, 2, 291, 292, 3, 2, 2, 2, 292, 290, 3, 2, 2, 2, 292, 293, 3, 2, 2, 2, 293, 29, 3, 2, 2, 2, 294, 299, 5, 64, 33, 2, 295, 299, 5, 66, 34, 2, 296, 299, 5, 68, 35, 2, 297, 299, 5, 70, 36, 2, 298, 294, 3, 2, 2, 2, 298, 295, 3, 2, 2, 2, 298, 296, 3, 2, 2, 2, 298, 297, 3, 2, 2, 2, 299, 31, 3, 2, 2, 2, 300, 301, 7, 9, 2, 2, 301, 305, 5, 126, 64, 2, 302, 304, 5, 34, 18, 2, 303, 302, 3, 2, 2, 2, 304, 307, 3, 2, 2, 2, 305, 303, 3, 2, 2, 2, 305, 306, 3, 2, 2, 2, 306, 311, 3, 2, 2, 2, 307, 305, 3, 2, 2, 2, 308, 310, 5, 36, 19, 2, 309, 308, 3, 2, 2, 2, 310, 313, 3, 2, 2, 2, 311, 309, 3, 2, 2, 2, 311, 312, 3, 2, 2, 2, 312, 33, 3, 2, 2, 2, 313, 311, 3, 2, 2, 2, 314, 318, 5, 60, 31, 2, 315, 318, 5, 62, 32, 2, 316, 318, 5, 64, 33, 2, 317, 314, 3, 2, 2, 2, 317, 315, 3, 2, 2, 2, 317, 316, 3, 2, 2, 2, 318, 35, 3, 2, 2, 2, 319, 323, 5, 106, 54, 2, 320, 323, 5, 94, 48, 2, 321, 323, 5, 100, 51, 2, 322, 319, 3, 2, 2, 2, 322, 320, 3, 2, 2, 2, 322, 321, 3, 2, 2, 2, 323, 37, 3, 2, 2, 2, 324, 325, 7, 10, 2, 2, 325, 329, 5, 126, 64, 2, 326, 328, 5, 40, 21, 2, 327, 326, 3, 2, 2, 2, 328, 331, 3, 2, 2, 2, 329, 327, 3, 2, 2, 2, 329, 330, 3, 2, 2, 2, 330, 335, 3, 2, 2, 2, 331, 329, 3, 2, 2, 2, 332, 334, 5, 42, 22, 2, 333, 332, 3, 2, 2, 2, 334, 337, 3, 2, 2, 2, 335, 333, 3, 2, 2, 2, 335, 336, 3, 2, 2, 2, 336, 39, 3, 2, 2, 2, 337, 335, 3, 2, 2, 2, 338, 342, 5, 60, 31, 2, 339, 342, 5, 62, 32, 2, 340, 342, 5, 64, 33, 2, 341, 338, 3, 2, 2, 2, 341, 339, 3, 2, 2, 2, 341, 340, 3, 2, 2, 2, 342, 41, 3, 2, 2, 2, 343, 347, 5, 142, 72, 2, 344, 347, 5, 96, 49, 2, 345, 347, 5, 100, 51, 2, 346, 343, 3, 2, 2, 2, 346, 344, 3, 2, 2, 2, 346, 345, 3, 2, 2, 2, 347, 43, 3, 2, 2, 2, 348, 349, 7, 11, 2, 2, 349, 351, 7, 76, 2, 2, 350, 352, 5, 46, 24, 2, 351, 350, 3, 2, 2, 2, 352, 353, 3, 2, 2, 2, 353, 351, 3, 2, 2, 2, 353, 354, 3, 2, 2, 2, 354, 45, 3, 2, 2, 2, 355, 360, 5, 18, 10, 2, 356, 360, 5, 142, 72, 2, 357, 360, 5, 96, 49, 2, 358, 360, 5, 106, 54, 2, 359, 355, 3, 2, 2, 2, 359, 356, 3, 2, 2, 2, 359, 357, 3, 2, 2, 2, 359, 358, 3, 2, 2, 2, 360, 47, 3, 2, 2, 2, 361, 362, 7, 11, 2, 2, 362, 363, 7, 75, 2, 2, 363, 364, 5, 50, 26, 2, 364, 49, 3, 2, 2, 2, 365, 369, 7, 53, 2, 2, 366, 368, 10, 2, 2, 2, 367, 366, 3, 2, 2, 2, 368, 371, 3, 2, 2, 2, 369, 367, 3, 2, 2, 2, 369, 370, 3, 2, 2, 2, 370, 51, 3, 2, 2, 2, 371, 369, 3, 2, 2, 2, 372, 373, 7, 12, 2, 2, 373, 377, 5, 126, 64, 2, 374, 376, 5, 54, 28, 2, 375, 374, 3, 2, 2, 2, 376, 379, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 378, 383, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 382, 5, 56, 29, 2, 381, 380, 3, 2, 2, 2, 382, 385, 3, 2, 2, 2, 383, 381, 3, 2, 2, 2, 383, 384, 3, 2, 2, 2, 384, 53, 3, 2, 2, 2, 385, 383, 3, 2, 2, 2, 386, 392, 5, 60, 31, 2, 387, 392, 5, 76, 39, 2, 388, 392, 5, 78, 40, 2, 389, 392, 5, 64, 33, 2, 390, 392, 5, 62, 32, 2, 391, 386, 3, 2, 2, 2, 391, 387, 3, 2, 2, 2, 391, 388, 3, 2, 2, 2, 391, 389, 3, 2, 2, 2, 391, 390, 3, 2, 2, 2, 392, 55, 3, 2, 2, 2, 393, 397, 5, 98, 50, 2, 394, 397, 5, 100, 51, 2, 395, 397, 5, 104, 53, 2, 396, 393, 3, 2, 2, 2, 396, 394, 3, 2, 2, 2, 396, 395, 3, 2, 2, 2, 397, 57, 3, 2, 2, 2, 398, 399, 7, 15, 2, 2, 399, 400, 5, 126, 64, 2, 400, 59, 3, 2, 2, 2, 401, 402, 7, 16, 2, 2, 402, 403, 5, 126, 64, 2, 403, 61, 3, 2, 2, 2, 404, 405, 7, 17, 2, 2, 405, 406, 7, 57, 2, 2, 406, 63, 3, 2, 2, 2, 407, 408, 7, 18, 2, 2, 408, 409, 9, 3, 2, 2, 409, 65, 3, 2, 2, 2, 410, 411, 7, 19, 2, 2, 411, 412, 7, 57, 2, 2, 412, 67, 3, 2, 2, 2, 413, 414, 7, 20, 2, 2, 414, 415, 7, 57, 2, 2, 415, 69, 3, 2, 2, 2, 416, 417, 7, 21, 2, 2, 417, 418, 7, 61, 2, 2, 418, 71, 3, 2, 2, 2, 419, 420, 7, 7, 2, 2, 420, 421, 5, 126, 64, 2, 421, 73, 3, 2, 2, 2, 422, 423, 7, 22, 2, 2, 423, 424, 7, 61, 2, 2, 424, 75, 3, 2, 2, 2, 425, 426, 7, 23, 2, 2, 426, 427, 5, 126, 64, 2, 427, 77, 3, 2, 2, 2, 428, 429, 7, 24, 2, 2, 429, 430, 7, 57, 2, 2, 430, 79, 3, 2, 2, 2, 431, 432, 7, 53, 2, 2, 432, 433, 5, 128, 65, 2, 433, 437, 7, 65, 2, 2, 434, 436, 5, 132, 67, 2, 435, 434, 3, 2, 2, 2, 436, 439, 3, 2, 2, 2, 437, 435, 3, 2, 2, 2, 437, 438, 3, 2, 2, 2, 438, 81, 3, 2, 2, 2, 439, 437, 3, 2, 2, 2, 440, 441, 7, 53, 2, 2, 441, 446, 5, 128, 65, 2, 442, 443, 7, 38, 2, 2, 443, 445, 5, 128, 65, 2, 444, 442, 3, 2, 2, 2, 445, 448, 3, 2, 2, 2, 446, 444, 3, 2, 2, 2, 446, 447, 3, 2, 2, 2, 447, 450, 3, 2, 2, 2, 448, 446, 3, 2, 2, 2, 449, 451, 5, 132, 67, 2, 450, 449, 3, 2, 2, 2, 451, 452, 3, 2, 2, 2, 452, 450, 3, 2, 2, 2, 452, 453, 3, 2, 2, 2, 453, 83, 3, 2, 2, 2, 454, 455, 7, 53, 2, 2, 455, 456, 5, 128, 65, 2, 456, 457, 7, 31, 2, 2, 457, 459, 5, 126, 64, 2, 458, 460, 5, 134, 68, 2, 459, 458, 3, 2, 2, 2, 459, 460, 3, 2, 2, 2, 460, 85, 3, 2, 2, 2, 461, 462, 7, 53, 2, 2, 462, 463, 5, 128, 65, 2, 463, 464, 7, 52, 2, 2, 464, 466, 5, 136, 69, 2, 465, 467, 7, 50, 2, 2, 466, 465, 3, 2, 2, 2, 466, 467, 3, 2, 2, 2, 467, 87, 3, 2, 2, 2, 468, 469, 7, 53, 2, 2, 469, 470, 5, 128, 65, 2, 470, 471, 7, 36, 2, 2, 471, 476, 5, 138, 70, 2, 472, 473, 7, 38, 2, 2, 473, 475, 5, 138, 70, 2, 474, 472, 3, 2, 2, 2, 475, 478, 3, 2, 2, 2, 476, 474, 3, 2, 2, 2, 476, 477, 3, 2, 2, 2, 477, 89, 3, 2, 2, 2, 478, 476, 3, 2, 2, 2, 479, 480, 7, 53, 2, 2, 480, 481, 5, 128, 65, 2, 481, 482, 7, 39, 2, 2, 482, 487, 5, 156, 79, 2, 483, 484, 7, 40, 2, 2, 484, 486, 5, 156, 79, 2, 485, 483, 3, 2, 2, 2, 486, 489, 3, 2, 2, 2, 487, 485, 3, 2, 2, 2, 487, 488, 3, 2, 2, 2, 488, 91, 3, 2, 2, 2, 489, 487, 3, 2, 2, 2, 490, 492, 7, 53, 2, 2, 491, 493, 5, 128, 65, 2, 492, 491, 3, 2, 2, 2, 492, 493, 3, 2, 2, 2, 493, 494, 3, 2, 2, 2, 494, 495, 7, 41, 2, 2, 495, 500, 5, 126, 64, 2, 496, 497, 7, 38, 2, 2, 497, 499, 5, 126, 64, 2, 498, 496, 3, 2, 2, 2, 499, 502, 3, 2, 2, 2, 500, 498, 3, 2, 2, 2, 500, 501, 3, 2, 2, 2, 501, 93, 3, 2, 2, 2, 502, 500, 3, 2, 2, 2, 503, 505, 7, 53, 2, 2, 504, 506, 5, 128, 65, 2, 505, 504, 3, 2, 2, 2, 505, 506, 3, 2, 2, 2, 506, 507, 3, 2, 2, 2, 507, 508, 5, 130, 66, 2, 508, 509, 7, 52, 2, 2, 509, 510, 5, 136, 69, 2, 510, 95, 3, 2, 2, 2, 511, 515, 7, 53, 2, 2, 512, 514, 7, 61, 2, 2, 513, 512, 3, 2, 2, 2, 514, 517, 3, 2, 2, 2, 515, 513, 3, 2, 2, 2, 515, 516, 3, 2, 2, 2, 516, 518, 3, 2, 2, 2, 517, 515, 3, 2, 2, 2, 518, 519, 5, 130, 66, 2, 519, 520, 7, 52, 2, 2, 520, 521, 5, 136, 69, 2, 521, 97, 3, 2, 2, 2, 522, 524, 7, 53, 2, 2, 523, 525, 5, 128, 65, 2, 524, 523, 3, 2, 2, 2, 524, 525, 3, 2, 2, 2, 525, 526, 3, 2, 2, 2, 526, 527, 7, 56, 2, 2, 527, 529, 7, 57, 2, 2, 528, 530, 7, 57, 2, 2, 529, 528, 3, 2, 2, 2, 529, 530, 3, 2, 2, 2, 530, 532, 3, 2, 2, 2, 531, 533, 7, 61, 2, 2, 532, 531, 3, 2, 2, 2, 532, 533, 3, 2, 2, 2, 533, 99, 3, 2, 2, 2, 534, 535, 7, 53, 2, 2, 535, 536, 7, 51, 2, 2, 536, 537, 9, 4, 2, 2, 537, 101, 3, 2, 2, 2, 538, 539, 7, 53, 2, 2, 539, 540, 5, 128, 65, 2, 540, 544, 7, 65, 2, 2, 541, 543, 5, 132, 67, 2, 542, 541, 3, 2, 2, 2, 543, 546, 3, 2, 2, 2, 544, 542, 3, 2, 2, 2, 544, 545, 3, 2, 2, 2, 545, 547, 3, 2, 2, 2, 546, 544, 3, 2, 2, 2, 547, 552, 5, 156, 79, 2, 548, 549, 7, 40, 2, 2, 549, 551, 5, 156, 79, 2, 550, 548, 3, 2, 2, 2, 551, 554, 3, 2, 2, 2, 552, 550, 3, 2, 2, 2, 552, 553, 3, 2, 2, 2, 553, 556, 3, 2, 2, 2, 554, 552, 3, 2, 2, 2, 555, 557, 7, 57, 2, 2, 556, 555, 3, 2, 2, 2, 556, 557, 3, 2, 2, 2, 557, 559, 3, 2, 2, 2, 558, 560, 7, 57, 2, 2, 559, 558, 3, 2, 2, 2, 559, 560, 3, 2, 2, 2, 560, 103, 3, 2, 2, 2, 561, 562, 7, 53, 2, 2, 562, 563, 5, 128, 65, 2, 563, 105, 3, 2, 2, 2, 564, 566, 7, 53, 2, 2, 565, 567, 9, 5, 2, 2, 566, 565, 3, 2, 2, 2, 566, 567, 3, 2, 2, 2, 567, 570, 3, 2, 2, 2, 568, 571, 5, 108, 55, 2, 569, 571, 5, 110, 56, 2, 570, 568, 3, 2, 2, 2, 570, 569, 3, 2, 2, 2, 571, 107, 3, 2, 2, 2, 572, 574, 5, 140, 71, 2, 573, 575, 5, 112, 57, 2, 574, 573, 3, 2, 2, 2, 574, 575, 3, 2, 2, 2, 575, 587, 3, 2, 2, 2, 576, 577, 5, 140, 71, 2, 577, 578, 7, 38, 2, 2, 578, 580, 3, 2, 2, 2, 579, 576, 3, 2, 2, 2, 580, 581, 3, 2, 2, 2, 581, 579, 3, 2, 2, 2, 581, 582, 3, 2, 2, 2, 582, 583, 3, 2, 2, 2, 583, 584, 5, 140, 71, 2, 584, 585, 5, 112, 57, 2, 585, 587, 3, 2, 2, 2, 586, 572, 3, 2, 2, 2, 586, 579, 3, 2, 2, 2, 587, 109, 3, 2, 2, 2, 588, 589, 7, 46, 2, 2, 589, 592, 5, 112, 57, 2, 590, 591, 7, 47, 2, 2, 591, 593, 5, 118, 60, 2, 592, 590, 3, 2, 2, 2, 592, 593, 3, 2, 2, 2, 593, 111, 3, 2, 2, 2, 594, 605, 7, 31, 2, 2, 595, 598, 5, 114, 58, 2, 596, 597, 7, 38, 2, 2, 597, 599, 5, 116, 59, 2, 598, 596, 3, 2, 2, 2, 598, 599, 3, 2, 2, 2, 599, 606, 3, 2, 2, 2, 600, 603, 5, 116, 59, 2, 601, 602, 7, 38, 2, 2, 602, 604, 5, 114, 58, 2, 603, 601, 3, 2, 2, 2, 603, 604, 3, 2, 2, 2, 604, 606, 3, 2, 2, 2, 605, 595, 3, 2, 2, 2, 605, 600, 3, 2, 2, 2, 606, 113, 3, 2, 2, 2, 607, 608, 7, 49, 2, 2, 608, 609, 5, 126, 64, 2, 609, 115, 3, 2, 2, 2, 610, 611, 7, 48, 2, 2, 611, 616, 5, 126, 64, 2, 612, 613, 7, 38, 2, 2, 613, 615, 5, 126, 64, 2, 614, 612, 3, 2, 2, 2, 615, 618, 3, 2, 2, 2, 616, 614, 3, 2, 2, 2, 616, 617, 3, 2, 2, 2, 617, 117, 3, 2, 2, 2, 618, 616, 3, 2, 2, 2, 619, 620, 5, 120, 61, 2, 620, 621, 7, 38, 2, 2, 621, 622, 5, 120, 61, 2, 622, 119, 3, 2, 2, 2, 623, 624, 5, 126, 64, 2, 624, 626, 5, 122, 62, 2, 625, 627, 5, 124, 63, 2, 626, 625, 3, 2, 2, 2, 626, 627, 3, 2, 2, 2, 627, 121, 3, 2, 2, 2, 628, 629, 9, 6, 2, 2, 629, 123, 3, 2, 2, 2, 630, 636, 5, 140, 71, 2, 631, 636, 7, 42, 2, 2, 632, 636, 7, 43, 2, 2, 633, 636, 7, 69, 2, 2, 634, 636, 7, 57, 2, 2, 635, 630, 3, 2, 2, 2, 635, 631, 3, 2, 2, 2, 635, 632, 3, 2, 2, 2, 635, 633, 3, 2, 2, 2, 635, 634, 3, 2, 2, 2, 636, 125, 3, 2, 2, 2, 637, 638, 9, 7, 2, 2, 638, 127, 3, 2, 2, 2, 639, 640, 9, 8, 2, 2, 640, 129, 3, 2, 2, 2, 641, 642, 7, 68, 2, 2, 642, 131, 3, 2, 2, 2, 643, 644, 9, 9, 2, 2, 644, 133, 3, 2, 2, 2, 645, 646, 9, 10, 2, 2, 646, 135, 3, 2, 2, 2, 647, 660, 7, 57, 2, 2, 648, 660, 7, 58, 2, 2, 649, 660, 7, 59, 2, 2, 650, 660, 7, 63, 2, 2, 651, 660, 7, 64, 2, 2, 652, 660, 5, 148, 75, 2, 653, 660, 5, 150, 76, 2, 654, 660, 5, 140, 71, 2, 655, 660, 5, 144, 73, 2, 656, 660, 5, 146, 74, 2, 657, 660, 5, 154, 78, 2, 658, 660, 5, 126, 64, 2, 659, 647, 3, 2, 2, 2, 659, 648, 3, 2, 2, 2, 659, 649, 3, 2, 2, 2, 659, 650, 3, 2, 2, 2, 659, 651, 3, 2, 2, 2, 659, 652, 3, 2, 2, 2, 659, 653, 3, 2, 2, 2, 659, 654, 3, 2, 2, 2, 659, 655, 3, 2, 2, 2, 659, 656, 3, 2, 2, 2, 659, 657, 3, 2, 2, 2, 659, 658, 3, 2, 2, 2, 660, 137, 3, 2, 2, 2, 661, 664, 5, 126, 64, 2, 662, 663, 7, 37, 2, 2, 663, 665, 5, 126, 64, 2, 664, 662, 3, 2, 2, 2, 664, 665, 3, 2, 2, 2, 665, 666, 3, 2, 2, 2, 666, 670, 7, 65, 2, 2, 667, 669, 5, 132, 67, 2, 668, 667, 3, 2, 2, 2, 669, 672, 3, 2, 2, 2, 670, 668, 3, 2, 2, 2, 670, 671, 3, 2, 2, 2, 671, 139, 3, 2, 2, 2, 672, 670, 3, 2, 2, 2, 673, 675, 7, 61, 2, 2, 674, 676, 7, 57, 2, 2, 675, 674, 3, 2, 2, 2, 675, 676, 3, 2, 2, 2, 676, 141, 3, 2, 2, 2, 677, 679, 7, 53, 2, 2, 678, 680, 7, 61, 2, 2, 679, 678, 3, 2, 2, 2, 680, 681, 3, 2, 2, 2, 681, 679, 3, 2, 2, 2, 681, 682, 3, 2, 2, 2, 682, 684, 3, 2, 2, 2, 683, 685, 7, 57, 2, 2, 684, 683, 3, 2, 2, 2, 684, 685, 3, 2, 2, 2, 685, 687, 3, 2, 2, 2, 686, 688, 9, 3, 2, 2, 687, 686, 3, 2, 2, 2, 687, 688, 3, 2, 2, 2, 688, 143, 3, 2, 2, 2, 689, 690, 7, 59, 2, 2, 690, 692, 9, 11, 2, 2, 691, 693, 7, 57, 2, 2, 692, 691, 3, 2, 2, 2, 692, 693, 3, 2, 2, 2, 693, 145, 3, 2, 2, 2, 694, 695, 5, 152, 77, 2, 695, 696, 7, 54, 2, 2, 696, 697, 5, 152, 77, 2, 697, 147, 3, 2, 2, 2, 698, 700, 7, 66, 2, 2, 699, 701, 7, 57, 2, 2, 700, 699, 3, 2, 2, 2, 700, 701, 3, 2, 2, 2, 701, 149, 3, 2, 2, 2, 702, 703, 7, 67, 2, 2, 703, 151, 3, 2, 2, 2, 704, 707, 7, 59, 2, 2, 705, 707, 5, 144, 73, 2, 706, 704, 3, 2, 2, 2, 706, 705, 3, 2, 2, 2, 707, 153, 3, 2, 2, 2, 708, 709, 9, 12, 2, 2, 709, 155, 3, 2, 2, 2, 710, 713, 5, 126, 64, 2, 711, 713, 5, 148, 75, 2, 712, 710, 3, 2, 2, 2, 712, 711, 3, 2, 2, 2, 713, 157, 3, 2, 2, 2, 77, 161, 178, 190, 195, 203, 209, 217, 223, 231, 237, 244, 256, 260, 267, 273, 280, 285, 292, 298, 305, 311, 317, 322, 329, 335, 341, 346, 353, 359, 369, 377, 383, 391, 396, 437, 446, 452, 459, 466, 476, 487, 492, 500, 505, 515, 524, 529, 532, 544, 552, 556, 559, 566, 570, 574, 581, 586, 592, 598, 603, 605, 616, 626, 635, 659, 664, 670, 675, 681, 684, 687, 692, 700, 706, 712]
\ No newline at end of file
diff --git a/src/import/generated/FSHParser.js b/src/import/generated/FSHParser.js
index 0b77096..38c35eb 100644
--- a/src/import/generated/FSHParser.js
+++ b/src/import/generated/FSHParser.js
@@ -53,100 +53,100 @@ var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964",
     "\u0003\u0014\u0003\u0014\u0007\u0014\u0148\n\u0014\f\u0014\u000e\u0014",
     "\u014b\u000b\u0014\u0003\u0014\u0007\u0014\u014e\n\u0014\f\u0014\u000e",
     "\u0014\u0151\u000b\u0014\u0003\u0015\u0003\u0015\u0003\u0015\u0005\u0015",
-    "\u0156\n\u0015\u0003\u0016\u0003\u0016\u0003\u0016\u0003\u0016\u0005",
-    "\u0016\u015c\n\u0016\u0003\u0017\u0003\u0017\u0003\u0017\u0006\u0017",
-    "\u0161\n\u0017\r\u0017\u000e\u0017\u0162\u0003\u0018\u0003\u0018\u0003",
-    "\u0018\u0003\u0018\u0005\u0018\u0169\n\u0018\u0003\u0019\u0003\u0019",
-    "\u0003\u0019\u0003\u0019\u0003\u001a\u0003\u001a\u0007\u001a\u0171\n",
-    "\u001a\f\u001a\u000e\u001a\u0174\u000b\u001a\u0003\u001b\u0003\u001b",
-    "\u0003\u001b\u0007\u001b\u0179\n\u001b\f\u001b\u000e\u001b\u017c\u000b",
-    "\u001b\u0003\u001b\u0007\u001b\u017f\n\u001b\f\u001b\u000e\u001b\u0182",
-    "\u000b\u001b\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c",
-    "\u0005\u001c\u0189\n\u001c\u0003\u001d\u0003\u001d\u0003\u001d\u0005",
-    "\u001d\u018e\n\u001d\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001f",
-    "\u0003\u001f\u0003\u001f\u0003 \u0003 \u0003 \u0003!\u0003!\u0003!\u0003",
-    "\"\u0003\"\u0003\"\u0003#\u0003#\u0003#\u0003$\u0003$\u0003$\u0003%",
-    "\u0003%\u0003%\u0003&\u0003&\u0003&\u0003\'\u0003\'\u0003\'\u0003(\u0003",
-    "(\u0003(\u0003)\u0003)\u0003)\u0003)\u0007)\u01b5\n)\f)\u000e)\u01b8",
-    "\u000b)\u0003*\u0003*\u0003*\u0003*\u0007*\u01be\n*\f*\u000e*\u01c1",
-    "\u000b*\u0003*\u0006*\u01c4\n*\r*\u000e*\u01c5\u0003+\u0003+\u0003+",
-    "\u0003+\u0003+\u0005+\u01cd\n+\u0003,\u0003,\u0003,\u0003,\u0003,\u0005",
-    ",\u01d4\n,\u0003-\u0003-\u0003-\u0003-\u0003-\u0003-\u0007-\u01dc\n",
-    "-\f-\u000e-\u01df\u000b-\u0003.\u0003.\u0003.\u0003.\u0003.\u0003.\u0007",
-    ".\u01e7\n.\f.\u000e.\u01ea\u000b.\u0003/\u0003/\u0005/\u01ee\n/\u0003",
-    "/\u0003/\u0003/\u0003/\u0007/\u01f4\n/\f/\u000e/\u01f7\u000b/\u0003",
-    "0\u00030\u00050\u01fb\n0\u00030\u00030\u00030\u00030\u00031\u00031\u0006",
-    "1\u0203\n1\r1\u000e1\u0204\u00031\u00031\u00031\u00031\u00032\u0003",
-    "2\u00052\u020d\n2\u00032\u00032\u00032\u00052\u0212\n2\u00032\u0005",
-    "2\u0215\n2\u00033\u00033\u00033\u00033\u00034\u00034\u00034\u00034\u0007",
-    "4\u021f\n4\f4\u000e4\u0222\u000b4\u00034\u00034\u00034\u00074\u0227",
-    "\n4\f4\u000e4\u022a\u000b4\u00034\u00054\u022d\n4\u00034\u00054\u0230",
-    "\n4\u00035\u00035\u00035\u00036\u00036\u00056\u0237\n6\u00036\u0003",
-    "6\u00056\u023b\n6\u00037\u00037\u00057\u023f\n7\u00037\u00037\u0003",
-    "7\u00067\u0244\n7\r7\u000e7\u0245\u00037\u00037\u00037\u00057\u024b",
-    "\n7\u00038\u00038\u00038\u00038\u00058\u0251\n8\u00039\u00039\u0003",
-    "9\u00039\u00059\u0257\n9\u00039\u00039\u00039\u00059\u025c\n9\u0005",
-    "9\u025e\n9\u0003:\u0003:\u0003:\u0003;\u0003;\u0003;\u0003;\u0007;\u0267",
-    "\n;\f;\u000e;\u026a\u000b;\u0003<\u0003<\u0003<\u0003<\u0003=\u0003",
-    "=\u0003=\u0005=\u0273\n=\u0003>\u0003>\u0003?\u0003?\u0003?\u0003?\u0003",
-    "?\u0005?\u027c\n?\u0003@\u0003@\u0003A\u0003A\u0003B\u0003B\u0003C\u0003",
-    "C\u0003D\u0003D\u0003E\u0003E\u0003E\u0003E\u0003E\u0003E\u0003E\u0003",
-    "E\u0003E\u0003E\u0003E\u0003E\u0005E\u0294\nE\u0003F\u0003F\u0003F\u0005",
-    "F\u0299\nF\u0003F\u0003F\u0007F\u029d\nF\fF\u000eF\u02a0\u000bF\u0003",
-    "G\u0003G\u0005G\u02a4\nG\u0003H\u0003H\u0006H\u02a8\nH\rH\u000eH\u02a9",
-    "\u0003H\u0005H\u02ad\nH\u0003H\u0005H\u02b0\nH\u0003I\u0003I\u0003I",
-    "\u0005I\u02b5\nI\u0003J\u0003J\u0003J\u0003J\u0003K\u0003K\u0005K\u02bd",
-    "\nK\u0003L\u0003L\u0003M\u0003M\u0005M\u02c3\nM\u0003N\u0003N\u0003",
-    "O\u0003O\u0005O\u02c9\nO\u0003O\u0002\u0002P\u0002\u0004\u0006\b\n\f",
-    "\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.0246",
-    "8:<>@BDFHJLNPRTVXZ\\^`bdfhjlnprtvxz|~\u0080\u0082\u0084\u0086\u0088",
-    "\u008a\u008c\u008e\u0090\u0092\u0094\u0096\u0098\u009a\u009c\u0002\r",
-    "\u0004\u0002\u0003\u0006\b\f\u0003\u00029:\u0003\u0002KL\u0003\u0002",
-    ",-\u0004\u000244HH\u0007\u0002\u001a\u001e..01;;HH\u0004\u000211HH\u0003",
-    "\u0002\u0019\u001e\u0003\u0002 #\u0003\u0002<=\u0003\u0002*+\u0002\u02f8",
-    "\u0002\u00a1\u0003\u0002\u0002\u0002\u0004\u00b2\u0003\u0002\u0002\u0002",
-    "\u0006\u00b4\u0003\u0002\u0002\u0002\b\u00b9\u0003\u0002\u0002\u0002",
-    "\n\u00c6\u0003\u0002\u0002\u0002\f\u00d4\u0003\u0002\u0002\u0002\u000e",
-    "\u00e2\u0003\u0002\u0002\u0002\u0010\u00f4\u0003\u0002\u0002\u0002\u0012",
-    "\u0100\u0003\u0002\u0002\u0002\u0014\u0104\u0003\u0002\u0002\u0002\u0016",
-    "\u0106\u0003\u0002\u0002\u0002\u0018\u0118\u0003\u0002\u0002\u0002\u001a",
-    "\u011d\u0003\u0002\u0002\u0002\u001c\u011f\u0003\u0002\u0002\u0002\u001e",
-    "\u012a\u0003\u0002\u0002\u0002 \u012c\u0003\u0002\u0002\u0002\"\u013d",
-    "\u0003\u0002\u0002\u0002$\u0142\u0003\u0002\u0002\u0002&\u0144\u0003",
-    "\u0002\u0002\u0002(\u0155\u0003\u0002\u0002\u0002*\u015b\u0003\u0002",
-    "\u0002\u0002,\u015d\u0003\u0002\u0002\u0002.\u0168\u0003\u0002\u0002",
-    "\u00020\u016a\u0003\u0002\u0002\u00022\u016e\u0003\u0002\u0002\u0002",
-    "4\u0175\u0003\u0002\u0002\u00026\u0188\u0003\u0002\u0002\u00028\u018d",
-    "\u0003\u0002\u0002\u0002:\u018f\u0003\u0002\u0002\u0002<\u0192\u0003",
-    "\u0002\u0002\u0002>\u0195\u0003\u0002\u0002\u0002@\u0198\u0003\u0002",
-    "\u0002\u0002B\u019b\u0003\u0002\u0002\u0002D\u019e\u0003\u0002\u0002",
-    "\u0002F\u01a1\u0003\u0002\u0002\u0002H\u01a4\u0003\u0002\u0002\u0002",
-    "J\u01a7\u0003\u0002\u0002\u0002L\u01aa\u0003\u0002\u0002\u0002N\u01ad",
-    "\u0003\u0002\u0002\u0002P\u01b0\u0003\u0002\u0002\u0002R\u01b9\u0003",
-    "\u0002\u0002\u0002T\u01c7\u0003\u0002\u0002\u0002V\u01ce\u0003\u0002",
-    "\u0002\u0002X\u01d5\u0003\u0002\u0002\u0002Z\u01e0\u0003\u0002\u0002",
-    "\u0002\\\u01eb\u0003\u0002\u0002\u0002^\u01f8\u0003\u0002\u0002\u0002",
-    "`\u0200\u0003\u0002\u0002\u0002b\u020a\u0003\u0002\u0002\u0002d\u0216",
-    "\u0003\u0002\u0002\u0002f\u021a\u0003\u0002\u0002\u0002h\u0231\u0003",
-    "\u0002\u0002\u0002j\u0234\u0003\u0002\u0002\u0002l\u024a\u0003\u0002",
-    "\u0002\u0002n\u024c\u0003\u0002\u0002\u0002p\u0252\u0003\u0002\u0002",
-    "\u0002r\u025f\u0003\u0002\u0002\u0002t\u0262\u0003\u0002\u0002\u0002",
-    "v\u026b\u0003\u0002\u0002\u0002x\u026f\u0003\u0002\u0002\u0002z\u0274",
-    "\u0003\u0002\u0002\u0002|\u027b\u0003\u0002\u0002\u0002~\u027d\u0003",
-    "\u0002\u0002\u0002\u0080\u027f\u0003\u0002\u0002\u0002\u0082\u0281\u0003",
-    "\u0002\u0002\u0002\u0084\u0283\u0003\u0002\u0002\u0002\u0086\u0285\u0003",
-    "\u0002\u0002\u0002\u0088\u0293\u0003\u0002\u0002\u0002\u008a\u0295\u0003",
-    "\u0002\u0002\u0002\u008c\u02a1\u0003\u0002\u0002\u0002\u008e\u02a5\u0003",
-    "\u0002\u0002\u0002\u0090\u02b1\u0003\u0002\u0002\u0002\u0092\u02b6\u0003",
-    "\u0002\u0002\u0002\u0094\u02ba\u0003\u0002\u0002\u0002\u0096\u02be\u0003",
-    "\u0002\u0002\u0002\u0098\u02c2\u0003\u0002\u0002\u0002\u009a\u02c4\u0003",
-    "\u0002\u0002\u0002\u009c\u02c8\u0003\u0002\u0002\u0002\u009e\u00a0\u0005",
-    "\u0004\u0003\u0002\u009f\u009e\u0003\u0002\u0002\u0002\u00a0\u00a3\u0003",
-    "\u0002\u0002\u0002\u00a1\u009f\u0003\u0002\u0002\u0002\u00a1\u00a2\u0003",
-    "\u0002\u0002\u0002\u00a2\u00a4\u0003\u0002\u0002\u0002\u00a3\u00a1\u0003",
-    "\u0002\u0002\u0002\u00a4\u00a5\u0007\u0002\u0002\u0003\u00a5\u0003\u0003",
-    "\u0002\u0002\u0002\u00a6\u00b3\u0005\u0006\u0004\u0002\u00a7\u00b3\u0005",
-    "\b\u0005\u0002\u00a8\u00b3\u0005\n\u0006\u0002\u00a9\u00b3\u0005\u001c",
+    "\u0156\n\u0015\u0003\u0016\u0003\u0016\u0003\u0016\u0005\u0016\u015b",
+    "\n\u0016\u0003\u0017\u0003\u0017\u0003\u0017\u0006\u0017\u0160\n\u0017",
+    "\r\u0017\u000e\u0017\u0161\u0003\u0018\u0003\u0018\u0003\u0018\u0003",
+    "\u0018\u0005\u0018\u0168\n\u0018\u0003\u0019\u0003\u0019\u0003\u0019",
+    "\u0003\u0019\u0003\u001a\u0003\u001a\u0007\u001a\u0170\n\u001a\f\u001a",
+    "\u000e\u001a\u0173\u000b\u001a\u0003\u001b\u0003\u001b\u0003\u001b\u0007",
+    "\u001b\u0178\n\u001b\f\u001b\u000e\u001b\u017b\u000b\u001b\u0003\u001b",
+    "\u0007\u001b\u017e\n\u001b\f\u001b\u000e\u001b\u0181\u000b\u001b\u0003",
+    "\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0005\u001c\u0188",
+    "\n\u001c\u0003\u001d\u0003\u001d\u0003\u001d\u0005\u001d\u018d\n\u001d",
+    "\u0003\u001e\u0003\u001e\u0003\u001e\u0003\u001f\u0003\u001f\u0003\u001f",
+    "\u0003 \u0003 \u0003 \u0003!\u0003!\u0003!\u0003\"\u0003\"\u0003\"\u0003",
+    "#\u0003#\u0003#\u0003$\u0003$\u0003$\u0003%\u0003%\u0003%\u0003&\u0003",
+    "&\u0003&\u0003\'\u0003\'\u0003\'\u0003(\u0003(\u0003(\u0003)\u0003)",
+    "\u0003)\u0003)\u0007)\u01b4\n)\f)\u000e)\u01b7\u000b)\u0003*\u0003*",
+    "\u0003*\u0003*\u0007*\u01bd\n*\f*\u000e*\u01c0\u000b*\u0003*\u0006*",
+    "\u01c3\n*\r*\u000e*\u01c4\u0003+\u0003+\u0003+\u0003+\u0003+\u0005+",
+    "\u01cc\n+\u0003,\u0003,\u0003,\u0003,\u0003,\u0005,\u01d3\n,\u0003-",
+    "\u0003-\u0003-\u0003-\u0003-\u0003-\u0007-\u01db\n-\f-\u000e-\u01de",
+    "\u000b-\u0003.\u0003.\u0003.\u0003.\u0003.\u0003.\u0007.\u01e6\n.\f",
+    ".\u000e.\u01e9\u000b.\u0003/\u0003/\u0005/\u01ed\n/\u0003/\u0003/\u0003",
+    "/\u0003/\u0007/\u01f3\n/\f/\u000e/\u01f6\u000b/\u00030\u00030\u0005",
+    "0\u01fa\n0\u00030\u00030\u00030\u00030\u00031\u00031\u00071\u0202\n",
+    "1\f1\u000e1\u0205\u000b1\u00031\u00031\u00031\u00031\u00032\u00032\u0005",
+    "2\u020d\n2\u00032\u00032\u00032\u00052\u0212\n2\u00032\u00052\u0215",
+    "\n2\u00033\u00033\u00033\u00033\u00034\u00034\u00034\u00034\u00074\u021f",
+    "\n4\f4\u000e4\u0222\u000b4\u00034\u00034\u00034\u00074\u0227\n4\f4\u000e",
+    "4\u022a\u000b4\u00034\u00054\u022d\n4\u00034\u00054\u0230\n4\u00035",
+    "\u00035\u00035\u00036\u00036\u00056\u0237\n6\u00036\u00036\u00056\u023b",
+    "\n6\u00037\u00037\u00057\u023f\n7\u00037\u00037\u00037\u00067\u0244",
+    "\n7\r7\u000e7\u0245\u00037\u00037\u00037\u00057\u024b\n7\u00038\u0003",
+    "8\u00038\u00038\u00058\u0251\n8\u00039\u00039\u00039\u00039\u00059\u0257",
+    "\n9\u00039\u00039\u00039\u00059\u025c\n9\u00059\u025e\n9\u0003:\u0003",
+    ":\u0003:\u0003;\u0003;\u0003;\u0003;\u0007;\u0267\n;\f;\u000e;\u026a",
+    "\u000b;\u0003<\u0003<\u0003<\u0003<\u0003=\u0003=\u0003=\u0005=\u0273",
+    "\n=\u0003>\u0003>\u0003?\u0003?\u0003?\u0003?\u0003?\u0005?\u027c\n",
+    "?\u0003@\u0003@\u0003A\u0003A\u0003B\u0003B\u0003C\u0003C\u0003D\u0003",
+    "D\u0003E\u0003E\u0003E\u0003E\u0003E\u0003E\u0003E\u0003E\u0003E\u0003",
+    "E\u0003E\u0003E\u0005E\u0294\nE\u0003F\u0003F\u0003F\u0005F\u0299\n",
+    "F\u0003F\u0003F\u0007F\u029d\nF\fF\u000eF\u02a0\u000bF\u0003G\u0003",
+    "G\u0005G\u02a4\nG\u0003H\u0003H\u0006H\u02a8\nH\rH\u000eH\u02a9\u0003",
+    "H\u0005H\u02ad\nH\u0003H\u0005H\u02b0\nH\u0003I\u0003I\u0003I\u0005",
+    "I\u02b5\nI\u0003J\u0003J\u0003J\u0003J\u0003K\u0003K\u0005K\u02bd\n",
+    "K\u0003L\u0003L\u0003M\u0003M\u0005M\u02c3\nM\u0003N\u0003N\u0003O\u0003",
+    "O\u0005O\u02c9\nO\u0003O\u0002\u0002P\u0002\u0004\u0006\b\n\f\u000e",
+    "\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@B",
+    "DFHJLNPRTVXZ\\^`bdfhjlnprtvxz|~\u0080\u0082\u0084\u0086\u0088\u008a",
+    "\u008c\u008e\u0090\u0092\u0094\u0096\u0098\u009a\u009c\u0002\r\u0004",
+    "\u0002\u0003\u0006\b\f\u0003\u00029:\u0003\u0002KL\u0003\u0002,-\u0004",
+    "\u000244HH\u0007\u0002\u001a\u001e..01;;HH\u0004\u000211HH\u0003\u0002",
+    "\u0019\u001e\u0003\u0002 #\u0003\u0002<=\u0003\u0002*+\u0002\u02f7\u0002",
+    "\u00a1\u0003\u0002\u0002\u0002\u0004\u00b2\u0003\u0002\u0002\u0002\u0006",
+    "\u00b4\u0003\u0002\u0002\u0002\b\u00b9\u0003\u0002\u0002\u0002\n\u00c6",
+    "\u0003\u0002\u0002\u0002\f\u00d4\u0003\u0002\u0002\u0002\u000e\u00e2",
+    "\u0003\u0002\u0002\u0002\u0010\u00f4\u0003\u0002\u0002\u0002\u0012\u0100",
+    "\u0003\u0002\u0002\u0002\u0014\u0104\u0003\u0002\u0002\u0002\u0016\u0106",
+    "\u0003\u0002\u0002\u0002\u0018\u0118\u0003\u0002\u0002\u0002\u001a\u011d",
+    "\u0003\u0002\u0002\u0002\u001c\u011f\u0003\u0002\u0002\u0002\u001e\u012a",
+    "\u0003\u0002\u0002\u0002 \u012c\u0003\u0002\u0002\u0002\"\u013d\u0003",
+    "\u0002\u0002\u0002$\u0142\u0003\u0002\u0002\u0002&\u0144\u0003\u0002",
+    "\u0002\u0002(\u0155\u0003\u0002\u0002\u0002*\u015a\u0003\u0002\u0002",
+    "\u0002,\u015c\u0003\u0002\u0002\u0002.\u0167\u0003\u0002\u0002\u0002",
+    "0\u0169\u0003\u0002\u0002\u00022\u016d\u0003\u0002\u0002\u00024\u0174",
+    "\u0003\u0002\u0002\u00026\u0187\u0003\u0002\u0002\u00028\u018c\u0003",
+    "\u0002\u0002\u0002:\u018e\u0003\u0002\u0002\u0002<\u0191\u0003\u0002",
+    "\u0002\u0002>\u0194\u0003\u0002\u0002\u0002@\u0197\u0003\u0002\u0002",
+    "\u0002B\u019a\u0003\u0002\u0002\u0002D\u019d\u0003\u0002\u0002\u0002",
+    "F\u01a0\u0003\u0002\u0002\u0002H\u01a3\u0003\u0002\u0002\u0002J\u01a6",
+    "\u0003\u0002\u0002\u0002L\u01a9\u0003\u0002\u0002\u0002N\u01ac\u0003",
+    "\u0002\u0002\u0002P\u01af\u0003\u0002\u0002\u0002R\u01b8\u0003\u0002",
+    "\u0002\u0002T\u01c6\u0003\u0002\u0002\u0002V\u01cd\u0003\u0002\u0002",
+    "\u0002X\u01d4\u0003\u0002\u0002\u0002Z\u01df\u0003\u0002\u0002\u0002",
+    "\\\u01ea\u0003\u0002\u0002\u0002^\u01f7\u0003\u0002\u0002\u0002`\u01ff",
+    "\u0003\u0002\u0002\u0002b\u020a\u0003\u0002\u0002\u0002d\u0216\u0003",
+    "\u0002\u0002\u0002f\u021a\u0003\u0002\u0002\u0002h\u0231\u0003\u0002",
+    "\u0002\u0002j\u0234\u0003\u0002\u0002\u0002l\u024a\u0003\u0002\u0002",
+    "\u0002n\u024c\u0003\u0002\u0002\u0002p\u0252\u0003\u0002\u0002\u0002",
+    "r\u025f\u0003\u0002\u0002\u0002t\u0262\u0003\u0002\u0002\u0002v\u026b",
+    "\u0003\u0002\u0002\u0002x\u026f\u0003\u0002\u0002\u0002z\u0274\u0003",
+    "\u0002\u0002\u0002|\u027b\u0003\u0002\u0002\u0002~\u027d\u0003\u0002",
+    "\u0002\u0002\u0080\u027f\u0003\u0002\u0002\u0002\u0082\u0281\u0003\u0002",
+    "\u0002\u0002\u0084\u0283\u0003\u0002\u0002\u0002\u0086\u0285\u0003\u0002",
+    "\u0002\u0002\u0088\u0293\u0003\u0002\u0002\u0002\u008a\u0295\u0003\u0002",
+    "\u0002\u0002\u008c\u02a1\u0003\u0002\u0002\u0002\u008e\u02a5\u0003\u0002",
+    "\u0002\u0002\u0090\u02b1\u0003\u0002\u0002\u0002\u0092\u02b6\u0003\u0002",
+    "\u0002\u0002\u0094\u02ba\u0003\u0002\u0002\u0002\u0096\u02be\u0003\u0002",
+    "\u0002\u0002\u0098\u02c2\u0003\u0002\u0002\u0002\u009a\u02c4\u0003\u0002",
+    "\u0002\u0002\u009c\u02c8\u0003\u0002\u0002\u0002\u009e\u00a0\u0005\u0004",
+    "\u0003\u0002\u009f\u009e\u0003\u0002\u0002\u0002\u00a0\u00a3\u0003\u0002",
+    "\u0002\u0002\u00a1\u009f\u0003\u0002\u0002\u0002\u00a1\u00a2\u0003\u0002",
+    "\u0002\u0002\u00a2\u00a4\u0003\u0002\u0002\u0002\u00a3\u00a1\u0003\u0002",
+    "\u0002\u0002\u00a4\u00a5\u0007\u0002\u0002\u0003\u00a5\u0003\u0003\u0002",
+    "\u0002\u0002\u00a6\u00b3\u0005\u0006\u0004\u0002\u00a7\u00b3\u0005\b",
+    "\u0005\u0002\u00a8\u00b3\u0005\n\u0006\u0002\u00a9\u00b3\u0005\u001c",
     "\u000f\u0002\u00aa\u00b3\u0005\u0016\f\u0002\u00ab\u00b3\u0005 \u0011",
     "\u0002\u00ac\u00b3\u0005&\u0014\u0002\u00ad\u00b3\u0005,\u0017\u0002",
     "\u00ae\u00b3\u00050\u0019\u0002\u00af\u00b3\u00054\u001b\u0002\u00b0",
@@ -254,141 +254,141 @@ var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964",
     "\u0002\u0151\u014f\u0003\u0002\u0002\u0002\u0152\u0156\u0005<\u001f",
     "\u0002\u0153\u0156\u0005> \u0002\u0154\u0156\u0005@!\u0002\u0155\u0152",
     "\u0003\u0002\u0002\u0002\u0155\u0153\u0003\u0002\u0002\u0002\u0155\u0154",
-    "\u0003\u0002\u0002\u0002\u0156)\u0003\u0002\u0002\u0002\u0157\u015c",
-    "\u0005\u008eH\u0002\u0158\u015c\u0005^0\u0002\u0159\u015c\u0005`1\u0002",
-    "\u015a\u015c\u0005d3\u0002\u015b\u0157\u0003\u0002\u0002\u0002\u015b",
-    "\u0158\u0003\u0002\u0002\u0002\u015b\u0159\u0003\u0002\u0002\u0002\u015b",
-    "\u015a\u0003\u0002\u0002\u0002\u015c+\u0003\u0002\u0002\u0002\u015d",
-    "\u015e\u0007\u000b\u0002\u0002\u015e\u0160\u0007L\u0002\u0002\u015f",
-    "\u0161\u0005.\u0018\u0002\u0160\u015f\u0003\u0002\u0002\u0002\u0161",
-    "\u0162\u0003\u0002\u0002\u0002\u0162\u0160\u0003\u0002\u0002\u0002\u0162",
-    "\u0163\u0003\u0002\u0002\u0002\u0163-\u0003\u0002\u0002\u0002\u0164",
-    "\u0169\u0005\u0012\n\u0002\u0165\u0169\u0005\u008eH\u0002\u0166\u0169",
-    "\u0005`1\u0002\u0167\u0169\u0005j6\u0002\u0168\u0164\u0003\u0002\u0002",
-    "\u0002\u0168\u0165\u0003\u0002\u0002\u0002\u0168\u0166\u0003\u0002\u0002",
-    "\u0002\u0168\u0167\u0003\u0002\u0002\u0002\u0169/\u0003\u0002\u0002",
-    "\u0002\u016a\u016b\u0007\u000b\u0002\u0002\u016b\u016c\u0007K\u0002",
-    "\u0002\u016c\u016d\u00052\u001a\u0002\u016d1\u0003\u0002\u0002\u0002",
-    "\u016e\u0172\u00075\u0002\u0002\u016f\u0171\n\u0002\u0002\u0002\u0170",
-    "\u016f\u0003\u0002\u0002\u0002\u0171\u0174\u0003\u0002\u0002\u0002\u0172",
-    "\u0170\u0003\u0002\u0002\u0002\u0172\u0173\u0003\u0002\u0002\u0002\u0173",
-    "3\u0003\u0002\u0002\u0002\u0174\u0172\u0003\u0002\u0002\u0002\u0175",
-    "\u0176\u0007\f\u0002\u0002\u0176\u017a\u0005~@\u0002\u0177\u0179\u0005",
-    "6\u001c\u0002\u0178\u0177\u0003\u0002\u0002\u0002\u0179\u017c\u0003",
-    "\u0002\u0002\u0002\u017a\u0178\u0003\u0002\u0002\u0002\u017a\u017b\u0003",
-    "\u0002\u0002\u0002\u017b\u0180\u0003\u0002\u0002\u0002\u017c\u017a\u0003",
-    "\u0002\u0002\u0002\u017d\u017f\u00058\u001d\u0002\u017e\u017d\u0003",
-    "\u0002\u0002\u0002\u017f\u0182\u0003\u0002\u0002\u0002\u0180\u017e\u0003",
-    "\u0002\u0002\u0002\u0180\u0181\u0003\u0002\u0002\u0002\u01815\u0003",
-    "\u0002\u0002\u0002\u0182\u0180\u0003\u0002\u0002\u0002\u0183\u0189\u0005",
-    "<\u001f\u0002\u0184\u0189\u0005L\'\u0002\u0185\u0189\u0005N(\u0002\u0186",
-    "\u0189\u0005@!\u0002\u0187\u0189\u0005> \u0002\u0188\u0183\u0003\u0002",
-    "\u0002\u0002\u0188\u0184\u0003\u0002\u0002\u0002\u0188\u0185\u0003\u0002",
-    "\u0002\u0002\u0188\u0186\u0003\u0002\u0002\u0002\u0188\u0187\u0003\u0002",
-    "\u0002\u0002\u01897\u0003\u0002\u0002\u0002\u018a\u018e\u0005b2\u0002",
-    "\u018b\u018e\u0005d3\u0002\u018c\u018e\u0005h5\u0002\u018d\u018a\u0003",
-    "\u0002\u0002\u0002\u018d\u018b\u0003\u0002\u0002\u0002\u018d\u018c\u0003",
-    "\u0002\u0002\u0002\u018e9\u0003\u0002\u0002\u0002\u018f\u0190\u0007",
-    "\u000f\u0002\u0002\u0190\u0191\u0005~@\u0002\u0191;\u0003\u0002\u0002",
-    "\u0002\u0192\u0193\u0007\u0010\u0002\u0002\u0193\u0194\u0005~@\u0002",
-    "\u0194=\u0003\u0002\u0002\u0002\u0195\u0196\u0007\u0011\u0002\u0002",
-    "\u0196\u0197\u00079\u0002\u0002\u0197?\u0003\u0002\u0002\u0002\u0198",
-    "\u0199\u0007\u0012\u0002\u0002\u0199\u019a\t\u0003\u0002\u0002\u019a",
-    "A\u0003\u0002\u0002\u0002\u019b\u019c\u0007\u0013\u0002\u0002\u019c",
-    "\u019d\u00079\u0002\u0002\u019dC\u0003\u0002\u0002\u0002\u019e\u019f",
-    "\u0007\u0014\u0002\u0002\u019f\u01a0\u00079\u0002\u0002\u01a0E\u0003",
-    "\u0002\u0002\u0002\u01a1\u01a2\u0007\u0015\u0002\u0002\u01a2\u01a3\u0007",
-    "=\u0002\u0002\u01a3G\u0003\u0002\u0002\u0002\u01a4\u01a5\u0007\u0007",
-    "\u0002\u0002\u01a5\u01a6\u0005~@\u0002\u01a6I\u0003\u0002\u0002\u0002",
-    "\u01a7\u01a8\u0007\u0016\u0002\u0002\u01a8\u01a9\u0007=\u0002\u0002",
-    "\u01a9K\u0003\u0002\u0002\u0002\u01aa\u01ab\u0007\u0017\u0002\u0002",
-    "\u01ab\u01ac\u0005~@\u0002\u01acM\u0003\u0002\u0002\u0002\u01ad\u01ae",
-    "\u0007\u0018\u0002\u0002\u01ae\u01af\u00079\u0002\u0002\u01afO\u0003",
-    "\u0002\u0002\u0002\u01b0\u01b1\u00075\u0002\u0002\u01b1\u01b2\u0005",
-    "\u0080A\u0002\u01b2\u01b6\u0007A\u0002\u0002\u01b3\u01b5\u0005\u0084",
-    "C\u0002\u01b4\u01b3\u0003\u0002\u0002\u0002\u01b5\u01b8\u0003\u0002",
-    "\u0002\u0002\u01b6\u01b4\u0003\u0002\u0002\u0002\u01b6\u01b7\u0003\u0002",
-    "\u0002\u0002\u01b7Q\u0003\u0002\u0002\u0002\u01b8\u01b6\u0003\u0002",
-    "\u0002\u0002\u01b9\u01ba\u00075\u0002\u0002\u01ba\u01bf\u0005\u0080",
-    "A\u0002\u01bb\u01bc\u0007&\u0002\u0002\u01bc\u01be\u0005\u0080A\u0002",
-    "\u01bd\u01bb\u0003\u0002\u0002\u0002\u01be\u01c1\u0003\u0002\u0002\u0002",
-    "\u01bf\u01bd\u0003\u0002\u0002\u0002\u01bf\u01c0\u0003\u0002\u0002\u0002",
-    "\u01c0\u01c3\u0003\u0002\u0002\u0002\u01c1\u01bf\u0003\u0002\u0002\u0002",
-    "\u01c2\u01c4\u0005\u0084C\u0002\u01c3\u01c2\u0003\u0002\u0002\u0002",
-    "\u01c4\u01c5\u0003\u0002\u0002\u0002\u01c5\u01c3\u0003\u0002\u0002\u0002",
-    "\u01c5\u01c6\u0003\u0002\u0002\u0002\u01c6S\u0003\u0002\u0002\u0002",
-    "\u01c7\u01c8\u00075\u0002\u0002\u01c8\u01c9\u0005\u0080A\u0002\u01c9",
-    "\u01ca\u0007\u001f\u0002\u0002\u01ca\u01cc\u0005~@\u0002\u01cb\u01cd",
-    "\u0005\u0086D\u0002\u01cc\u01cb\u0003\u0002\u0002\u0002\u01cc\u01cd",
-    "\u0003\u0002\u0002\u0002\u01cdU\u0003\u0002\u0002\u0002\u01ce\u01cf",
-    "\u00075\u0002\u0002\u01cf\u01d0\u0005\u0080A\u0002\u01d0\u01d1\u0007",
-    "4\u0002\u0002\u01d1\u01d3\u0005\u0088E\u0002\u01d2\u01d4\u00072\u0002",
-    "\u0002\u01d3\u01d2\u0003\u0002\u0002\u0002\u01d3\u01d4\u0003\u0002\u0002",
-    "\u0002\u01d4W\u0003\u0002\u0002\u0002\u01d5\u01d6\u00075\u0002\u0002",
-    "\u01d6\u01d7\u0005\u0080A\u0002\u01d7\u01d8\u0007$\u0002\u0002\u01d8",
-    "\u01dd\u0005\u008aF\u0002\u01d9\u01da\u0007&\u0002\u0002\u01da\u01dc",
-    "\u0005\u008aF\u0002\u01db\u01d9\u0003\u0002\u0002\u0002\u01dc\u01df",
-    "\u0003\u0002\u0002\u0002\u01dd\u01db\u0003\u0002\u0002\u0002\u01dd\u01de",
-    "\u0003\u0002\u0002\u0002\u01deY\u0003\u0002\u0002\u0002\u01df\u01dd",
-    "\u0003\u0002\u0002\u0002\u01e0\u01e1\u00075\u0002\u0002\u01e1\u01e2",
-    "\u0005\u0080A\u0002\u01e2\u01e3\u0007\'\u0002\u0002\u01e3\u01e8\u0005",
-    "\u009cO\u0002\u01e4\u01e5\u0007(\u0002\u0002\u01e5\u01e7\u0005\u009c",
-    "O\u0002\u01e6\u01e4\u0003\u0002\u0002\u0002\u01e7\u01ea\u0003\u0002",
-    "\u0002\u0002\u01e8\u01e6\u0003\u0002\u0002\u0002\u01e8\u01e9\u0003\u0002",
-    "\u0002\u0002\u01e9[\u0003\u0002\u0002\u0002\u01ea\u01e8\u0003\u0002",
-    "\u0002\u0002\u01eb\u01ed\u00075\u0002\u0002\u01ec\u01ee\u0005\u0080",
-    "A\u0002\u01ed\u01ec\u0003\u0002\u0002\u0002\u01ed\u01ee\u0003\u0002",
-    "\u0002\u0002\u01ee\u01ef\u0003\u0002\u0002\u0002\u01ef\u01f0\u0007)",
-    "\u0002\u0002\u01f0\u01f5\u0005~@\u0002\u01f1\u01f2\u0007&\u0002\u0002",
-    "\u01f2\u01f4\u0005~@\u0002\u01f3\u01f1\u0003\u0002\u0002\u0002\u01f4",
-    "\u01f7\u0003\u0002\u0002\u0002\u01f5\u01f3\u0003\u0002\u0002\u0002\u01f5",
-    "\u01f6\u0003\u0002\u0002\u0002\u01f6]\u0003\u0002\u0002\u0002\u01f7",
-    "\u01f5\u0003\u0002\u0002\u0002\u01f8\u01fa\u00075\u0002\u0002\u01f9",
-    "\u01fb\u0005\u0080A\u0002\u01fa\u01f9\u0003\u0002\u0002\u0002\u01fa",
-    "\u01fb\u0003\u0002\u0002\u0002\u01fb\u01fc\u0003\u0002\u0002\u0002\u01fc",
-    "\u01fd\u0005\u0082B\u0002\u01fd\u01fe\u00074\u0002\u0002\u01fe\u01ff",
-    "\u0005\u0088E\u0002\u01ff_\u0003\u0002\u0002\u0002\u0200\u0202\u0007",
-    "5\u0002\u0002\u0201\u0203\u0007=\u0002\u0002\u0202\u0201\u0003\u0002",
-    "\u0002\u0002\u0203\u0204\u0003\u0002\u0002\u0002\u0204\u0202\u0003\u0002",
-    "\u0002\u0002\u0204\u0205\u0003\u0002\u0002\u0002\u0205\u0206\u0003\u0002",
-    "\u0002\u0002\u0206\u0207\u0005\u0082B\u0002\u0207\u0208\u00074\u0002",
-    "\u0002\u0208\u0209\u0005\u0088E\u0002\u0209a\u0003\u0002\u0002\u0002",
-    "\u020a\u020c\u00075\u0002\u0002\u020b\u020d\u0005\u0080A\u0002\u020c",
-    "\u020b\u0003\u0002\u0002\u0002\u020c\u020d\u0003\u0002\u0002\u0002\u020d",
-    "\u020e\u0003\u0002\u0002\u0002\u020e\u020f\u00078\u0002\u0002\u020f",
-    "\u0211\u00079\u0002\u0002\u0210\u0212\u00079\u0002\u0002\u0211\u0210",
-    "\u0003\u0002\u0002\u0002\u0211\u0212\u0003\u0002\u0002\u0002\u0212\u0214",
-    "\u0003\u0002\u0002\u0002\u0213\u0215\u0007=\u0002\u0002\u0214\u0213",
-    "\u0003\u0002\u0002\u0002\u0214\u0215\u0003\u0002\u0002\u0002\u0215c",
-    "\u0003\u0002\u0002\u0002\u0216\u0217\u00075\u0002\u0002\u0217\u0218",
-    "\u00073\u0002\u0002\u0218\u0219\t\u0004\u0002\u0002\u0219e\u0003\u0002",
-    "\u0002\u0002\u021a\u021b\u00075\u0002\u0002\u021b\u021c\u0005\u0080",
-    "A\u0002\u021c\u0220\u0007A\u0002\u0002\u021d\u021f\u0005\u0084C\u0002",
-    "\u021e\u021d\u0003\u0002\u0002\u0002\u021f\u0222\u0003\u0002\u0002\u0002",
-    "\u0220\u021e\u0003\u0002\u0002\u0002\u0220\u0221\u0003\u0002\u0002\u0002",
-    "\u0221\u0223\u0003\u0002\u0002\u0002\u0222\u0220\u0003\u0002\u0002\u0002",
-    "\u0223\u0228\u0005\u009cO\u0002\u0224\u0225\u0007(\u0002\u0002\u0225",
-    "\u0227\u0005\u009cO\u0002\u0226\u0224\u0003\u0002\u0002\u0002\u0227",
-    "\u022a\u0003\u0002\u0002\u0002\u0228\u0226\u0003\u0002\u0002\u0002\u0228",
-    "\u0229\u0003\u0002\u0002\u0002\u0229\u022c\u0003\u0002\u0002\u0002\u022a",
-    "\u0228\u0003\u0002\u0002\u0002\u022b\u022d\u00079\u0002\u0002\u022c",
-    "\u022b\u0003\u0002\u0002\u0002\u022c\u022d\u0003\u0002\u0002\u0002\u022d",
-    "\u022f\u0003\u0002\u0002\u0002\u022e\u0230\u00079\u0002\u0002\u022f",
-    "\u022e\u0003\u0002\u0002\u0002\u022f\u0230\u0003\u0002\u0002\u0002\u0230",
-    "g\u0003\u0002\u0002\u0002\u0231\u0232\u00075\u0002\u0002\u0232\u0233",
-    "\u0005\u0080A\u0002\u0233i\u0003\u0002\u0002\u0002\u0234\u0236\u0007",
-    "5\u0002\u0002\u0235\u0237\t\u0005\u0002\u0002\u0236\u0235\u0003\u0002",
-    "\u0002\u0002\u0236\u0237\u0003\u0002\u0002\u0002\u0237\u023a\u0003\u0002",
-    "\u0002\u0002\u0238\u023b\u0005l7\u0002\u0239\u023b\u0005n8\u0002\u023a",
-    "\u0238\u0003\u0002\u0002\u0002\u023a\u0239\u0003\u0002\u0002\u0002\u023b",
-    "k\u0003\u0002\u0002\u0002\u023c\u023e\u0005\u008cG\u0002\u023d\u023f",
-    "\u0005p9\u0002\u023e\u023d\u0003\u0002\u0002\u0002\u023e\u023f\u0003",
-    "\u0002\u0002\u0002\u023f\u024b\u0003\u0002\u0002\u0002\u0240\u0241\u0005",
-    "\u008cG\u0002\u0241\u0242\u0007&\u0002\u0002\u0242\u0244\u0003\u0002",
-    "\u0002\u0002\u0243\u0240\u0003\u0002\u0002\u0002\u0244\u0245\u0003\u0002",
-    "\u0002\u0002\u0245\u0243\u0003\u0002\u0002\u0002\u0245\u0246\u0003\u0002",
-    "\u0002\u0002\u0246\u0247\u0003\u0002\u0002\u0002\u0247\u0248\u0005\u008c",
-    "G\u0002\u0248\u0249\u0005p9\u0002\u0249\u024b\u0003\u0002\u0002\u0002",
+    "\u0003\u0002\u0002\u0002\u0156)\u0003\u0002\u0002\u0002\u0157\u015b",
+    "\u0005\u008eH\u0002\u0158\u015b\u0005`1\u0002\u0159\u015b\u0005d3\u0002",
+    "\u015a\u0157\u0003\u0002\u0002\u0002\u015a\u0158\u0003\u0002\u0002\u0002",
+    "\u015a\u0159\u0003\u0002\u0002\u0002\u015b+\u0003\u0002\u0002\u0002",
+    "\u015c\u015d\u0007\u000b\u0002\u0002\u015d\u015f\u0007L\u0002\u0002",
+    "\u015e\u0160\u0005.\u0018\u0002\u015f\u015e\u0003\u0002\u0002\u0002",
+    "\u0160\u0161\u0003\u0002\u0002\u0002\u0161\u015f\u0003\u0002\u0002\u0002",
+    "\u0161\u0162\u0003\u0002\u0002\u0002\u0162-\u0003\u0002\u0002\u0002",
+    "\u0163\u0168\u0005\u0012\n\u0002\u0164\u0168\u0005\u008eH\u0002\u0165",
+    "\u0168\u0005`1\u0002\u0166\u0168\u0005j6\u0002\u0167\u0163\u0003\u0002",
+    "\u0002\u0002\u0167\u0164\u0003\u0002\u0002\u0002\u0167\u0165\u0003\u0002",
+    "\u0002\u0002\u0167\u0166\u0003\u0002\u0002\u0002\u0168/\u0003\u0002",
+    "\u0002\u0002\u0169\u016a\u0007\u000b\u0002\u0002\u016a\u016b\u0007K",
+    "\u0002\u0002\u016b\u016c\u00052\u001a\u0002\u016c1\u0003\u0002\u0002",
+    "\u0002\u016d\u0171\u00075\u0002\u0002\u016e\u0170\n\u0002\u0002\u0002",
+    "\u016f\u016e\u0003\u0002\u0002\u0002\u0170\u0173\u0003\u0002\u0002\u0002",
+    "\u0171\u016f\u0003\u0002\u0002\u0002\u0171\u0172\u0003\u0002\u0002\u0002",
+    "\u01723\u0003\u0002\u0002\u0002\u0173\u0171\u0003\u0002\u0002\u0002",
+    "\u0174\u0175\u0007\f\u0002\u0002\u0175\u0179\u0005~@\u0002\u0176\u0178",
+    "\u00056\u001c\u0002\u0177\u0176\u0003\u0002\u0002\u0002\u0178\u017b",
+    "\u0003\u0002\u0002\u0002\u0179\u0177\u0003\u0002\u0002\u0002\u0179\u017a",
+    "\u0003\u0002\u0002\u0002\u017a\u017f\u0003\u0002\u0002\u0002\u017b\u0179",
+    "\u0003\u0002\u0002\u0002\u017c\u017e\u00058\u001d\u0002\u017d\u017c",
+    "\u0003\u0002\u0002\u0002\u017e\u0181\u0003\u0002\u0002\u0002\u017f\u017d",
+    "\u0003\u0002\u0002\u0002\u017f\u0180\u0003\u0002\u0002\u0002\u01805",
+    "\u0003\u0002\u0002\u0002\u0181\u017f\u0003\u0002\u0002\u0002\u0182\u0188",
+    "\u0005<\u001f\u0002\u0183\u0188\u0005L\'\u0002\u0184\u0188\u0005N(\u0002",
+    "\u0185\u0188\u0005@!\u0002\u0186\u0188\u0005> \u0002\u0187\u0182\u0003",
+    "\u0002\u0002\u0002\u0187\u0183\u0003\u0002\u0002\u0002\u0187\u0184\u0003",
+    "\u0002\u0002\u0002\u0187\u0185\u0003\u0002\u0002\u0002\u0187\u0186\u0003",
+    "\u0002\u0002\u0002\u01887\u0003\u0002\u0002\u0002\u0189\u018d\u0005",
+    "b2\u0002\u018a\u018d\u0005d3\u0002\u018b\u018d\u0005h5\u0002\u018c\u0189",
+    "\u0003\u0002\u0002\u0002\u018c\u018a\u0003\u0002\u0002\u0002\u018c\u018b",
+    "\u0003\u0002\u0002\u0002\u018d9\u0003\u0002\u0002\u0002\u018e\u018f",
+    "\u0007\u000f\u0002\u0002\u018f\u0190\u0005~@\u0002\u0190;\u0003\u0002",
+    "\u0002\u0002\u0191\u0192\u0007\u0010\u0002\u0002\u0192\u0193\u0005~",
+    "@\u0002\u0193=\u0003\u0002\u0002\u0002\u0194\u0195\u0007\u0011\u0002",
+    "\u0002\u0195\u0196\u00079\u0002\u0002\u0196?\u0003\u0002\u0002\u0002",
+    "\u0197\u0198\u0007\u0012\u0002\u0002\u0198\u0199\t\u0003\u0002\u0002",
+    "\u0199A\u0003\u0002\u0002\u0002\u019a\u019b\u0007\u0013\u0002\u0002",
+    "\u019b\u019c\u00079\u0002\u0002\u019cC\u0003\u0002\u0002\u0002\u019d",
+    "\u019e\u0007\u0014\u0002\u0002\u019e\u019f\u00079\u0002\u0002\u019f",
+    "E\u0003\u0002\u0002\u0002\u01a0\u01a1\u0007\u0015\u0002\u0002\u01a1",
+    "\u01a2\u0007=\u0002\u0002\u01a2G\u0003\u0002\u0002\u0002\u01a3\u01a4",
+    "\u0007\u0007\u0002\u0002\u01a4\u01a5\u0005~@\u0002\u01a5I\u0003\u0002",
+    "\u0002\u0002\u01a6\u01a7\u0007\u0016\u0002\u0002\u01a7\u01a8\u0007=",
+    "\u0002\u0002\u01a8K\u0003\u0002\u0002\u0002\u01a9\u01aa\u0007\u0017",
+    "\u0002\u0002\u01aa\u01ab\u0005~@\u0002\u01abM\u0003\u0002\u0002\u0002",
+    "\u01ac\u01ad\u0007\u0018\u0002\u0002\u01ad\u01ae\u00079\u0002\u0002",
+    "\u01aeO\u0003\u0002\u0002\u0002\u01af\u01b0\u00075\u0002\u0002\u01b0",
+    "\u01b1\u0005\u0080A\u0002\u01b1\u01b5\u0007A\u0002\u0002\u01b2\u01b4",
+    "\u0005\u0084C\u0002\u01b3\u01b2\u0003\u0002\u0002\u0002\u01b4\u01b7",
+    "\u0003\u0002\u0002\u0002\u01b5\u01b3\u0003\u0002\u0002\u0002\u01b5\u01b6",
+    "\u0003\u0002\u0002\u0002\u01b6Q\u0003\u0002\u0002\u0002\u01b7\u01b5",
+    "\u0003\u0002\u0002\u0002\u01b8\u01b9\u00075\u0002\u0002\u01b9\u01be",
+    "\u0005\u0080A\u0002\u01ba\u01bb\u0007&\u0002\u0002\u01bb\u01bd\u0005",
+    "\u0080A\u0002\u01bc\u01ba\u0003\u0002\u0002\u0002\u01bd\u01c0\u0003",
+    "\u0002\u0002\u0002\u01be\u01bc\u0003\u0002\u0002\u0002\u01be\u01bf\u0003",
+    "\u0002\u0002\u0002\u01bf\u01c2\u0003\u0002\u0002\u0002\u01c0\u01be\u0003",
+    "\u0002\u0002\u0002\u01c1\u01c3\u0005\u0084C\u0002\u01c2\u01c1\u0003",
+    "\u0002\u0002\u0002\u01c3\u01c4\u0003\u0002\u0002\u0002\u01c4\u01c2\u0003",
+    "\u0002\u0002\u0002\u01c4\u01c5\u0003\u0002\u0002\u0002\u01c5S\u0003",
+    "\u0002\u0002\u0002\u01c6\u01c7\u00075\u0002\u0002\u01c7\u01c8\u0005",
+    "\u0080A\u0002\u01c8\u01c9\u0007\u001f\u0002\u0002\u01c9\u01cb\u0005",
+    "~@\u0002\u01ca\u01cc\u0005\u0086D\u0002\u01cb\u01ca\u0003\u0002\u0002",
+    "\u0002\u01cb\u01cc\u0003\u0002\u0002\u0002\u01ccU\u0003\u0002\u0002",
+    "\u0002\u01cd\u01ce\u00075\u0002\u0002\u01ce\u01cf\u0005\u0080A\u0002",
+    "\u01cf\u01d0\u00074\u0002\u0002\u01d0\u01d2\u0005\u0088E\u0002\u01d1",
+    "\u01d3\u00072\u0002\u0002\u01d2\u01d1\u0003\u0002\u0002\u0002\u01d2",
+    "\u01d3\u0003\u0002\u0002\u0002\u01d3W\u0003\u0002\u0002\u0002\u01d4",
+    "\u01d5\u00075\u0002\u0002\u01d5\u01d6\u0005\u0080A\u0002\u01d6\u01d7",
+    "\u0007$\u0002\u0002\u01d7\u01dc\u0005\u008aF\u0002\u01d8\u01d9\u0007",
+    "&\u0002\u0002\u01d9\u01db\u0005\u008aF\u0002\u01da\u01d8\u0003\u0002",
+    "\u0002\u0002\u01db\u01de\u0003\u0002\u0002\u0002\u01dc\u01da\u0003\u0002",
+    "\u0002\u0002\u01dc\u01dd\u0003\u0002\u0002\u0002\u01ddY\u0003\u0002",
+    "\u0002\u0002\u01de\u01dc\u0003\u0002\u0002\u0002\u01df\u01e0\u00075",
+    "\u0002\u0002\u01e0\u01e1\u0005\u0080A\u0002\u01e1\u01e2\u0007\'\u0002",
+    "\u0002\u01e2\u01e7\u0005\u009cO\u0002\u01e3\u01e4\u0007(\u0002\u0002",
+    "\u01e4\u01e6\u0005\u009cO\u0002\u01e5\u01e3\u0003\u0002\u0002\u0002",
+    "\u01e6\u01e9\u0003\u0002\u0002\u0002\u01e7\u01e5\u0003\u0002\u0002\u0002",
+    "\u01e7\u01e8\u0003\u0002\u0002\u0002\u01e8[\u0003\u0002\u0002\u0002",
+    "\u01e9\u01e7\u0003\u0002\u0002\u0002\u01ea\u01ec\u00075\u0002\u0002",
+    "\u01eb\u01ed\u0005\u0080A\u0002\u01ec\u01eb\u0003\u0002\u0002\u0002",
+    "\u01ec\u01ed\u0003\u0002\u0002\u0002\u01ed\u01ee\u0003\u0002\u0002\u0002",
+    "\u01ee\u01ef\u0007)\u0002\u0002\u01ef\u01f4\u0005~@\u0002\u01f0\u01f1",
+    "\u0007&\u0002\u0002\u01f1\u01f3\u0005~@\u0002\u01f2\u01f0\u0003\u0002",
+    "\u0002\u0002\u01f3\u01f6\u0003\u0002\u0002\u0002\u01f4\u01f2\u0003\u0002",
+    "\u0002\u0002\u01f4\u01f5\u0003\u0002\u0002\u0002\u01f5]\u0003\u0002",
+    "\u0002\u0002\u01f6\u01f4\u0003\u0002\u0002\u0002\u01f7\u01f9\u00075",
+    "\u0002\u0002\u01f8\u01fa\u0005\u0080A\u0002\u01f9\u01f8\u0003\u0002",
+    "\u0002\u0002\u01f9\u01fa\u0003\u0002\u0002\u0002\u01fa\u01fb\u0003\u0002",
+    "\u0002\u0002\u01fb\u01fc\u0005\u0082B\u0002\u01fc\u01fd\u00074\u0002",
+    "\u0002\u01fd\u01fe\u0005\u0088E\u0002\u01fe_\u0003\u0002\u0002\u0002",
+    "\u01ff\u0203\u00075\u0002\u0002\u0200\u0202\u0007=\u0002\u0002\u0201",
+    "\u0200\u0003\u0002\u0002\u0002\u0202\u0205\u0003\u0002\u0002\u0002\u0203",
+    "\u0201\u0003\u0002\u0002\u0002\u0203\u0204\u0003\u0002\u0002\u0002\u0204",
+    "\u0206\u0003\u0002\u0002\u0002\u0205\u0203\u0003\u0002\u0002\u0002\u0206",
+    "\u0207\u0005\u0082B\u0002\u0207\u0208\u00074\u0002\u0002\u0208\u0209",
+    "\u0005\u0088E\u0002\u0209a\u0003\u0002\u0002\u0002\u020a\u020c\u0007",
+    "5\u0002\u0002\u020b\u020d\u0005\u0080A\u0002\u020c\u020b\u0003\u0002",
+    "\u0002\u0002\u020c\u020d\u0003\u0002\u0002\u0002\u020d\u020e\u0003\u0002",
+    "\u0002\u0002\u020e\u020f\u00078\u0002\u0002\u020f\u0211\u00079\u0002",
+    "\u0002\u0210\u0212\u00079\u0002\u0002\u0211\u0210\u0003\u0002\u0002",
+    "\u0002\u0211\u0212\u0003\u0002\u0002\u0002\u0212\u0214\u0003\u0002\u0002",
+    "\u0002\u0213\u0215\u0007=\u0002\u0002\u0214\u0213\u0003\u0002\u0002",
+    "\u0002\u0214\u0215\u0003\u0002\u0002\u0002\u0215c\u0003\u0002\u0002",
+    "\u0002\u0216\u0217\u00075\u0002\u0002\u0217\u0218\u00073\u0002\u0002",
+    "\u0218\u0219\t\u0004\u0002\u0002\u0219e\u0003\u0002\u0002\u0002\u021a",
+    "\u021b\u00075\u0002\u0002\u021b\u021c\u0005\u0080A\u0002\u021c\u0220",
+    "\u0007A\u0002\u0002\u021d\u021f\u0005\u0084C\u0002\u021e\u021d\u0003",
+    "\u0002\u0002\u0002\u021f\u0222\u0003\u0002\u0002\u0002\u0220\u021e\u0003",
+    "\u0002\u0002\u0002\u0220\u0221\u0003\u0002\u0002\u0002\u0221\u0223\u0003",
+    "\u0002\u0002\u0002\u0222\u0220\u0003\u0002\u0002\u0002\u0223\u0228\u0005",
+    "\u009cO\u0002\u0224\u0225\u0007(\u0002\u0002\u0225\u0227\u0005\u009c",
+    "O\u0002\u0226\u0224\u0003\u0002\u0002\u0002\u0227\u022a\u0003\u0002",
+    "\u0002\u0002\u0228\u0226\u0003\u0002\u0002\u0002\u0228\u0229\u0003\u0002",
+    "\u0002\u0002\u0229\u022c\u0003\u0002\u0002\u0002\u022a\u0228\u0003\u0002",
+    "\u0002\u0002\u022b\u022d\u00079\u0002\u0002\u022c\u022b\u0003\u0002",
+    "\u0002\u0002\u022c\u022d\u0003\u0002\u0002\u0002\u022d\u022f\u0003\u0002",
+    "\u0002\u0002\u022e\u0230\u00079\u0002\u0002\u022f\u022e\u0003\u0002",
+    "\u0002\u0002\u022f\u0230\u0003\u0002\u0002\u0002\u0230g\u0003\u0002",
+    "\u0002\u0002\u0231\u0232\u00075\u0002\u0002\u0232\u0233\u0005\u0080",
+    "A\u0002\u0233i\u0003\u0002\u0002\u0002\u0234\u0236\u00075\u0002\u0002",
+    "\u0235\u0237\t\u0005\u0002\u0002\u0236\u0235\u0003\u0002\u0002\u0002",
+    "\u0236\u0237\u0003\u0002\u0002\u0002\u0237\u023a\u0003\u0002\u0002\u0002",
+    "\u0238\u023b\u0005l7\u0002\u0239\u023b\u0005n8\u0002\u023a\u0238\u0003",
+    "\u0002\u0002\u0002\u023a\u0239\u0003\u0002\u0002\u0002\u023bk\u0003",
+    "\u0002\u0002\u0002\u023c\u023e\u0005\u008cG\u0002\u023d\u023f\u0005",
+    "p9\u0002\u023e\u023d\u0003\u0002\u0002\u0002\u023e\u023f\u0003\u0002",
+    "\u0002\u0002\u023f\u024b\u0003\u0002\u0002\u0002\u0240\u0241\u0005\u008c",
+    "G\u0002\u0241\u0242\u0007&\u0002\u0002\u0242\u0244\u0003\u0002\u0002",
+    "\u0002\u0243\u0240\u0003\u0002\u0002\u0002\u0244\u0245\u0003\u0002\u0002",
+    "\u0002\u0245\u0243\u0003\u0002\u0002\u0002\u0245\u0246\u0003\u0002\u0002",
+    "\u0002\u0246\u0247\u0003\u0002\u0002\u0002\u0247\u0248\u0005\u008cG",
+    "\u0002\u0248\u0249\u0005p9\u0002\u0249\u024b\u0003\u0002\u0002\u0002",
     "\u024a\u023c\u0003\u0002\u0002\u0002\u024a\u0243\u0003\u0002\u0002\u0002",
     "\u024bm\u0003\u0002\u0002\u0002\u024c\u024d\u0007.\u0002\u0002\u024d",
     "\u0250\u0005p9\u0002\u024e\u024f\u0007/\u0002\u0002\u024f\u0251\u0005",
@@ -467,8 +467,8 @@ var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964",
     "\u0002\u0002\u0002\u02c9\u009d\u0003\u0002\u0002\u0002M\u00a1\u00b2",
     "\u00be\u00c3\u00cb\u00d1\u00d9\u00df\u00e7\u00ed\u00f4\u0100\u0104\u010b",
     "\u0111\u0118\u011d\u0124\u012a\u0131\u0137\u013d\u0142\u0149\u014f\u0155",
-    "\u015b\u0162\u0168\u0172\u017a\u0180\u0188\u018d\u01b6\u01bf\u01c5\u01cc",
-    "\u01d3\u01dd\u01e8\u01ed\u01f5\u01fa\u0204\u020c\u0211\u0214\u0220\u0228",
+    "\u015a\u0161\u0167\u0171\u0179\u017f\u0187\u018c\u01b5\u01be\u01c4\u01cb",
+    "\u01d2\u01dc\u01e7\u01ec\u01f4\u01f9\u0203\u020c\u0211\u0214\u0220\u0228",
     "\u022c\u022f\u0236\u023a\u023e\u0245\u024a\u0250\u0256\u025b\u025d\u0268",
     "\u0272\u027b\u0293\u0298\u029e\u02a3\u02a9\u02ac\u02af\u02b4\u02bc\u02c2",
     "\u02c8"].join("");
@@ -2943,10 +2943,6 @@ CsRuleContext.prototype.concept = function() {
     return this.getTypedRuleContext(ConceptContext,0);
 };
 
-CsRuleContext.prototype.caretValueRule = function() {
-    return this.getTypedRuleContext(CaretValueRuleContext,0);
-};
-
 CsRuleContext.prototype.codeCaretValueRule = function() {
     return this.getTypedRuleContext(CodeCaretValueRuleContext,0);
 };
@@ -2985,7 +2981,7 @@ FSHParser.prototype.csRule = function() {
     var localctx = new CsRuleContext(this, this._ctx, this.state);
     this.enterRule(localctx, 40, FSHParser.RULE_csRule);
     try {
-        this.state = 345;
+        this.state = 344;
         this._errHandler.sync(this);
         var la_ = this._interp.adaptivePredict(this._input,26,this._ctx);
         switch(la_) {
@@ -2998,18 +2994,12 @@ FSHParser.prototype.csRule = function() {
         case 2:
             this.enterOuterAlt(localctx, 2);
             this.state = 342;
-            this.caretValueRule();
+            this.codeCaretValueRule();
             break;
 
         case 3:
             this.enterOuterAlt(localctx, 3);
             this.state = 343;
-            this.codeCaretValueRule();
-            break;
-
-        case 4:
-            this.enterOuterAlt(localctx, 4);
-            this.state = 344;
             this.insertRule();
             break;
 
@@ -3096,17 +3086,17 @@ FSHParser.prototype.ruleSet = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 347;
+        this.state = 346;
         this.match(FSHParser.KW_RULESET);
-        this.state = 348;
+        this.state = 347;
         this.match(FSHParser.RULESET_REFERENCE);
-        this.state = 350; 
+        this.state = 349; 
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         do {
-            this.state = 349;
+            this.state = 348;
             this.ruleSetRule();
-            this.state = 352; 
+            this.state = 351; 
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         } while(_la===FSHParser.STAR);
@@ -3187,31 +3177,31 @@ FSHParser.prototype.ruleSetRule = function() {
     var localctx = new RuleSetRuleContext(this, this._ctx, this.state);
     this.enterRule(localctx, 44, FSHParser.RULE_ruleSetRule);
     try {
-        this.state = 358;
+        this.state = 357;
         this._errHandler.sync(this);
         var la_ = this._interp.adaptivePredict(this._input,28,this._ctx);
         switch(la_) {
         case 1:
             this.enterOuterAlt(localctx, 1);
-            this.state = 354;
+            this.state = 353;
             this.sdRule();
             break;
 
         case 2:
             this.enterOuterAlt(localctx, 2);
-            this.state = 355;
+            this.state = 354;
             this.concept();
             break;
 
         case 3:
             this.enterOuterAlt(localctx, 3);
-            this.state = 356;
+            this.state = 355;
             this.codeCaretValueRule();
             break;
 
         case 4:
             this.enterOuterAlt(localctx, 4);
-            this.state = 357;
+            this.state = 356;
             this.vsComponent();
             break;
 
@@ -3290,11 +3280,11 @@ FSHParser.prototype.paramRuleSet = function() {
     this.enterRule(localctx, 46, FSHParser.RULE_paramRuleSet);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 360;
+        this.state = 359;
         this.match(FSHParser.KW_RULESET);
-        this.state = 361;
+        this.state = 360;
         this.match(FSHParser.PARAM_RULESET_REFERENCE);
-        this.state = 362;
+        this.state = 361;
         this.paramRuleSetContent();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -3471,14 +3461,14 @@ FSHParser.prototype.paramRuleSetContent = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 364;
+        this.state = 363;
         this.match(FSHParser.STAR);
-        this.state = 368;
+        this.state = 367;
         this._errHandler.sync(this);
         var _alt = this._interp.adaptivePredict(this._input,29,this._ctx)
         while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) {
             if(_alt===1) {
-                this.state = 365;
+                this.state = 364;
                 _la = this._input.LA(1);
                 if(_la<=0 || (((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_ALIAS) | (1 << FSHParser.KW_PROFILE) | (1 << FSHParser.KW_EXTENSION) | (1 << FSHParser.KW_INSTANCE) | (1 << FSHParser.KW_INVARIANT) | (1 << FSHParser.KW_VALUESET) | (1 << FSHParser.KW_CODESYSTEM) | (1 << FSHParser.KW_RULESET) | (1 << FSHParser.KW_MAPPING))) !== 0)) {
                 this._errHandler.recoverInline(this);
@@ -3488,7 +3478,7 @@ FSHParser.prototype.paramRuleSetContent = function() {
                     this.consume();
                 } 
             }
-            this.state = 370;
+            this.state = 369;
             this._errHandler.sync(this);
             _alt = this._interp.adaptivePredict(this._input,29,this._ctx);
         }
@@ -3586,27 +3576,27 @@ FSHParser.prototype.mapping = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 371;
+        this.state = 370;
         this.match(FSHParser.KW_MAPPING);
-        this.state = 372;
+        this.state = 371;
         this.name();
-        this.state = 376;
+        this.state = 375;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_ID) | (1 << FSHParser.KW_TITLE) | (1 << FSHParser.KW_DESCRIPTION) | (1 << FSHParser.KW_SOURCE) | (1 << FSHParser.KW_TARGET))) !== 0)) {
-            this.state = 373;
+            this.state = 372;
             this.mappingMetadata();
-            this.state = 378;
+            this.state = 377;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
-        this.state = 382;
+        this.state = 381;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.STAR) {
-            this.state = 379;
+            this.state = 378;
             this.mappingEntityRule();
-            this.state = 384;
+            this.state = 383;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -3691,32 +3681,32 @@ FSHParser.prototype.mappingMetadata = function() {
     var localctx = new MappingMetadataContext(this, this._ctx, this.state);
     this.enterRule(localctx, 52, FSHParser.RULE_mappingMetadata);
     try {
-        this.state = 390;
+        this.state = 389;
         this._errHandler.sync(this);
         switch(this._input.LA(1)) {
         case FSHParser.KW_ID:
             this.enterOuterAlt(localctx, 1);
-            this.state = 385;
+            this.state = 384;
             this.id();
             break;
         case FSHParser.KW_SOURCE:
             this.enterOuterAlt(localctx, 2);
-            this.state = 386;
+            this.state = 385;
             this.source();
             break;
         case FSHParser.KW_TARGET:
             this.enterOuterAlt(localctx, 3);
-            this.state = 387;
+            this.state = 386;
             this.target();
             break;
         case FSHParser.KW_DESCRIPTION:
             this.enterOuterAlt(localctx, 4);
-            this.state = 388;
+            this.state = 387;
             this.description();
             break;
         case FSHParser.KW_TITLE:
             this.enterOuterAlt(localctx, 5);
-            this.state = 389;
+            this.state = 388;
             this.title();
             break;
         default:
@@ -3795,25 +3785,25 @@ FSHParser.prototype.mappingEntityRule = function() {
     var localctx = new MappingEntityRuleContext(this, this._ctx, this.state);
     this.enterRule(localctx, 54, FSHParser.RULE_mappingEntityRule);
     try {
-        this.state = 395;
+        this.state = 394;
         this._errHandler.sync(this);
         var la_ = this._interp.adaptivePredict(this._input,33,this._ctx);
         switch(la_) {
         case 1:
             this.enterOuterAlt(localctx, 1);
-            this.state = 392;
+            this.state = 391;
             this.mappingRule();
             break;
 
         case 2:
             this.enterOuterAlt(localctx, 2);
-            this.state = 393;
+            this.state = 392;
             this.insertRule();
             break;
 
         case 3:
             this.enterOuterAlt(localctx, 3);
-            this.state = 394;
+            this.state = 393;
             this.pathRule();
             break;
 
@@ -3888,9 +3878,9 @@ FSHParser.prototype.parent = function() {
     this.enterRule(localctx, 56, FSHParser.RULE_parent);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 397;
+        this.state = 396;
         this.match(FSHParser.KW_PARENT);
-        this.state = 398;
+        this.state = 397;
         this.name();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -3962,9 +3952,9 @@ FSHParser.prototype.id = function() {
     this.enterRule(localctx, 58, FSHParser.RULE_id);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 400;
+        this.state = 399;
         this.match(FSHParser.KW_ID);
-        this.state = 401;
+        this.state = 400;
         this.name();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4036,9 +4026,9 @@ FSHParser.prototype.title = function() {
     this.enterRule(localctx, 60, FSHParser.RULE_title);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 403;
+        this.state = 402;
         this.match(FSHParser.KW_TITLE);
-        this.state = 404;
+        this.state = 403;
         this.match(FSHParser.STRING);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4115,9 +4105,9 @@ FSHParser.prototype.description = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 406;
+        this.state = 405;
         this.match(FSHParser.KW_DESCRIPTION);
-        this.state = 407;
+        this.state = 406;
         _la = this._input.LA(1);
         if(!(_la===FSHParser.STRING || _la===FSHParser.MULTILINE_STRING)) {
         this._errHandler.recoverInline(this);
@@ -4196,9 +4186,9 @@ FSHParser.prototype.expression = function() {
     this.enterRule(localctx, 64, FSHParser.RULE_expression);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 409;
+        this.state = 408;
         this.match(FSHParser.KW_EXPRESSION);
-        this.state = 410;
+        this.state = 409;
         this.match(FSHParser.STRING);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4270,9 +4260,9 @@ FSHParser.prototype.xpath = function() {
     this.enterRule(localctx, 66, FSHParser.RULE_xpath);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 412;
+        this.state = 411;
         this.match(FSHParser.KW_XPATH);
-        this.state = 413;
+        this.state = 412;
         this.match(FSHParser.STRING);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4344,9 +4334,9 @@ FSHParser.prototype.severity = function() {
     this.enterRule(localctx, 68, FSHParser.RULE_severity);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 415;
+        this.state = 414;
         this.match(FSHParser.KW_SEVERITY);
-        this.state = 416;
+        this.state = 415;
         this.match(FSHParser.CODE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4418,9 +4408,9 @@ FSHParser.prototype.instanceOf = function() {
     this.enterRule(localctx, 70, FSHParser.RULE_instanceOf);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 418;
+        this.state = 417;
         this.match(FSHParser.KW_INSTANCEOF);
-        this.state = 419;
+        this.state = 418;
         this.name();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4492,9 +4482,9 @@ FSHParser.prototype.usage = function() {
     this.enterRule(localctx, 72, FSHParser.RULE_usage);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 421;
+        this.state = 420;
         this.match(FSHParser.KW_USAGE);
-        this.state = 422;
+        this.state = 421;
         this.match(FSHParser.CODE);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4566,9 +4556,9 @@ FSHParser.prototype.source = function() {
     this.enterRule(localctx, 74, FSHParser.RULE_source);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 424;
+        this.state = 423;
         this.match(FSHParser.KW_SOURCE);
-        this.state = 425;
+        this.state = 424;
         this.name();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4640,9 +4630,9 @@ FSHParser.prototype.target = function() {
     this.enterRule(localctx, 76, FSHParser.RULE_target);
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 427;
+        this.state = 426;
         this.match(FSHParser.KW_TARGET);
-        this.state = 428;
+        this.state = 427;
         this.match(FSHParser.STRING);
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -4730,19 +4720,19 @@ FSHParser.prototype.cardRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 430;
+        this.state = 429;
         this.match(FSHParser.STAR);
-        this.state = 431;
+        this.state = 430;
         this.path();
-        this.state = 432;
+        this.state = 431;
         this.match(FSHParser.CARD);
-        this.state = 436;
+        this.state = 435;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_MOD) | (1 << FSHParser.KW_MS) | (1 << FSHParser.KW_SU) | (1 << FSHParser.KW_TU) | (1 << FSHParser.KW_NORMATIVE) | (1 << FSHParser.KW_DRAFT))) !== 0)) {
-            this.state = 433;
+            this.state = 432;
             this.flag();
-            this.state = 438;
+            this.state = 437;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -4847,29 +4837,29 @@ FSHParser.prototype.flagRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 439;
+        this.state = 438;
         this.match(FSHParser.STAR);
-        this.state = 440;
+        this.state = 439;
         this.path();
-        this.state = 445;
+        this.state = 444;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.KW_AND) {
-            this.state = 441;
+            this.state = 440;
             this.match(FSHParser.KW_AND);
-            this.state = 442;
+            this.state = 441;
             this.path();
-            this.state = 447;
+            this.state = 446;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
-        this.state = 449; 
+        this.state = 448; 
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         do {
-            this.state = 448;
+            this.state = 447;
             this.flag();
-            this.state = 451; 
+            this.state = 450; 
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         } while((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << FSHParser.KW_MOD) | (1 << FSHParser.KW_MS) | (1 << FSHParser.KW_SU) | (1 << FSHParser.KW_TU) | (1 << FSHParser.KW_NORMATIVE) | (1 << FSHParser.KW_DRAFT))) !== 0));
@@ -4956,19 +4946,19 @@ FSHParser.prototype.valueSetRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 453;
+        this.state = 452;
         this.match(FSHParser.STAR);
-        this.state = 454;
+        this.state = 453;
         this.path();
-        this.state = 455;
+        this.state = 454;
         this.match(FSHParser.KW_FROM);
-        this.state = 456;
+        this.state = 455;
         this.name();
-        this.state = 458;
+        this.state = 457;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(((((_la - 30)) & ~0x1f) == 0 && ((1 << (_la - 30)) & ((1 << (FSHParser.KW_EXAMPLE - 30)) | (1 << (FSHParser.KW_PREFERRED - 30)) | (1 << (FSHParser.KW_EXTENSIBLE - 30)) | (1 << (FSHParser.KW_REQUIRED - 30)))) !== 0)) {
-            this.state = 457;
+            this.state = 456;
             this.strength();
         }
 
@@ -5055,19 +5045,19 @@ FSHParser.prototype.fixedValueRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 460;
+        this.state = 459;
         this.match(FSHParser.STAR);
-        this.state = 461;
+        this.state = 460;
         this.path();
-        this.state = 462;
+        this.state = 461;
         this.match(FSHParser.EQUAL);
-        this.state = 463;
+        this.state = 462;
         this.value();
-        this.state = 465;
+        this.state = 464;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(_la===FSHParser.KW_EXACTLY) {
-            this.state = 464;
+            this.state = 463;
             this.match(FSHParser.KW_EXACTLY);
         }
 
@@ -5169,23 +5159,23 @@ FSHParser.prototype.containsRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 467;
+        this.state = 466;
         this.match(FSHParser.STAR);
-        this.state = 468;
+        this.state = 467;
         this.path();
-        this.state = 469;
+        this.state = 468;
         this.match(FSHParser.KW_CONTAINS);
-        this.state = 470;
+        this.state = 469;
         this.item();
-        this.state = 475;
+        this.state = 474;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.KW_AND) {
-            this.state = 471;
+            this.state = 470;
             this.match(FSHParser.KW_AND);
-            this.state = 472;
+            this.state = 471;
             this.item();
-            this.state = 477;
+            this.state = 476;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -5287,23 +5277,23 @@ FSHParser.prototype.onlyRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 478;
+        this.state = 477;
         this.match(FSHParser.STAR);
-        this.state = 479;
+        this.state = 478;
         this.path();
-        this.state = 480;
+        this.state = 479;
         this.match(FSHParser.KW_ONLY);
-        this.state = 481;
+        this.state = 480;
         this.targetType();
-        this.state = 486;
+        this.state = 485;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.KW_OR) {
-            this.state = 482;
+            this.state = 481;
             this.match(FSHParser.KW_OR);
-            this.state = 483;
+            this.state = 482;
             this.targetType();
-            this.state = 488;
+            this.state = 487;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -5405,29 +5395,29 @@ FSHParser.prototype.obeysRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 489;
+        this.state = 488;
         this.match(FSHParser.STAR);
-        this.state = 491;
+        this.state = 490;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(_la===FSHParser.KW_SYSTEM || _la===FSHParser.SEQUENCE) {
-            this.state = 490;
+            this.state = 489;
             this.path();
         }
 
-        this.state = 493;
+        this.state = 492;
         this.match(FSHParser.KW_OBEYS);
-        this.state = 494;
+        this.state = 493;
         this.name();
-        this.state = 499;
+        this.state = 498;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         while(_la===FSHParser.KW_AND) {
-            this.state = 495;
+            this.state = 494;
             this.match(FSHParser.KW_AND);
-            this.state = 496;
+            this.state = 495;
             this.name();
-            this.state = 501;
+            this.state = 500;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
         }
@@ -5514,21 +5504,21 @@ FSHParser.prototype.caretValueRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 502;
+        this.state = 501;
         this.match(FSHParser.STAR);
-        this.state = 504;
+        this.state = 503;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
         if(_la===FSHParser.KW_SYSTEM || _la===FSHParser.SEQUENCE) {
-            this.state = 503;
+            this.state = 502;
             this.path();
         }
 
-        this.state = 506;
+        this.state = 505;
         this.caretPath();
-        this.state = 507;
+        this.state = 506;
         this.match(FSHParser.EQUAL);
-        this.state = 508;
+        this.state = 507;
         this.value();
     } catch (re) {
     	if(re instanceof antlr4.error.RecognitionException) {
@@ -5621,18 +5611,18 @@ FSHParser.prototype.codeCaretValueRule = function() {
     var _la = 0; // Token type
     try {
         this.enterOuterAlt(localctx, 1);
-        this.state = 510;
+        this.state = 509;
         this.match(FSHParser.STAR);
-        this.state = 512; 
+        this.state = 513;
         this._errHandler.sync(this);
         _la = this._input.LA(1);
-        do {
-            this.state = 511;
+        while(_la===FSHParser.CODE) {
+            this.state = 510;
             this.match(FSHParser.CODE);
-            this.state = 514; 
+            this.state = 515;
             this._errHandler.sync(this);
             _la = this._input.LA(1);
-        } while(_la===FSHParser.CODE);
+        }
         this.state = 516;
         this.caretPath();
         this.state = 517;
diff --git a/src/import/parserContexts.ts b/src/import/parserContexts.ts
index a144ace..b7a9ce1 100644
--- a/src/import/parserContexts.ts
+++ b/src/import/parserContexts.ts
@@ -93,7 +93,6 @@ export interface CsMetadataContext extends ParserRuleContext {
 }
 export interface CsRuleContext extends ParserRuleContext {
   concept(): ConceptContext;
-  caretValueRule(): CaretValueRuleContext;
   codeCaretValueRule(): CodeCaretValueRuleContext;
   insertRule(): InsertRuleContext;
 }
@@ -483,6 +482,18 @@ export function containsPathContext(ctx: ParserRuleContext) {
   return (ctx as any).path != null;
 }
 
+export function containsCodePathContext(ctx: ParserRuleContext) {
+  // A code path comes from a concept or a codeCaretValueRule.
+  // So, detect a concept (with a non-empty CODE() list)
+  // or a codeCaretValueRule (with a caretPath)
+  return (
+    ((ctx as any).CODE != null && // If we have CODE,
+      Array.isArray((ctx as any).CODE()) && // and it's a list,
+      (ctx as any).CODE().length > 0) || // and the list is not empty, or
+    ((ctx as any).caretPath != null && (ctx as any).caretPath() != null) // we have a non-null caretPath
+  );
+}
+
 export function hasPathRule(ctx: ParserRuleContext) {
   return (ctx as any).pathRule != null && (ctx as any).pathRule() != null;
 }
diff --git a/src/utils/PathUtils.ts b/src/utils/PathUtils.ts
index 25bc2c5..892ed4d 100644
--- a/src/utils/PathUtils.ts
+++ b/src/utils/PathUtils.ts
@@ -158,7 +158,7 @@ export function resolveSoftIndexing(rules: Array<Rule | CaretValueRule>): void {
     });
 
     // If a rule is a CaretValueRule, we assemble its caretPath as well
-    if (originalRule instanceof CaretValueRule) {
+    if (originalRule instanceof CaretValueRule || originalRule instanceof CodeCaretValueRule) {
       originalRule.caretPath = assembleFSHPath(parsedRule.caretPath);
     }
   });


Test patch:
diff --git a/test/export/CodeSystemExporter.test.ts b/test/export/CodeSystemExporter.test.ts
index 9eca72a..66be84b 100644
--- a/test/export/CodeSystemExporter.test.ts
+++ b/test/export/CodeSystemExporter.test.ts
@@ -428,6 +428,70 @@ describe('CodeSystemExporter', () => {
     ]);
   });
 
+  it('should resolve soft indexing when applying CodeCaretValue rules', () => {
+    const codeSystem = new FshCodeSystem('CodeCaretCS');
+    const topCode = new ConceptRule('topCode', 'Top Code');
+    const bottomCode = new ConceptRule('bottomCode', 'Bottom Code');
+    bottomCode.hierarchy = ['topCode'];
+
+    const firstTop = new CodeCaretValueRule(['topCode']);
+    firstTop.caretPath = 'designation[+].value';
+    firstTop.value = 'First top designation';
+    const secondTop = new CodeCaretValueRule(['topCode']);
+    secondTop.caretPath = 'designation[+].value';
+    secondTop.value = 'Second top designation';
+
+    const firstBottom = new CodeCaretValueRule(['topCode', 'bottomCode']);
+    firstBottom.caretPath = 'designation[+].value';
+    firstBottom.value = 'First bottom designation';
+    const secondBottom = new CodeCaretValueRule(['topCode', 'bottomCode']);
+    secondBottom.caretPath = 'designation[+].value';
+    secondBottom.value = 'Second bottom designation';
+
+    codeSystem.rules.push(topCode, bottomCode, firstTop, secondTop, firstBottom, secondBottom);
+    doc.codeSystems.set(codeSystem.name, codeSystem);
+    const exported = exporter.export().codeSystems;
+    expect(exported.length).toBe(1);
+    expect(exported[0]).toEqual({
+      resourceType: 'CodeSystem',
+      id: 'CodeCaretCS',
+      name: 'CodeCaretCS',
+      content: 'complete',
+      url: 'http://hl7.org/fhir/us/minimal/CodeSystem/CodeCaretCS',
+      version: '1.0.0',
+      count: 2,
+      status: 'active',
+      concept: [
+        {
+          code: 'topCode',
+          display: 'Top Code',
+          designation: [
+            {
+              value: 'First top designation'
+            },
+            {
+              value: 'Second top designation'
+            }
+          ],
+          concept: [
+            {
+              code: 'bottomCode',
+              display: 'Bottom Code',
+              designation: [
+                {
+                  value: 'First bottom designation'
+                },
+                {
+                  value: 'Second bottom designation'
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    });
+  });
+
   it('should not override count when ^count is provided by user', () => {
     const codeSystem = new FshCodeSystem('MyCodeSystem');
     const rule = new CaretValueRule('');
diff --git a/test/import/FSHImporter.CodeSystem.test.ts b/test/import/FSHImporter.CodeSystem.test.ts
index 3712c23..efdad81 100644
--- a/test/import/FSHImporter.CodeSystem.test.ts
+++ b/test/import/FSHImporter.CodeSystem.test.ts
@@ -1,16 +1,14 @@
 import { importSingleText } from '../testhelpers/importSingleText';
-import { assertCaretValueRule, assertConceptRule, assertInsertRule } from '../testhelpers/asserts';
+import { assertConceptRule, assertInsertRule, assertCodeCaretRule } from '../testhelpers/asserts';
 import { loggerSpy } from '../testhelpers/loggerSpy';
-import {
-  Rule,
-  CaretValueRule,
-  InsertRule,
-  ConceptRule,
-  CodeCaretValueRule
-} from '../../src/fshtypes/rules';
+import { Rule, CaretValueRule, InsertRule, ConceptRule } from '../../src/fshtypes/rules';
 
 describe('FSHImporter', () => {
   describe('CodeSystem', () => {
+    beforeEach(() => {
+      loggerSpy.reset();
+    });
+
     describe('#csMetadata', () => {
       it('should parse the simplest possible code system', () => {
         const input = `
@@ -185,6 +183,7 @@ describe('FSHImporter', () => {
           endColumn: 15
         });
         expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
       it('should parse a code system with one concept with a display string', () => {
@@ -205,6 +204,7 @@ describe('FSHImporter', () => {
           endColumn: 24
         });
         expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
       it('should parse a code system with one concept with display and definition strings', () => {
@@ -225,6 +225,7 @@ describe('FSHImporter', () => {
           endColumn: 52
         });
         expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
       it('should parse a concept with a multi-line definition string', () => {
@@ -252,6 +253,7 @@ describe('FSHImporter', () => {
           endColumn: 115
         });
         expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
       it('should parse a code system with more than one concept', () => {
@@ -290,6 +292,7 @@ describe('FSHImporter', () => {
           endColumn: 52
         });
         expect(codeSystem.rules[2].sourceInfo.file).toBe('Zoo.fsh');
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
       it('should parse a code system with hierarchical codes', () => {
@@ -330,13 +333,14 @@ describe('FSHImporter', () => {
           endLine: 5,
           endColumn: 54
         });
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
       it('should log an error when encountering a duplicate code', () => {
         const input = `
         CodeSystem: ZOO
-        * #goat
-        * #goat
+        * #goat "A goat"
+        * #goat "Another goat?"
         `;
         const result = importSingleText(input, 'Zoo.fsh');
         expect(result.codeSystems.size).toBe(1);
@@ -346,6 +350,20 @@ describe('FSHImporter', () => {
         expect(loggerSpy.getLastMessage('error')).toMatch(/File: Zoo\.fsh.*Line: 4\D*/s);
       });
 
+      it('should not log an error when encountering a duplicate code if the new code has no display or definition', () => {
+        const input = `
+        CodeSystem: ZOO
+        * #goat "A goat"
+        * #goat
+        `;
+        const result = importSingleText(input, 'Zoo.fsh');
+        expect(result.codeSystems.size).toBe(1);
+        const codeSystem = result.codeSystems.get('ZOO');
+        expect(codeSystem.name).toBe('ZOO');
+        expect(codeSystem.rules.length).toBe(1);
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
+      });
+
       it('should log an error when encountering a code with an incorrectly defined hierarchy', () => {
         const input = `
         CodeSystem: ZOO
@@ -384,17 +402,31 @@ describe('FSHImporter', () => {
     });
 
     describe('#CaretValueRule', () => {
-      it('should parse a code system that uses a CaretValueRule', () => {
+      it('should log an error when a CaretValueRule contains a path before ^', () => {
+        const input = `
+        CodeSystem: ZOO
+        * somepath ^publisher = "Marky Mark"
+        `;
+        const result = importSingleText(input, 'Simple.fsh');
+        const codeSystem = result.codeSystems.get('ZOO');
+        expect(codeSystem.rules).toHaveLength(0);
+        expect(loggerSpy.getLastMessage('error')).toMatch(/File: Simple\.fsh.*Line: 3\D*/s);
+      });
+    });
+
+    describe('#codeCaretValueRule', () => {
+      it('should parse a code system that uses a CodeCaretValueRule with no codes', () => {
         const input = `
           CodeSystem: ZOO
           * ^publisher = "Matt"
           `;
         const result = importSingleText(input);
         const codeSystem = result.codeSystems.get('ZOO');
-        assertCaretValueRule(codeSystem.rules[0] as Rule, '', 'publisher', 'Matt', false);
+        assertCodeCaretRule(codeSystem.rules[0] as Rule, [], 'publisher', 'Matt', false);
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
-      it('should parse a code system that uses CaretValueRules alongside rules', () => {
+      it('should parse a code system that uses CodeCaretValueRules with no codes alongside rules', () => {
         const input = `
         CodeSystem: ZOO
         * #lion
@@ -404,28 +436,10 @@ describe('FSHImporter', () => {
         const codeSystem = result.codeSystems.get('ZOO');
         assertConceptRule(codeSystem.rules[0], 'lion', undefined, undefined, []);
         expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
-        assertCaretValueRule(
-          codeSystem.rules[1] as CaretValueRule,
-          '',
-          'publisher',
-          'Damon',
-          false
-        );
+        assertCodeCaretRule(codeSystem.rules[1] as CaretValueRule, [], 'publisher', 'Damon', false);
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
-      it('should log an error when a CaretValueRule contains a path before ^', () => {
-        const input = `
-        CodeSystem: ZOO
-        * somepath ^publisher = "Marky Mark"
-        `;
-        const result = importSingleText(input, 'Simple.fsh');
-        const codeSystem = result.codeSystems.get('ZOO');
-        expect(codeSystem.rules).toHaveLength(0);
-        expect(loggerSpy.getLastMessage('error')).toMatch(/File: Simple\.fsh.*Line: 3\D*/s);
-      });
-    });
-
-    describe('#codeCaretValueRule', () => {
       it('should parse a code system that uses a CodeCaretValueRule on a top-level concept', () => {
         const input = `
         CodeSystem: ZOO
@@ -436,13 +450,14 @@ describe('FSHImporter', () => {
         const codeSystem = result.codeSystems.get('ZOO');
         assertConceptRule(codeSystem.rules[0], 'anteater', 'Anteater', undefined, []);
         expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
-        expect(codeSystem.rules[1]).toBeInstanceOf(CodeCaretValueRule);
-        const codeCaret = codeSystem.rules[1] as CodeCaretValueRule;
-        expect(codeCaret.codePath).toEqual(['anteater']);
-        expect(codeCaret.path).toBe('');
-        expect(codeCaret.caretPath).toBe('property[0].valueString');
-        expect(codeCaret.value).toBe('Their threat pose is really cute.');
-        expect(codeCaret.sourceInfo.file).toBe('Zoo.fsh');
+        assertCodeCaretRule(
+          codeSystem.rules[1],
+          ['anteater'],
+          'property[0].valueString',
+          'Their threat pose is really cute.'
+        );
+        expect(codeSystem.rules[1].sourceInfo.file).toBe('Zoo.fsh');
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
 
       it('should parse a code system that uses a CodeCaretValueRule on a nested concept', () => {
@@ -460,13 +475,14 @@ describe('FSHImporter', () => {
           'anteater'
         ]);
         expect(codeSystem.rules[1].sourceInfo.file).toBe('Zoo.fsh');
-        expect(codeSystem.rules[2]).toBeInstanceOf(CodeCaretValueRule);
-        const codeCaret = codeSystem.rules[2] as CodeCaretValueRule;
-        expect(codeCaret.codePath).toEqual(['anteater', 'northern']);
-        expect(codeCaret.path).toBe('');
-        expect(codeCaret.caretPath).toBe('property[0].valueString');
-        expect(codeCaret.value).toBe('They are strong climbers.');
-        expect(codeCaret.sourceInfo.file).toBe('Zoo.fsh');
+        assertCodeCaretRule(
+          codeSystem.rules[2],
+          ['anteater', 'northern'],
+          'property[0].valueString',
+          'They are strong climbers.'
+        );
+        expect(codeSystem.rules[2].sourceInfo.file).toBe('Zoo.fsh');
+        expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
       });
     });
 
diff --git a/test/import/FSHImporter.RuleSet.test.ts b/test/import/FSHImporter.RuleSet.test.ts
index b6b68b6..980cf43 100644
--- a/test/import/FSHImporter.RuleSet.test.ts
+++ b/test/import/FSHImporter.RuleSet.test.ts
@@ -4,10 +4,11 @@ import {
   assertAssignmentRule,
   assertCardRule,
   assertInsertRule,
-  assertValueSetConceptComponent
+  assertValueSetConceptComponent,
+  assertCodeCaretRule
 } from '../testhelpers/asserts';
 import { loggerSpy } from '../testhelpers/loggerSpy';
-import { Rule, ConceptRule, CodeCaretValueRule } from '../../src/fshtypes/rules';
+import { Rule, ConceptRule } from '../../src/fshtypes/rules';
 import { FshCode } from '../../src/fshtypes';
 
 describe('FSHImporter', () => {
@@ -132,14 +133,13 @@ describe('FSHImporter', () => {
       expect(concept).toEqual(
         new ConceptRule('lion').withFile('Rules.fsh').withLocation([5, 9, 5, 15])
       );
-      expect(ruleSet.rules[3]).toBeInstanceOf(CodeCaretValueRule);
-      const codeCaret = ruleSet.rules[3] as CodeCaretValueRule;
-      expect(codeCaret.codePath).toEqual(['lion']);
-      expect(codeCaret.path).toBe('');
-      expect(codeCaret.caretPath).toBe('designation.value');
-      expect(codeCaret.value).toBe('Watch out for big cat!');
-      expect(codeCaret.sourceInfo.file).toBe('Rules.fsh');
-      expect(codeCaret.sourceInfo.location).toEqual({
+      assertCodeCaretRule(
+        ruleSet.rules[3],
+        ['lion'],
+        'designation.value',
+        'Watch out for big cat!'
+      );
+      expect(ruleSet.rules[3].sourceInfo.location).toEqual({
         startLine: 6,
         startColumn: 9,
         endLine: 6,
diff --git a/test/import/FSHImporter.context.test.ts b/test/import/FSHImporter.context.test.ts
index 5f5e677..74acac8 100644
--- a/test/import/FSHImporter.context.test.ts
+++ b/test/import/FSHImporter.context.test.ts
@@ -9,7 +9,8 @@ import {
   assertInsertRule,
   assertObeysRule,
   assertValueSetConceptComponent,
-  assertValueSetFilterComponent
+  assertValueSetFilterComponent,
+  assertCodeCaretRule
 } from '../testhelpers/asserts';
 import { FshCode } from '../../src/fshtypes';
 
@@ -450,28 +451,6 @@ describe('FSHImporter', () => {
       assertInsertRule(instance.rules[1], 'Bar');
     });
 
-    it('should log an error when a ConceptRule is indented', () => {
-      const input = `
-        CodeSystem: Foo
-        * #101
-          * #102
-      `;
-
-      const result = importSingleText(input, 'Context.fsh');
-      expect(loggerSpy.getAllMessages('error')).toHaveLength(1);
-      expect(loggerSpy.getLastMessage('error')).toMatch(
-        /rule that does not use a path cannot be indented/
-      );
-      expect(loggerSpy.getAllMessages('warn')).toHaveLength(0);
-      expect(result.codeSystems.size).toBe(1);
-      const cs = result.codeSystems.get('Foo');
-      expect(cs.name).toBe('Foo');
-      expect(cs.rules.length).toBe(2);
-      assertConceptRule(cs.rules[0], '101', undefined, undefined, []);
-      // rule is not assigned any context
-      assertConceptRule(cs.rules[1], '102', undefined, undefined, []);
-    });
-
     it('should log an error when a ValueSetFilterComponentRule is indented', () => {
       const input = `
         ValueSet: Foo
@@ -521,4 +500,159 @@ describe('FSHImporter', () => {
       ]);
     });
   });
+
+  describe('code context', () => {
+    it('should parse a code system with indented hierarchical rules', () => {
+      const input = `
+      CodeSystem: ZOO
+      * #bear "Bear" "A member of family Ursidae."
+        * #sunbear "Sun bear" "Helarctos malayanus"
+          * #ursula "Ursula the sun bear"
+      `;
+      const result = importSingleText(input, 'Zoo.fsh');
+      expect(result.codeSystems.size).toBe(1);
+      const codeSystem = result.codeSystems.get('ZOO');
+      expect(codeSystem.name).toBe('ZOO');
+      expect(codeSystem.rules.length).toBe(3);
+      assertConceptRule(codeSystem.rules[0], 'bear', 'Bear', 'A member of family Ursidae.', []);
+      expect(codeSystem.rules[0].sourceInfo.location).toEqual({
+        startLine: 3,
+        startColumn: 7,
+        endLine: 3,
+        endColumn: 50
+      });
+      assertConceptRule(codeSystem.rules[1], 'sunbear', 'Sun bear', 'Helarctos malayanus', [
+        'bear'
+      ]);
+      expect(codeSystem.rules[1].sourceInfo.location).toEqual({
+        startLine: 4,
+        startColumn: 9,
+        endLine: 4,
+        endColumn: 51
+      });
+      assertConceptRule(codeSystem.rules[2], 'ursula', 'Ursula the sun bear', undefined, [
+        'bear',
+        'sunbear'
+      ]);
+      expect(codeSystem.rules[2].sourceInfo.location).toEqual({
+        startLine: 5,
+        startColumn: 11,
+        endLine: 5,
+        endColumn: 41
+      });
+      expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
+    });
+
+    it('should parse a code system that uses an indented CodeCaretValueRule on a top-level concept', () => {
+      const input = `
+      CodeSystem: ZOO
+      * #anteater "Anteater"
+        * ^property[0].valueString = "Their threat pose is really cute."
+      `;
+      const result = importSingleText(input, 'Zoo.fsh');
+      const codeSystem = result.codeSystems.get('ZOO');
+      assertConceptRule(codeSystem.rules[0], 'anteater', 'Anteater', undefined, []);
+      expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
+      assertCodeCaretRule(
+        codeSystem.rules[1],
+        ['anteater'],
+        'property[0].valueString',
+        'Their threat pose is really cute.'
+      );
+      expect(codeSystem.rules[1].sourceInfo.file).toBe('Zoo.fsh');
+      expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
+    });
+
+    it('should parse a code system that uses an indented CodeCaretValueRule on a nested concept', () => {
+      const input = `
+      CodeSystem: ZOO
+      * #anteater "Anteater"
+        * #northern "Northern tamandua"
+          * ^property[0].valueString = "They are strong climbers."
+      `;
+      const result = importSingleText(input, 'Zoo.fsh');
+      const codeSystem = result.codeSystems.get('ZOO');
+      assertConceptRule(codeSystem.rules[0], 'anteater', 'Anteater', undefined, []);
+      expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
+      assertConceptRule(codeSystem.rules[1], 'northern', 'Northern tamandua', undefined, [
+        'anteater'
+      ]);
+      expect(codeSystem.rules[1].sourceInfo.file).toBe('Zoo.fsh');
+      assertCodeCaretRule(
+        codeSystem.rules[2],
+        ['anteater', 'northern'],
+        'property[0].valueString',
+        'They are strong climbers.'
+      );
+      expect(codeSystem.rules[2].sourceInfo.file).toBe('Zoo.fsh');
+      expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
+    });
+
+    it('should allow code path context to be set by referencing an existing top-level code', () => {
+      const input = `
+      CodeSystem: ZOO
+      * #anteater "Anteater"
+        * #northern "Northern tamandua"
+          * ^property[0].valueString = "They are strong climbers."
+      * #anteater
+        * ^property[0].valueString = "Their threat pose is really cute."
+      `;
+      const result = importSingleText(input, 'Zoo.fsh');
+      const codeSystem = result.codeSystems.get('ZOO');
+      expect(codeSystem.rules).toHaveLength(4);
+      assertConceptRule(codeSystem.rules[0], 'anteater', 'Anteater', undefined, []);
+      expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
+      assertConceptRule(codeSystem.rules[1], 'northern', 'Northern tamandua', undefined, [
+        'anteater'
+      ]);
+      expect(codeSystem.rules[1].sourceInfo.file).toBe('Zoo.fsh');
+      assertCodeCaretRule(
+        codeSystem.rules[2],
+        ['anteater', 'northern'],
+        'property[0].valueString',
+        'They are strong climbers.'
+      );
+      expect(codeSystem.rules[2].sourceInfo.file).toBe('Zoo.fsh');
+      assertCodeCaretRule(
+        codeSystem.rules[3],
+        ['anteater'],
+        'property[0].valueString',
+        'Their threat pose is really cute.'
+      );
+      expect(codeSystem.rules[3].sourceInfo.file).toBe('Zoo.fsh');
+      expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
+    });
+
+    it('should allow code path context to be set by referencing an existing nested code', () => {
+      const input = `
+      CodeSystem: ZOO
+      * #anteater "Anteater"
+        * #northern "Northern tamandua"
+        * #southern "Southern tamandua"
+      * #anteater #northern
+        * ^property[0].valueString = "They are strong climbers."
+      `;
+      const result = importSingleText(input, 'Zoo.fsh');
+      const codeSystem = result.codeSystems.get('ZOO');
+      expect(codeSystem.rules).toHaveLength(4);
+      assertConceptRule(codeSystem.rules[0], 'anteater', 'Anteater', undefined, []);
+      expect(codeSystem.rules[0].sourceInfo.file).toBe('Zoo.fsh');
+      assertConceptRule(codeSystem.rules[1], 'northern', 'Northern tamandua', undefined, [
+        'anteater'
+      ]);
+      expect(codeSystem.rules[2].sourceInfo.file).toBe('Zoo.fsh');
+      assertConceptRule(codeSystem.rules[2], 'southern', 'Southern tamandua', undefined, [
+        'anteater'
+      ]);
+      expect(codeSystem.rules[2].sourceInfo.file).toBe('Zoo.fsh');
+      assertCodeCaretRule(
+        codeSystem.rules[3],
+        ['anteater', 'northern'],
+        'property[0].valueString',
+        'They are strong climbers.'
+      );
+      expect(codeSystem.rules[3].sourceInfo.file).toBe('Zoo.fsh');
+      expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
+    });
+  });
 });
diff --git a/test/testhelpers/asserts.ts b/test/testhelpers/asserts.ts
index 00c4574..1423ca3 100644
--- a/test/testhelpers/asserts.ts
+++ b/test/testhelpers/asserts.ts
@@ -15,7 +15,8 @@ import {
   InsertRule,
   ValueSetConceptComponentRule,
   ValueSetFilterComponentRule,
-  ConceptRule
+  ConceptRule,
+  CodeCaretValueRule
 } from '../../src/fshtypes/rules';
 import { FshCode, ValueSetFilter } from '../../src/fshtypes';
 
@@ -187,3 +188,18 @@ export function assertConceptRule(
     expect(conceptRule.hierarchy).toEqual(hierarchy);
   }
 }
+
+export function assertCodeCaretRule(
+  rule: Rule,
+  codePath: string[],
+  caretPath: string,
+  value: AssignmentValueType,
+  isInstance = false
+) {
+  expect(rule).toBeInstanceOf(CodeCaretValueRule);
+  const codeCaretValueRule = rule as CodeCaretValueRule;
+  expect(codeCaretValueRule.codePath).toEqual(codePath);
+  expect(codeCaretValueRule.caretPath).toBe(caretPath);
+  expect(codeCaretValueRule.value).toEqual(value);
+  expect(codeCaretValueRule.isInstance).toBe(isInstance);
+}