diff --git a/Combinatorial_map/doc/Combinatorial_map/Concepts/GenericMap.h b/Combinatorial_map/doc/Combinatorial_map/Concepts/GenericMap.h index 4c9a672d69b..abeeb7bde3b 100644 --- a/Combinatorial_map/doc/Combinatorial_map/Concepts/GenericMap.h +++ b/Combinatorial_map/doc/Combinatorial_map/Concepts/GenericMap.h @@ -1068,8 +1068,18 @@ If \link GenericMap::are_attributes_automatically_managed `are_attributes_automa template size_type remove_cell(Dart_descriptor d); +/*! +\ingroup PkgCombinatorialMapsRefIO + Writes `amap` in `os`, using our own internal file format in XML. Writes both the topology of the combinatorial map and its enabled attributes. + */ +friend std::ostream& operator<< (std::ostream& os, const GenericMap& amap); + +/*! + \ingroup PkgCombinatorialMapsRefIO + Reads `amap` from `is`, using our own internal file format in XML. Reads both the topology of the combinatorial map and its enabled attributes which are present in `is`. Note that if `amap` is not empty before the reading, the new map is added in the previous one. + */ +friend std::ifstream& operator>> (std::ifstream& is, GenericMap& amap); + /// @} }; /* end GenericMap */ - - diff --git a/Combinatorial_map/doc/Combinatorial_map/PackageDescription.txt b/Combinatorial_map/doc/Combinatorial_map/PackageDescription.txt index 5016a763697..45081261ce8 100644 --- a/Combinatorial_map/doc/Combinatorial_map/PackageDescription.txt +++ b/Combinatorial_map/doc/Combinatorial_map/PackageDescription.txt @@ -6,6 +6,9 @@ /// \defgroup PkgCombinatorialMapsClasses Classes /// \ingroup PkgCombinatorialMapsRef +/// \defgroup PkgCombinatorialMapsRefIO IO Functions for CMap +/// \ingroup PkgCombinatorialMapsRef + /*! \addtogroup PkgCombinatorialMapsRef \cgalPkgDescriptionBegin{Combinatorial Maps,PkgCombinatorialMaps} @@ -36,5 +39,9 @@ - `CGAL::Cell_attribute_with_id` - `CGAL::Generic_map_min_items` +\cgalCRPSubsection{IO Functions for CMap} +- \link PkgCombinatorialMapsRefIO `std::ostream& operator<< (std::ostream& os, const GenericMap& amap)` \endlink +- \link PkgCombinatorialMapsRefIO `std::ifstream& operator>> (std::ifstream& is, GenericMap& amap)` \endlink + */ diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 407b27617fd..a14c628f2ac 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -255,7 +255,7 @@ namespace CGAL { } } - // Create an mapping between darts of the two maps (originals->copies). + // Creates a mapping between darts of the two maps (originals->copies). // (here we cannot use CGAL::Unique_hash_map because it does not provide // iterators... std::unordered_map local_dartmap; @@ -585,7 +585,7 @@ namespace CGAL { bool copy_perforated_darts=false, size_type mark_perforated=INVALID_MARK) { - // Create an mapping between darts of the two maps (originals->copies). + // Creates a mapping between darts of the two maps (originals->copies). // (here we cannot use CGAL::Unique_hash_map because it does not provide // iterators... std::unordered_map @@ -661,7 +661,7 @@ namespace CGAL { return is; } - /** Create a new dart and add it to the map. + /** Creates a new dart and add it to the map. * The marks of the darts are initialized with mmask_marks, i.e. the dart * is unmarked for all the marks. * @return a Dart_descriptor on the new dart. @@ -968,7 +968,7 @@ namespace CGAL { size_type number_of_used_marks() const { return mnb_used_marks; } - /** Test if a given mark is reserved. + /** Tests if a given mark is reserved. * @return true iff the mark is reserved (i.e. in used). */ bool is_reserved(size_type amark) const @@ -997,14 +997,14 @@ namespace CGAL { return number_of_darts() - number_of_marked_darts(amark); } - /** Test if all the darts are unmarked for a given mark. + /** Tests if all the darts are unmarked for a given mark. * @param amark the mark index. * @return true iff all the darts are unmarked for amark. */ bool is_whole_map_unmarked(size_type amark) const { return number_of_marked_darts(amark) == 0; } - /** Test if all the darts are marked for a given mark. + /** Tests if all the darts are marked for a given mark. * @param amark the mark index. * @return true iff all the darts are marked for amark. */ @@ -1071,7 +1071,7 @@ namespace CGAL { mmask_marks.flip(amark); } - /** Test if a given dart is marked for a given mark. + /** Tests if a given dart is marked for a given mark. * @param adart the dart to test. * @param amark the given mark. * @return true iff adart is marked for the mark amark. @@ -1239,7 +1239,7 @@ namespace CGAL { std::size_t orient(size_type amark) const { negate_mark(amark); return number_of_darts(); } - /** Test if this map is without boundary for a given dimension. + /** Tests if this map is without boundary for a given dimension. * @param i the dimension. * @return true iff all the darts are not i-free. * @pre 1<=i<=n @@ -1253,7 +1253,7 @@ namespace CGAL { return true; } - /** Test if this map is without boundary for all the dimensions. + /** Tests if this map is without boundary for all the dimensions. * @return true iff all the darts are non free. */ bool is_without_boundary() const @@ -1334,7 +1334,7 @@ namespace CGAL { return res; } - /** Test if the map is valid. + /** Tests if the map is valid. * @return true iff the map is valid. */ bool is_valid(bool show_errors=true) const @@ -1579,7 +1579,7 @@ namespace CGAL { return os; } - /// Create a new attribute. + /// Creates a new attribute. /// @return a descriptor on the new attribute. template typename Attribute_descriptor::type create_attribute(const Args&... args) @@ -1988,7 +1988,7 @@ namespace CGAL { else unlink_beta_for_involution(adart, i); } - /** Test if it is possible to sew by betai the two given darts + /** Tests if it is possible to sew by betai the two given darts * @param adart1 the first dart. * @param adart2 the second dart. * @return true iff \em adart1 can be i-sewn with \em adart2. @@ -3439,7 +3439,7 @@ namespace CGAL { } - /** Test if the connected component of cmap containing dart dh1 is + /** Tests if the connected component of cmap containing dart dh1 is * isomorphic to the connected component of map2 containing dart dh2, * starting from dh1 and dh2. * @param dh1 initial dart for this map @@ -3648,7 +3648,7 @@ namespace CGAL { return match; } - /** Test if this cmap is isomorphic to map2. + /** Tests if this cmap is isomorphic to map2. * @pre cmap is connected. * @param map2 the second combinatorial map * @param testDartInfo Boolean to test the equality of dart info (true) @@ -3687,7 +3687,7 @@ namespace CGAL { return false; } - /** Test if the attributes of this map are automatically updated. + /** Tests if the attributes of this map are automatically updated. * @return true iff the boolean automatic_attributes_management is set to true. */ bool are_attributes_automatically_managed() const @@ -3710,13 +3710,13 @@ namespace CGAL { void set_automatic_attributes_management_without_correction(bool newval) { this->automatic_attributes_management = newval; } - /** Create a halfedge. - * @return a dart of the new halfedge. + /** Creates a halfedge. + * @return a dart of the new half-edge. */ Dart_descriptor make_half_edge() { return create_dart(); } - /** Create an edge. + /** Creates an edge. * if closed==true, the edge has no 2-free dart. * (note that for CMap there is no difference between true and false, but * this is not the case for GMap) @@ -3730,7 +3730,7 @@ namespace CGAL { return d1; } - /** Create an edge given 2 Attribute_descriptor<0>. + /** Creates an edge given 2 Attribute_descriptor<0>. * Note that this function can be used only if 0-attributes are non void * @param h0 the first vertex descriptor. * @param h1 the second vertex descriptor. @@ -3751,7 +3751,7 @@ namespace CGAL { return d1; } - /** Create a combinatorial polygon of length alg + /** Creates a combinatorial polygon of length alg * (a cycle of alg darts beta1 links together). * @return a new dart. */ @@ -3772,7 +3772,7 @@ namespace CGAL { return start; } - /** Test if a face is a combinatorial polygon of length alg + /** Tests if a face is a combinatorial polygon of length alg * (a cycle of alg darts beta1 links together). * @param adart an initial dart * @return true iff the face containing adart is a polygon of length alg. @@ -3794,7 +3794,7 @@ namespace CGAL { return (nb==alg); } - /** Create a triangle given 3 Attribute_descriptor<0>. + /** Creates a triangle given 3 Attribute_descriptor<0>. * @param h0 the first descriptor. * @param h1 the second descriptor. * @param h2 the third descriptor. @@ -3814,7 +3814,7 @@ namespace CGAL { return d1; } - /** Create a quadrangle given 4 Vertex_attribute_descriptor. + /** Creates a quadrangle given 4 Vertex_attribute_descriptor. * @param h0 the first vertex descriptor. * @param h1 the second vertex descriptor. * @param h2 the third vertex descriptor. @@ -3837,7 +3837,7 @@ namespace CGAL { return d1; } - /** Create a combinatorial tetrahedron from 4 triangles. + /** Creates a combinatorial tetrahedron from 4 triangles. * @param d1 a dart onto a first triangle. * @param d2 a dart onto a second triangle. * @param d3 a dart onto a third triangle. @@ -3859,9 +3859,9 @@ namespace CGAL { return d1; } - /** Test if a volume is a combinatorial tetrahedron. - * @param adart an initial dart - * @return true iff the volume containing adart is a combinatorial tetrahedron. + /** Tests if a volume is a combinatorial tetrahedron. + * @param d1 an initial dart + * @return true iff the volume containing d1 is a combinatorial tetrahedron. */ bool is_volume_combinatorial_tetrahedron(Dart_const_descriptor d1) const { @@ -3892,7 +3892,7 @@ namespace CGAL { return true; } - /** Create a new combinatorial tetrahedron. + /** Creates a new combinatorial tetrahedron. * @return a new dart. */ Dart_descriptor make_combinatorial_tetrahedron() @@ -3905,7 +3905,7 @@ namespace CGAL { return make_combinatorial_tetrahedron(d1, d2, d3, d4); } - /** Create a combinatorial hexahedron from 6 quadrilaterals. + /** Creates a combinatorial hexahedron from 6 quadrilaterals. * @param d1 a dart onto a first quadrilateral. * @param d2 a dart onto a second quadrilateral. * @param d3 a dart onto a third quadrilateral. @@ -3952,9 +3952,9 @@ namespace CGAL { return d1; } - /** Test if a volume is a combinatorial hexahedron. - * @param adart an initial dart - * @return true iff the volume containing adart is a combinatorial hexahedron. + /** Tests if a volume is a combinatorial hexahedron. + * @param d1 an initial dart + * @return true iff the volume containing d1 is a combinatorial hexahedron. */ bool is_volume_combinatorial_hexahedron(Dart_const_descriptor d1) const { @@ -4004,7 +4004,7 @@ namespace CGAL { return true; } - /** Create a new combinatorial hexahedron. + /** Creates a new combinatorial hexahedron. * @return a new dart. */ Dart_descriptor make_combinatorial_hexahedron() @@ -4019,7 +4019,362 @@ namespace CGAL { return make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6); } - /** Test if an i-cell can be removed. + /** Tests if a volume is a combinatorial prism. + * @param d1 an initial dart + * @return true iff the volume containing d1 is a combinatorial prism. + */ + bool is_volume_combinatorial_prism(Dart_const_descriptor d1) const + { + Dart_const_descriptor d2=beta(d1, 2); + Dart_const_descriptor d3=beta(d1, 1, 2); + Dart_const_descriptor d4=beta(d1, 0, 2); + Dart_const_descriptor d5=beta(d2, 1, 1, 2); + + if ( d1==null_dart_descriptor || d2==null_dart_descriptor || + d3==null_dart_descriptor || d4==null_dart_descriptor || + d5==null_dart_descriptor ) { return false; } + + if (!is_face_combinatorial_polygon(d1, 3) || + !is_face_combinatorial_polygon(d2, 4) || + !is_face_combinatorial_polygon(d3, 4) || + !is_face_combinatorial_polygon(d4, 4) || + !is_face_combinatorial_polygon(d5, 3)) { return false; } + + // TODO do better with marks. + if (belong_to_same_cell<2,1>(d1, d2) || + belong_to_same_cell<2,1>(d1, d3) || + belong_to_same_cell<2,1>(d1, d4) || + belong_to_same_cell<2,1>(d1, d5) || + belong_to_same_cell<2,1>(d2, d3) || + belong_to_same_cell<2,1>(d2, d4) || + belong_to_same_cell<2,1>(d2, d5) || + belong_to_same_cell<2,1>(d3, d4) || + belong_to_same_cell<2,1>(d3, d5) || + belong_to_same_cell<2,1>(d4, d5)) + { return false; } + + if (beta(d2,0,2) !=beta(d3,1) || + beta(d2,1,2) !=beta(d4,0) || + beta(d3,0,2) !=beta(d4,1) || + beta(d3,1,1,2)!=beta(d5,0) || + beta(d4,1,1,2)!=beta(d5,1)) { return false; } + + return true; + } + + /** Creates a combinatorial prism from 2 triangles and 3 squares. + * @param d1 a dart onto a first triangle. + * @param d2 a dart onto a first square. + * @param d3 a dart onto a second square. + * @param d4 a dart onto a thirth square. + * @param d5 a dart onto a second triangle. + * @return a new dart. + */ + Dart_descriptor make_combinatorial_prism(Dart_descriptor d1, + Dart_descriptor d2, + Dart_descriptor d3, + Dart_descriptor d4, + Dart_descriptor d5) + { + // 2-link for first triangle + basic_link_beta_for_involution(d1, d2, 2); + basic_link_beta_for_involution(beta(d1, 1), d3, 2); + basic_link_beta_for_involution(beta(d1, 0), d4, 2); + + // 2-link for quandrangles between them + basic_link_beta_for_involution(beta(d2, 0), beta(d3, 1), 2); + basic_link_beta_for_involution(beta(d2, 1), beta(d4, 0), 2); + basic_link_beta_for_involution(beta(d3, 0), beta(d4, 1), 2); + + // 2-link for second triangle + basic_link_beta_for_involution(beta(d2, 1, 1), d5, 2); + basic_link_beta_for_involution(beta(d3, 1, 1), beta(d5, 0), 2); + basic_link_beta_for_involution(beta(d4, 1, 1), beta(d5, 1), 2); + + return d1; + } + + /** Creates a new combinatorial prism. + * @return a new dart. + */ + Dart_descriptor make_combinatorial_prism() + { + Dart_descriptor d1 = make_combinatorial_polygon(3); + Dart_descriptor d2 = make_combinatorial_polygon(4); + Dart_descriptor d3 = make_combinatorial_polygon(4); + Dart_descriptor d4 = make_combinatorial_polygon(4); + Dart_descriptor d5 = make_combinatorial_polygon(3); + + return make_combinatorial_prism( d1, d2, d3, d4, d5); + } + + /** Tests if a volume is a combinatorial pyramid. + * @param d1 an intial dart + * @return true iff the volume containing d1 is a combinatorial pyramid. + */ + bool is_volume_combinatorial_pyramid(Dart_const_descriptor d1) const + { + Dart_const_descriptor d2=beta(d1, 2); + Dart_const_descriptor d3=beta(d1, 0, 2); + Dart_const_descriptor d4=beta(d1, 1, 1, 2); + Dart_const_descriptor d5=beta(d1, 1, 2); + + if (d1==null_dart_descriptor || d2==null_dart_descriptor || + d3==null_dart_descriptor || d4==null_dart_descriptor || + d5==null_dart_descriptor) { return false; } + + if (!is_face_combinatorial_polygon(d1, 4) || + !is_face_combinatorial_polygon(d2, 3) || + !is_face_combinatorial_polygon(d3, 3) || + !is_face_combinatorial_polygon(d4, 3) || + !is_face_combinatorial_polygon(d5, 3)) { return false; } + + // TODO do better with marks. + if (belong_to_same_cell<2,1>(d1, d2) || + belong_to_same_cell<2,1>(d1, d3) || + belong_to_same_cell<2,1>(d1, d4) || + belong_to_same_cell<2,1>(d1, d5) || + belong_to_same_cell<2,1>(d2, d3) || + belong_to_same_cell<2,1>(d2, d4) || + belong_to_same_cell<2,1>(d2, d5) || + belong_to_same_cell<2,1>(d3, d4) || + belong_to_same_cell<2,1>(d3, d5) || + belong_to_same_cell<2,1>(d4, d5)) + { return false; } + + if (beta(d2,1,2)!=beta(d3,0) || + beta(d2,0,2)!=beta(d5,1) || + beta(d5,0,2)!=beta(d4,1) || + beta(d4,0,2)!=beta(d3,1)) { return false; } + + return true; + } + + /** Creates a combinatorial pyramid from 1 square and 4 triangles. + * @param d1 a dart onto the square. + * @param d2 a dart onto a first triangle. + * @param d3 a dart onto a second triangle. + * @param d4 a dart onto a thirth triangle. + * @param d5 a dart onto a fourth triangle. + * @return a new dart. + */ + Dart_descriptor make_combinatorial_pyramid(Dart_descriptor d1, + Dart_descriptor d2, + Dart_descriptor d3, + Dart_descriptor d4, + Dart_descriptor d5) + { + // 2-link for the square + basic_link_beta_for_involution(d1, d2, 2); + basic_link_beta_for_involution(beta(d1, 1), d5, 2); + basic_link_beta_for_involution(beta(d1, 1, 1), d4, 2); + basic_link_beta_for_involution(beta(d1, 0), d3, 2); + + // 2-link for first triangle + basic_link_beta_for_involution(beta(d2, 1), beta(d3, 0), 2); + basic_link_beta_for_involution(beta(d2, 0), beta(d5, 1), 2); + + // 2-link for triangles between them + basic_link_beta_for_involution(beta(d5, 0), beta(d4, 1), 2); + basic_link_beta_for_involution(beta(d4, 0), beta(d3, 1), 2); + + return d1; + } + + /** Creates a new combinatorial pyramid. + * @return a new dart. + */ + Dart_descriptor make_combinatorial_pyramid() + { + Dart_descriptor d1=make_combinatorial_polygon(4); + Dart_descriptor d2=make_combinatorial_polygon(3); + Dart_descriptor d3=make_combinatorial_polygon(3); + Dart_descriptor d4=make_combinatorial_polygon(3); + Dart_descriptor d5=make_combinatorial_polygon(3); + + return make_combinatorial_pyramid(d1, d2, d3, d4, d5); + } + + /** Tests if a volume is a combinatorial pentagonal prism. + * @param d1 an initial dart + * @return true iff the volume containing d1 is a combinatorial pentagonal prism. + */ + bool is_volume_combinatorial_pentagonal_prism(Dart_const_descriptor d1) const + { + Dart_const_descriptor d2=beta(d1, 2); + Dart_const_descriptor d3=beta(d1, 1, 2); + Dart_const_descriptor d4=beta(d1, 1, 1, 2); + Dart_const_descriptor d5=beta(d1, 0, 0, 2); + Dart_const_descriptor d6=beta(d1, 0, 2); + Dart_const_descriptor d7=beta(d2, 1, 1, 2); + + if (d1==null_dart_descriptor || d2==null_dart_descriptor || + d3==null_dart_descriptor || d4==null_dart_descriptor || + d5==null_dart_descriptor || d6==null_dart_descriptor || + d7==null_dart_descriptor) + { return false; } + + if (!is_face_combinatorial_polygon(d1, 5) || + !is_face_combinatorial_polygon(d2, 4) || + !is_face_combinatorial_polygon(d3, 4) || + !is_face_combinatorial_polygon(d4, 4) || + !is_face_combinatorial_polygon(d5, 4) || + !is_face_combinatorial_polygon(d6, 4) || + !is_face_combinatorial_polygon(d7, 5)) { return false; } + + // TODO do better with marks. + if (belong_to_same_cell<2,1>(d1, d2) || + belong_to_same_cell<2,1>(d1, d3) || + belong_to_same_cell<2,1>(d1, d4) || + belong_to_same_cell<2,1>(d1, d5) || + belong_to_same_cell<2,1>(d1, d6) || + belong_to_same_cell<2,1>(d1, d7) || + belong_to_same_cell<2,1>(d2, d3) || + belong_to_same_cell<2,1>(d2, d4) || + belong_to_same_cell<2,1>(d2, d5) || + belong_to_same_cell<2,1>(d2, d6) || + belong_to_same_cell<2,1>(d2, d7) || + belong_to_same_cell<2,1>(d3, d4) || + belong_to_same_cell<2,1>(d3, d5) || + belong_to_same_cell<2,1>(d3, d6) || + belong_to_same_cell<2,1>(d3, d7) || + belong_to_same_cell<2,1>(d4, d5) || + belong_to_same_cell<2,1>(d4, d6) || + belong_to_same_cell<2,1>(d4, d7) || + belong_to_same_cell<2,1>(d5, d6) || + belong_to_same_cell<2,1>(d5, d7) || + belong_to_same_cell<2,1>(d6, d7)) + { return false; } + + if (beta(d2,0,2) !=beta(d3,1) || + beta(d3,0,2) !=beta(d4,1) || + beta(d4,0,2) !=beta(d5,1) || + beta(d5,0,2) !=beta(d6,1) || + beta(d6,0,2) !=beta(d2,1) || + beta(d3,1,1,2)!=beta(d7,0) || + beta(d4,1,1,2)!=beta(d7,0,0) || + beta(d5,1,1,2)!=beta(d7,1,1) || + beta(d6,1,1,2)!=beta(d7,1)) { return false; } + + return true; + + } + + /** Tests if a volume is a combinatorial hexagonal prism. + * @param d1 an initial dart + * @return true iff the volume containing d1 is a combinatorial hexagonal prism. + */ + bool is_volume_combinatorial_hexagonal_prism(Dart_const_descriptor d1) const + { + Dart_const_descriptor d2=beta(d1, 2); + Dart_const_descriptor d3=beta(d1, 1, 2); + Dart_const_descriptor d4=beta(d1, 1, 1, 2); + Dart_const_descriptor d5=beta(d1, 1, 1, 1, 2); + Dart_const_descriptor d6=beta(d1, 0, 0, 2); + Dart_const_descriptor d7=beta(d1, 0, 2); + Dart_const_descriptor d8=beta(d2, 1, 1, 2); + + if (d1==null_dart_descriptor || d2==null_dart_descriptor || + d3==null_dart_descriptor || d4==null_dart_descriptor || + d5==null_dart_descriptor || d6==null_dart_descriptor || + d7==null_dart_descriptor || d8==null_dart_descriptor) + { return false; } + + if (!is_face_combinatorial_polygon(d1, 6) || + !is_face_combinatorial_polygon(d2, 4) || + !is_face_combinatorial_polygon(d3, 4) || + !is_face_combinatorial_polygon(d4, 4) || + !is_face_combinatorial_polygon(d5, 4) || + !is_face_combinatorial_polygon(d6, 4) || + !is_face_combinatorial_polygon(d7, 4) || + !is_face_combinatorial_polygon(d8, 6)) { return false; } + + // TODO do better with marks. + if (belong_to_same_cell<2,1>(d1, d2) || + belong_to_same_cell<2,1>(d1, d3) || + belong_to_same_cell<2,1>(d1, d4) || + belong_to_same_cell<2,1>(d1, d5) || + belong_to_same_cell<2,1>(d1, d6) || + belong_to_same_cell<2,1>(d1, d7) || + belong_to_same_cell<2,1>(d1, d8) || + belong_to_same_cell<2,1>(d2, d3) || + belong_to_same_cell<2,1>(d2, d4) || + belong_to_same_cell<2,1>(d2, d5) || + belong_to_same_cell<2,1>(d2, d6) || + belong_to_same_cell<2,1>(d2, d7) || + belong_to_same_cell<2,1>(d2, d8) || + belong_to_same_cell<2,1>(d3, d4) || + belong_to_same_cell<2,1>(d3, d5) || + belong_to_same_cell<2,1>(d3, d6) || + belong_to_same_cell<2,1>(d3, d7) || + belong_to_same_cell<2,1>(d3, d8) || + belong_to_same_cell<2,1>(d4, d5) || + belong_to_same_cell<2,1>(d4, d6) || + belong_to_same_cell<2,1>(d4, d7) || + belong_to_same_cell<2,1>(d4, d8) || + belong_to_same_cell<2,1>(d5, d6) || + belong_to_same_cell<2,1>(d5, d7) || + belong_to_same_cell<2,1>(d5, d8) || + belong_to_same_cell<2,1>(d6, d7) || + belong_to_same_cell<2,1>(d6, d8) || + belong_to_same_cell<2,1>(d7, d8)) + { return false; } + + if (beta(d2,0,2) !=beta(d3,1) || + beta(d3,0,2) !=beta(d4,1) || + beta(d4,0,2) !=beta(d5,1) || + beta(d5,0,2) !=beta(d6,1) || + beta(d6,0,2) !=beta(d7,1) || + beta(d7,0,2) !=beta(d2,1) || + beta(d3,1,1,2)!=beta(d8,0) || + beta(d4,1,1,2)!=beta(d8,0,0) || + beta(d5,1,1,2)!=beta(d8,0,0,0) || + beta(d6,1,1,2)!=beta(d8,1,1) || + beta(d7,1,1,2)!=beta(d8,1)) { return false; } + + return true; + } + + /** Tests if a volume is a combinatorial tetrahedron10. + * @param d1 an initial dart + * @return true iff the volume containing d1 is a combinatorial tetrahedron10. + */ + bool is_volume_combinatorial_tetrahedron10(Dart_const_descriptor d1) const + { + Dart_const_descriptor d2=beta(d1, 2,0); + Dart_const_descriptor d3=beta(d2, 0,2); + Dart_const_descriptor d4=beta(d2, 1,1,1,2); + + if(d1==null_dart_descriptor || d2==null_dart_descriptor || + d3==null_dart_descriptor || d4==null_dart_descriptor) + { return false; } + + if(!is_face_combinatorial_polygon(d1, 6) || + !is_face_combinatorial_polygon(d2, 6) || + !is_face_combinatorial_polygon(d3, 6) || + !is_face_combinatorial_polygon(d4, 6)) { return false; } + + if(beta(d1, 1,2)!=beta(d1, 2,0) || + beta(d2, 1,2)!=beta(d2, 2,0) || + beta(d3, 1,2)!=beta(d3, 2,0) || + beta(d4, 1,2)!=beta(d4, 2,0)) { return false; } + + // TODO do better with marks (?). + if(belong_to_same_cell<2,1>(d1, d2) || + belong_to_same_cell<2,1>(d1, d3) || + belong_to_same_cell<2,1>(d1, d4) || + belong_to_same_cell<2,1>(d2, d3) || + belong_to_same_cell<2,1>(d2, d4) || + belong_to_same_cell<2,1>(d3, d4)) { return false; } + + if(beta(d1,1,1,2)!=beta(d3,0) || + beta(d1,0,2)!=beta(d4,1,1) || + beta(d4,0,2)!=beta(d3,1,1)) { return false; } + + return true; + } + + /** Tests if an i-cell can be removed. * An i-cell can be removed if i==dimension or i==dimension-1, * or if there are at most two (i+1)-cell incident to it. * @param adart a dart of the i-cell. @@ -4041,7 +4396,7 @@ namespace CGAL { run(*this,adart,update_attributes); } - /** Test if an i-cell can be contracted. + /** Tests if an i-cell can be contracted. * An i-cell can be contracted if i==1 * or if there are at most two (i-1)-cell incident to it. * @param adart a dart of the i-cell. @@ -4407,7 +4762,7 @@ namespace CGAL { return this->template beta<0>(adart1); } - /** Test if an edge can be inserted onto a 2-cell between two given darts. + /** Tests if an edge can be inserted onto a 2-cell between two given darts. * @param adart1 a first dart. * @param adart2 a second dart. * @return true iff an edge can be inserted between adart1 and adart2. @@ -4443,7 +4798,7 @@ namespace CGAL { return generic_insert_cell_1(adart1, adart2, false, update_attributes); } - /** Test if an edge can be inserted between two different 2-cells + /** Tests if an edge can be inserted between two different 2-cells * between two given darts. * @param adart1 a first dart. * @param adart2 a second dart. @@ -4627,7 +4982,7 @@ namespace CGAL { return this->template beta<0>(adart1); } - /** Test if a 2-cell can be inserted onto a given 3-cell along + /** Tests if a 2-cell can be inserted onto a given 3-cell along * a path of edges. * @param afirst iterator on the beginning of the path. * @param alast iterator on the end of the path. diff --git a/Combinatorial_map/include/CGAL/Element_topo.h b/Combinatorial_map/include/CGAL/Element_topo.h new file mode 100644 index 00000000000..f37a18c6278 --- /dev/null +++ b/Combinatorial_map/include/CGAL/Element_topo.h @@ -0,0 +1,208 @@ +// Copyright (c) 2025 CNRS and LIRIS' Establishments (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Guillaume Damiand +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef CMAP_ELEMENT_TOPO_H +#define CMAP_ELEMENT_TOPO_H + +#include + +namespace CGAL { + namespace CMap { + namespace Element_topo { + +enum cell_topo + { + SQUARE=0, + TRIANGLE=1, + HEXAHEDRON=2, + TETRAHEDRON=3, + PRISM=4, + PYRAMID=5, + GENERIC_2D=6, + GENERIC_3D=7, + EDGE=8, + TETRAHEDRON10=9, + PENTAGONAL_PRISM=10, + HEXAGONAL_PRISM=11, + NO_TYPE=-1 + }; + +inline +std::string topo_name(cell_topo t) +{ + switch(t) + { + case SQUARE: return "SQUARE"; + case TRIANGLE: return "TRIANGLE"; + case HEXAHEDRON: return "HEXAHEDRON"; + case TETRAHEDRON: return "TETRAHEDRON"; + case PRISM: return "PRISM"; + case PYRAMID: return "PYRAMID"; + case GENERIC_2D: return "GENERIC_2D"; + case GENERIC_3D: return "GENERIC_3D"; + case EDGE: return "EDGE"; + case TETRAHEDRON10: return "TETRAHEDRON10"; + case PENTAGONAL_PRISM: return "PENTAGONAL_PRISM"; + case HEXAGONAL_PRISM: return "HEXAGONAL_PRISM"; + case NO_TYPE: return "NO_TYPE"; + } + return "UNKNOWN"; +} + +inline +cell_topo topo_from_name(const std::string& t) +{ + if (t=="SQUARE") return SQUARE; + if (t=="TRIANGLE") return TRIANGLE; + if (t=="HEXAHEDRON") return HEXAHEDRON; + if (t=="TETRAHEDRON") return TETRAHEDRON; + if (t=="PRISM") return PRISM; + if (t=="PYRAMID") return PYRAMID; + if (t=="GENERIC_2D") return GENERIC_2D; + if (t=="GENERIC_3D") return GENERIC_3D; + if (t=="EDGE") return EDGE; + if (t=="TETRAHEDRON10") return TETRAHEDRON10; + if (t=="PENTAGONAL_PRISM") return PENTAGONAL_PRISM; + if (t=="HEXAGONAL_PRISM") return HEXAGONAL_PRISM; + if (t=="NO_TYPE") return NO_TYPE; + return NO_TYPE; +} + +/** + * @brief To get the type of `dimD` cell of the `CMap` of `cmapdim` dimension. + */ +template +struct Get_cell_topo +{ + static cell_topo run(CMap&, typename CMap::Dart_descriptor dh, + typename CMap::Dart_descriptor& starting_dart) + { + starting_dart=dh; + return NO_TYPE; + } +}; + +/** + * @brief To get the type associated of an edge. For now only one type. + */ +template +struct Get_cell_topo +{ + static cell_topo run(CMap&, typename CMap::Dart_descriptor it, + typename CMap::Dart_descriptor& starting_dart) + { + starting_dart=it; + return EDGE; + } +}; + +/** + * @brief To get the type of 2D cell of the CMap of cmapdim dimension. + */ +template +struct Get_cell_topo +{ + static cell_topo run(CMap& cmap, typename CMap::Dart_descriptor it, + typename CMap::Dart_descriptor& starting_dart) + { + starting_dart=it; + + if (cmap.is_face_combinatorial_polygon(it, 3)) + { return TRIANGLE; } + + else if (cmap.is_face_combinatorial_polygon(it, 4)) + { return SQUARE; } + + return GENERIC_2D; + } +}; + +/** + * @brief To get the type of 3D cell of the CMap of dimension 3. + */ +template +struct Get_cell_topo +{ + static cell_topo run(CMap& cmap, typename CMap::Dart_descriptor it, + typename CMap::Dart_descriptor& starting_dart) + { + starting_dart=it; + + if (cmap.is_volume_combinatorial_tetrahedron(it)) + { return TETRAHEDRON; } + + else if (cmap.is_volume_combinatorial_hexahedron(it)) + { return HEXAHEDRON; } + + else if(cmap.is_volume_combinatorial_tetrahedron10(it)) + { return TETRAHEDRON10; } + + // For non symetric object, we need to test all darts + for (auto itv=cmap.template darts_of_cell<3>(it).begin(), + itvend=cmap.template darts_of_cell<3>(it).end(); itv!=itvend; ++itv) + { + starting_dart=itv; + + if (cmap.is_volume_combinatorial_prism(itv)) + { return PRISM; } + + else if (cmap.is_volume_combinatorial_pentagonal_prism(itv)) + { return PENTAGONAL_PRISM; } + + else if (cmap.is_volume_combinatorial_pyramid(itv)) + { return PYRAMID; } + + else if (cmap.is_volume_combinatorial_hexagonal_prism(itv)) + { return HEXAGONAL_PRISM; } + + } + + return GENERIC_3D; + } +}; + +template +cell_topo get_cell_topo(CMap& cmap, typename CMap::Dart_descriptor it, + typename CMap::Dart_descriptor& starting_dart) +{ return Get_cell_topo::run(cmap, it, starting_dart); } + +template +cell_topo get_cell_topo(CMap& cmap, typename CMap::Dart_descriptor it) +{ + typename CMap::Dart_descriptor dummy; + return get_cell_topo(cmap, it, dummy); +} + +template +cell_topo get_cell_topo(const CMap& cmap, typename CMap::Dart_const_descriptor it, + typename CMap::Dart_const_descriptor& starting_dart) +{ + typename CMap::Dart_descriptor it2=const_cast(cmap).dart_descriptor + (cmap.darts().index(it)); + typename CMap::Dart_descriptor sd2; + cell_topo res=Get_cell_topo::run(const_cast(cmap), + it2, sd2); + starting_dart=sd2; + return res; +} + +template +cell_topo get_cell_topo(const CMap& cmap, typename CMap::Dart_const_descriptor it) +{ + typename CMap::Dart_descriptor it2=it; + return Get_cell_topo::run(const_cast(cmap), it2); +} + +} } } // namespace CGAL::CMap::Element_topo + +#endif // CMAP_ELEMENT_TOPO_H diff --git a/Linear_cell_complex/doc/Linear_cell_complex/CGAL/Linear_cell_complex/IO/VTK.h b/Linear_cell_complex/doc/Linear_cell_complex/CGAL/Linear_cell_complex/IO/VTK.h new file mode 100644 index 00000000000..8be086ed211 --- /dev/null +++ b/Linear_cell_complex/doc/Linear_cell_complex/CGAL/Linear_cell_complex/IO/VTK.h @@ -0,0 +1,68 @@ +namespace CGAL { +namespace IO { + +/** \file VTK.h + * Functions to import/export 3D Linear_cell_complex from/to VTK legacy ASCII + * format. + * + * Only supports: + * - `CGAL::Linear_cell_complex_for_combinatorial_map<3,3>` + * - VTK legacy ASCII format (.vtk files) + * - Optional scalar fields for vertices and volumes + * + * Supported VTK cell types: + * - VTK_TETRA (10): Tetrahedron + * - VTK_VOXEL (11): Voxel (special hexahedron ordering) + * - VTK_HEXAHEDRON (12): Hexahedron + * - VTK_WEDGE (13): Prism/Wedge + * - VTK_PYRAMID (14): Pyramid + * - VTK_PENTAGONAL_PRISM (15): Pentagonal prism + * - VTK_HEXAGONAL_PRISM (16): Hexagonal prism + * - VTK_POLYHEDRON (42): Generic polyhedron + */ + +/** + * \brief Reads a VTK legacy ASCII file and load it into a 3D + * linear cell complex. + * \ingroup PkgLinearCellComplexRefIOVTK + * + * \tparam LCC must be a `CGAL::Linear_cell_complex_for_combinatorial_map<3,3>` + * \tparam VertexScalarType Type for vertex scalar data (default: float) + * \tparam VolumeScalarType Type for volume scalar data (default: float) + * \param filename Path to the VTK file + * \param alcc The linear cell complex to populate (will be cleared first) + * \param vertex_scalars Optional output vector to store per-vertex scalar values. + * If provided, will be resized to match number of vertices. + * \param volume_scalars Optional output vector to store per-volume scalar values. + * If provided, will be resized to match number of volumes. + * \return `true` if loading was successful, `false` otherwise + */ +template +bool read_VTK(const char* filename, + LCC& alcc, + std::vector* vertex_scalars=nullptr, + std::vector* volume_scalars=nullptr); + +/** + * \brief Writes a 3D Linear_cell_complex to a VTK legacy ASCII file. + * \ingroup PkgLinearCellComplexRefIOVTK + * + * \tparam LCC must be a `CGAL::Linear_cell_complex_for_combinatorial_map<3,3>` + * \tparam VertexScalarType Type for vertex scalar data (default: float) + * \tparam VolumeScalarType Type for volume scalar data (default: float) + * \param filename Path to the output VTK file + * \param alcc The linear cell complex to export + * \param vertex_scalars Optional per-vertex scalar data. If provided, must have + * same size as number of vertex attributes in the LCC. + * \param volume_scalars Optional per-volume scalar data. If provided, must have + * same size as number of 3-cells in the LCC. + * \return `true` if writing was successful, `false` otherwise + */ +template +bool write_VTK(const char* filename, + const LCC& alcc, + const std::vector* vertex_scalars=nullptr, + const std::vector* volume_scalars=nullptr); + +} // namespace IO +} // namespace CGAL diff --git a/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt b/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt index 5d7ac3cfd55..94672f31b71 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt @@ -289,6 +289,18 @@ The following example shows the use of \link GenericMap::insert_cell_1_between_t Result of the run of the linear_cell_complex_3_insert program. A window shows the 3D cube where one face has a hole. \cgalFigureEnd +\subsection Linear_cell_complexWriteVTK Writing a Linear Cell Complex to a VTK File +\anchor ssecLCCWriteVtK + +This example loads a 3D linear cell complex from a `.3map` file (using the `operator>>`). It computes for each 3-cell (volume) the number of incident vertices (0-cells), stores these values in a `std::vector`, and writes the result to a `.vtk` file using `CGAL::IO::write_VTK()`, with the computed values as scalars for each volume. + +\cgalExample{Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp} + +\cgalFigureBegin{fig_lcc_export_vtk,lcc-export-vtk.png} +Visualization of the VTK file generated by the `linear_cell_complex_3_vtk_io` program, using Paraview. Each volume is colored depending on its number of vertices. +\cgalFigureEnd + + \section Linear_cell_complexDesign Design and Implementation History This package was developed by Guillaume Damiand, with the help of Andreas Fabri, Sébastien Loriot and Laurent Rineau. Monique Teillaud and Bernd Gärtner contributed to the manual. diff --git a/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt b/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt index f0f70d53797..00619008616 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt @@ -23,6 +23,14 @@ /// \defgroup PkgDrawLinearCellComplex Draw a Linear Cell Complex /// \ingroup PkgLinearCellComplexRef +/// \defgroup PkgLinearCellComplexRefIO IO Functions for LCC +/// \ingroup PkgLinearCellComplexRef + +/*! High-level operations. +\cgalInclude{CGAL/Linear_cell_complex/IO/VTK.h} +*/ +/// \defgroup PkgLinearCellComplexRefIOVTK VTK IO Functions for LCC +/// \ingroup PkgLinearCellComplexRefIO /*! \addtogroup PkgLinearCellComplexRef @@ -74,4 +82,10 @@ - \link PkgDrawLinearCellComplex CGAL::draw() \endlink - \link PkgDrawLinearCellComplex CGAL::add_in_graphics_scene() \endlink +\cgalCRPSubsection{IO Functions for LCC} +- \link PkgCombinatorialMapsRefIO `std::ostream& operator<< (std::ostream& os, const GenericMap& amap)` \endlink +- \link PkgCombinatorialMapsRefIO `std::ifstream& operator>> (std::ifstream& is, GenericMap& amap)` \endlink +- \link PkgLinearCellComplexRefIOVTK `CGAL::IO::Read_VTK()` \endlink +- \link PkgLinearCellComplexRefIOVTK `CGAL::IO::Write_VTK()` \endlink + */ diff --git a/Linear_cell_complex/doc/Linear_cell_complex/examples.txt b/Linear_cell_complex/doc/Linear_cell_complex/examples.txt index def1f1a28fe..ff4b61c9c1f 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/examples.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/examples.txt @@ -6,4 +6,5 @@ \example Linear_cell_complex/linear_cell_complex_3_incremental_builder.cpp \example Linear_cell_complex/draw_linear_cell_complex.cpp \example Linear_cell_complex/linear_cell_complex_3_insert.cpp +\example Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp */ diff --git a/Linear_cell_complex/doc/Linear_cell_complex/fig/lcc-export-vtk.png b/Linear_cell_complex/doc/Linear_cell_complex/fig/lcc-export-vtk.png new file mode 100644 index 00000000000..02f534c8395 Binary files /dev/null and b/Linear_cell_complex/doc/Linear_cell_complex/fig/lcc-export-vtk.png differ diff --git a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt index d5b66adf6fa..234ae9e83da 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt @@ -27,6 +27,7 @@ create_single_source_cgal_program("linear_cell_complex_4.cpp") create_single_source_cgal_program("read_plane_graph_in_lcc_2.cpp") create_single_source_cgal_program("voronoi_2.cpp") create_single_source_cgal_program("voronoi_3.cpp") +create_single_source_cgal_program("linear_cell_complex_3_vtk_io.cpp") create_single_source_cgal_program("draw_linear_cell_complex.cpp") if(CGAL_Qt6_FOUND) diff --git a/Linear_cell_complex/examples/Linear_cell_complex/data/beam-with-mixed-cells.3map b/Linear_cell_complex/examples/Linear_cell_complex/data/beam-with-mixed-cells.3map new file mode 100644 index 00000000000..69e5a8cd3e7 --- /dev/null +++ b/Linear_cell_complex/examples/Linear_cell_complex/data/beam-with-mixed-cells.3map @@ -0,0 +1,2 @@ + +2413371511014511046121034810282135961377111361131291051416115203132421713641827631929621621612114221923282025251527226232752730274241727329223173018316282631532353853340388344738731513863631375438553961354141321084239107436410644651054570111467411040481094833552494655150785504779553523413248538213247545613246513613249563733557533345881339598333860673375562336623819636018646617614216664384056763840968598408698684076571840671441968726919677385197070751969754511807673117977841178788011827449118180501061817710648257106379521062845814118576141086721413836814128892176899617590102174911051738711217793879411695117929797889895991221001231011079610310389610410151021064106904310710442108100411091264011012746111131451051134411391208114111207115134206116118205112932091189446911911546812013346712112946612212446511798470124994121251214151261284141231084131281094911291254901301204931271324921321108831331308821341198851311148841361387137143913514881391352531401522521411532511421572501381442491441361451421461601471611431491491371721501471711511641701521541691481391681541408332155151833115616383301531588333158141834515915683441601628347157145834616214616315916415516115016616883931671738395165178839416916515217018115117118215017218614916817414817416690175172891761888817718487173179911791672161801772151811832141781692131831701841801851761821871871711881851861751901938721911968711922018701892058731941891952091931971971902281981952271992082262002102301962022292021918421203200842020421284232012068422206192115207204114208211113209198112205194116211199197521220719742102031976214217181215221180216226179213231178218213829121923582902202368289217222829222221422322022424022524122122722721519822822519722924419623024520022623219923221618362332301835234248183423523718332312181837237219238234239247240242236223242224200224323920052442462004241228200324622919882472431991248238199024523319892502541422512581412522631402532671392492721382552492562752572762542592592502231260257223026128222292622812228258264223226425183632652628362266280836526326883642682528396269266840027027983992712788398267273839727325324274271272752772627225525277256151127827415102792701509280269151528126515142822611513276260151228428615622852911561283298156328728314762883021475289303147429030714782862921477292284150529329015042943091503295310150229631515082973181507291299150629928530029730132230230429828730428814483053011447306321144630331214453082891424309311142330729314253112943563123083553133063543143203533103163573162953031731429315319283192963203173213133223053183003243261323932532913241323334132403273231322332834013222326344132213303243313473323483333533293353353255633633355337357603383585933936158334341573413271070342339106934336610723403671071345328131923463691319134734913190344330131893493311433350346143235137014313523641435348354143435433231335535231235636331135735931035333631435933713257360356132593583621325836233814093633601408364355140736535114063663721405361342140436834310893693711088367345109037135013973723681396370365139837437837538237638537738937339337937397138039697038139796937840297238337413256384404132553823861325438637531387384343884003338539032390376408391388411392399410389394409394377581395392580396398579393379582398380566399395565400391564401387568397403567403381132374044011323640238313238406408407412405416409405389410419392411421391408413390413406123414411126415420125412417124417407456418415455419422458416409457421414528422410527420418526424427888425431887426437886423441889428423832429446835430447834427432833432424463433430462434450461435451460436455459431438464438425514439436513440458512437442515442426589443440588444457587445453592446448591441428590448429702449445701450452704447433703452434453449454444451456456435417457454416458443419455439418460465435461471434462475433463479432464467431459466436466459121467464120468463119469482118470483117465472122472460473470474486471476476461781477474780478485783475480782480462854481478857482484856479468855484469485481486477483473488490530489494529487498531491487128492501127493503130490495129495488508496493511497502510494499509499489547500497546501504549498491548503496904504492903502500905506508524507512523505516525509505494510519497511521496508513495513506439514511438515520437512517440517507937518515936519522935516509938521514900522510902520518901524526506525529505523532507527523422528534421526530420530524488531528487529533489533525557534531559532527558536538939537542941535546940539535922540549921541550924538554923543536572544556571545552570542547569547537499548545498549551501546539500551540495525484855354447550555505555411044556553104355454310455585605325595645345575695335615579495625729525635739515605659505655583995665633985675753975685764015645704005705595455715685445725785435695615425745629685755779675735669665775671046578574104857657110475805833955815873945825933935795993965845799475856039465866079455835889485885804435895864425906114415916124465926174455875944445945815955925966205976215986265936006005821287601598128660263012855996041288604584125560560212546066291253603608125660858511696096061168610631117261161311716075891170613590207061461020746156342073616623207261261820716185916526196166516206226546175956536225966236196246156256336216276275971220628625121962963212186306051217626601122163260912056336281208634624120763161412066366388450637644845263565184516396356406546416556426596436636386456456366796466436786476656776486666836496616826506576816446526806526376186536506176546566206516396196566406576536586496556606606418459661658845866264884576596688456664642101806656671017966364610178667647101886686641018766666210189670673101636716771016267268410165669688101646746696756916766946736786786706466796766456807006446817016506827056496837106486776856476856711021368668310212687714102156847151021468967210657690718106566886921065869267410663693690106626916951066469567510123696693101226977211012169872210127699727101267007021012569467910124702680448703699447704732450701706449706681707704708731709733705711711682849071270984947137378493714738849271068684917166871070671774010705715719107047196891063672071710639721723106387186961063772369785727247208571725739857572673685747227288573728698776729726775730735774731734779732707778727703777734708852273573085267367298525737725852473371285237397131067174072410673738716106727427441008774374810086741752100887457411005174675510054747762100537447661005274974296157507689614751769961374877496127537439606754779960875275696077567457577547587787597807607847617907557637637461103076476111029765792110287627931103176774796357687969634766749963377075086657717988664772799866377380486627697758666775751729776773728777808727778781732779757731774753730781758476782777475783807478780785477785759786783787806788802789809784813791760110207928151101979076411021794765108717958111087079381610872797767107817988181078079677010779800771975180181797508028109754803787975379980597528057721010080680310099807786100988087821009780477610101810788110898118011108881279411087809814110868147891107581581211074813791110738177951080281880010801816797108008208238428821827843182283284308198368429824819202782584020268268412025823828202482882085382982685283084485183184585082783384983382142783483143083584842983283742883782220548388352053839847205284084220518368242050842825843839844846841829846830101488478431014784883810146845834101458508548318518588308528628298538668288498708278558494798568734828578744818548594808598501009186085710090861878100898588631009286385186486186587786286786785220128688652011869876201086687120138718531918728691908738751898708551928758568768728778688788648748608808828988818868978798908998838791328848931318858951348828871338878804258888854248898944238868914268918811183892889118689389611858908831184895888843489688484338948928432898900880899903879897906881901897520902908522900904521904898503905902502903907504907899909908905911906901910910912906911917908909921907913909116691492411659159251164916928116391291811679189109319199169349209309339179229329229115399239205389249265419219135409269141040927923104292592910419299159609309279629289199619329359179339399209349429199319459189369315189379485179389495169359405199409325359419385379399525369439339599449519589429469579469345859479445849489505839459365869509375609519475639529435629499415619549571020955960101995696310189539661017958953944959968943957961942961954928962959930960964929964955103796596210399639671038967956575968965574966958573970973380971976379972979378969982381974969989975984991973977990977970129597897512979769801296980971131498197813169799831315983972133098498113329829741331986989100198799210049889951003985998100299098597399110009759899939749939861327994991132999299613289969871276997994127899599912779999881298100099713009989901299100210059851003100898810041011987100110149861006100110211007101610231005100910221009100212601010100712621008101212611012100311321013101011341011101511331015100410991016101310981014100610971018102195610191024955102010279541017103095310221017100510231032100710211025100610251018109310261023109210241028109110281019111310291026111510271031111410311020126310321029126510301022126410341037104910351040105210361043105110331046105010381033963103910489651037104196410411034925104210399271040104492610441035555104510425541043104755610471036576104810455781046103857710501053103310511057103610521061103510491065103410541049107610551068107910561071107810531058107710581050132301059105613229106010701322810571062132311062105179106310608210641069811061106680106610521162106710641161106810721160106510541159107010633411071105934010721055343106910673421074107611001075108011021073108411011077107310531078108710561079108910551076108110541081107413881082107913911083108813901080108513891085107513491086108313521087109013511084107713501089108236810901078367108810863691092109410261093109710251091110010241095109111171096110311161094110611181098109210161099110810151097110110141101109310731102109910751100110410741104109513831105110213821103110713811107109611301108110511291106109811311110111311461111111611451112111911481109112211471114110910271115112410291113111710281117111010951118111510941116112010961120111111381121111811401119112311391123111212661124112112681122111412671126112912151127113212141128113512131125113812161130112511071131114011061129113311081133112610111134113110131132113610121136112712571137113412591135113912581139112811191140113711211138113011201142114513921143114913951144115413941141115913931146114111101147116311091148116811121145115011111150114211871151114811911152117211901153117311891149115511881155114314031156115314021157117714011158117814001154116013991160114410681161115810671162118210661159116410651164114691511651162914116611819131167118391211631169916116911476081170116760711711186611117211746101168115160911741152195111751171195011761185195411771179195311731156195211791157761180117675118111847411821165781178116177118411668901185118089311861175892118311708911188119211491189119711531190120111521191120511511187119311501193118712311194119112301195120812341196120912331192119812321198118814671199119614661200121214691197120214681202118919481203120019471204121119461201120619491206119063112071204634120812106331205119463212101195121112071212120312091199121412171127121512221126121612261125121312301128121812136291219123462812201235627122112396261217122363012231214127012241221126912251243127212221244127112271215138412281247138712291248138612261231138512311216119312321229119212331252119612341236119512301218119412361219123712331238125112351240124012201241123812421250124312451239122412451225136812461242136712471249136612441227136512491228143612501246144012511241143912521237143812481232143712541257605125512606041256126360312531266606125812531135125912681137125712611136126112541008126212591010126012641009126412551030126512621032126312671031126712561122126812651124126612581123127012731223127112761222127212791225126912821224127412691289127512841291127312771290127712709951278127599712761280996128012711324128112781326127912831325128312721308128412811310128212741309128612896011287129260012881295599128512986021290128512731291130012751289129312741293128613051294129113071292129613061296128797612971294978129512999771299128899813001297100012981290999130213051303130813041311130113141306130112921307131612941305130912931309130212821310130712841308131212831312130313211313131013231311131513221315130497913161313981131413069801318132113351319132413341320132713331317133013361322131713111323133213131321132513121325131812791326132312811324132812801328131999213291326994132713319931331132098213321329984133013229831334133713191335134013181336134313171333134613201338133313531339134813551337134113541341133413781342133913801340134413791344133513186134513421318813431347131871347133613215134813451321713461338132161350135310841351135610871352135910861349136210851354134913371355136413391353135713381357135013212135813551321413561360132131360135113199136113581320113591363132001363135213691364136113711362135413701366136912471367137212461368137512451365137812441370136513621371138013641369137313631373136613196137413711319813721376131971376136713177137713741317913751379131781379136813401380137713421378137013411382138411051383138811041381139211031385138112261386139512291387139712281384138912271389138210801390138710831391139610821388139310811393138311411394139111441395139811431392138511421397139037113981386370139613943721400140411581401141011571402141411561403141811551399140511541405139936614061403365140714223641408142336314091426362140414113611411140084141214098314131430861410141585141514011965141614131964141714291963141414191966141914021465142014171464142114281463142214241462141814061461142414073081425142130714231427309142714081894142814251898142914201897143014161896142614121895143214363501433144034914341441348143514453521431144935114371431124814381452125214391453125114401442125014361432124914421433144314391444145614411446144614343061447144430514481455304144514503031450143514571451144814601452145414591449143714581454143814551451145614471453144314581461144914591466145214601470145114571474145014621457142214631478142114641479142014651482141914611467141814671458119814681465119714691486120014661471119914711459147214691473148514701475147514602881476147328714771484286147814802901474146228914801463148814811477148714791483148914831464194414841481194314851476194214861472194114821468194514881490148014891493147914871496148114911487152114921498152314901494152214941488191214951492191414931497191314971489186714981495186614961491186815001502132661501150913268149915161326715031499294150415202931505152129215061524291150715312971508153629615021510295151015002781511150827715121540276151315412821514154528115151527280150915172791517150118991518151519031519152619021520152219011516150319001522150414901523151914921521152514911525150515871526152315931527151815921528151415911529154715901530154815891524153215881532150615331530153415511535155215311537153715071538153515391555154015421536151115421512263215431539263115441557263415411558263315461513268015471560268215451528268115491529162015501559161915511553161815481533162115531534211215541550211415521556211315561538207915571554208115551543208015591544265615601549265815581546265715621564284156315672831561157028515651561157515661572157415641568157315681562194015691566193915671571193815711563157215691570156515741576156615751582156515731587156415771573187115781593187015791592186915801594187415811598187315761583187215831574158415811585160115861602158215881588157515241589158615301590160615291591160515281592159515271593157815261587157715251595157917901596159117891597160417881594159917871599158016001597160116031598158416031585164816041600164716051596164616061590164516021589164416081611210816091615211116101618211016071622210916121607216616131625216516141626216416111630216316161608265016171632265216151619265116191609155016201617154916211628154816181623155116231610162416211625162716221612162716131633162816241636162916201635162616311634163116142167163216292169163016162168163416371626163516411629163616441628163316491627163816332161163916532160164016542159163716602162164216342176164316622178164116632177164516351606164616651605164716661604164816721603164416501602165016361651164816521675165316551649163816551639270916561652270816571674270716581670270616591669270516541676270416611640219016621678218916601642218816641643267816651667267716631645267916671646173216681664173116691677173016701658172916711657172816661673172716731647167416711675165616721651167716592208167816682207167616612206168016838225168116898224168216968223167917008222168416791685170616861707168717121688171516831690169016801691168816921718169317191694172216951727168916971697168117511698169517501699173217531696170117521701168222201702169922191703173122181704173022241705173322231706170822221700168422211708168533631709170533621710173633661711173733651707171333641713168636631714171136621712174136611716168729531717174329521718172029511715169129501720169228571721171728561719174428551723169327841724174627831725173827821726173527861722172827851728169416711729172616701730173416691731170316681732170216671727169816661734170427361735172927351736172527381733170927371738171028101739172428091740174528121737174228111742171436581743174036601741171636591745172128271746173928261744172328251748175017651749175417671747175817661751174716971752176116961753176316991750175516981755174817991756175318021757176218011754175918001759174982521760175782551761176482541758175182531763175683601764175283591762176083611766176817471767177217491765177617481769176517701779177117811768177317731766827317741771827617751780827517721777827417771767178617781775178517791782178417761769178317811774180917821770180817801778180717841787177917851791177817861795177717831799177617881783159717891802159617901805159517871792159417921784181017931790181317941804181217911796181117961785838017971794837917981803837817951800837718001786175418011798175718021806175617991788175518041797836918051793836818061789836718031801836618081810178218091814178118071818178018111807179118121821179418131823179318101815179218151808183818161813184118171822184018141819183918191809828518201817828818211824828718181811828618231816837518241812837418221820837618261828182718331825183818291825185518301841185418311842185318321846185718281834185618341826234183518322331836184823218371844231183318392351839182718141840183718171841184318161838182918151843183084031844184084021845183684011842184784041847183119721848184519711846183519731850185319091851185819081852186619111849186919101854184918301855187418291856187518281857188118321853185918311859185019341860185719331861188419321862188519311863187819301864188819371865187119361858186719351867185114971868186514961866187014981870185215781871186815771872186415761873189015811874187615801869185415791876185518771873187818891879186218801887187518821882185619871883188019861884188619851881186019841886186120391887188320381885187920401889186318901877188818721892189413263189318991326518911904132641895189114261896190714301897190814291898191214281894190014271900189215161901189815201902191415191903191015181899190515171905189384141906190384131907190984161904189584151909189618501910190618491911190218521908191318511913189714931914191114951912190114941916191819171924191519301919191519201937192119381922194119231946191819251925191620601926192320591927194920581928195020571929195520561924193120551931191718621932192918611933195818601934195918591935196318581936194318651937193918641930191918631939192015691940193615681938194215671942192114851943194014841944193514831945196614821941194714861947192212031948194512021949195112011946192612041951192711741952194811731953196511771954196111761950195611751956192884271957195484261958196084251955193284241960193319791961195719781962195319771959196419801964193414161965196214151966195214141963194414171968197171196919747019701977731967198072197219671847197319791846197119751848197519682111976197321019741978212197819691961197919761960198019721959197719701962198219848418198319888417198119928419198519811884198619951883198719971882198419891881198919822451990198724819911996247198819932461993198320291994199120281995199820311992198520301997199019981986199619942000200220012006199920102003199924120042013244200520152432002200724220072000200820052009201420062011201120018682012200986720132016866201020038692015200820172016200420192014201220182018202020142019202420162017202820152021201720222031202320332020202520252018826202620238252027203282420242029823202920191993203020271992203120341995202820211994203320262037203420222036203220302035203620382034203720412033203520442032203920351886204020461885203820421887204220362043204020412045204520372047204620432049204420392048204820502044204920552046204720612045205120478402052206583920532066838205420708372050205683620562048192920572054192820582074192720592073192620602075192520552062192420622049206320602064207820652067206120512067205284392068206484382069207784412066207184402071205361220722069616207320766152074205861420702057613207620592077207220782068207520632080208215552081208615572079209015562083207920842093208520952082208720872080258520882085258420892094258320862091258620912081210220922089210120932096210020902083210320952088214020962084213920942092213820982100212920992104212820972108212721012097209221022111209121032113209021002105209321052098210621032107211221042109210920991607211021071610211121141609210821011608211321061552211421021554211221101553211621192154211721232153211821272152211521302151212021152324212121332323212221342326211921242325212421162125212221262137212321282128211720992129212620982127213820972131211825692132214025682133213525672130212025702135212121362132213721392134212521392129209621402136209521382131209421422144247621432148247521412151247421452141232221462154232121472155232021442159231921492142218421502162218321482163218221522143211821532166211721542156211621512145211521562146215721532158216521552160216021471639216121581638216221641637215921491640216421501614216521611613216621571612216321521611216821701630216921731632216721761631217121672179217221782181217021742180217421682662217521722664217321772663217721691641217821751643217621711642218021822170218121852172217921882171218321792150218421902149218221862148218621802193218721842192218521892191218921811662219021871661218821831660219221942187219321972186219122002185219521912203219622022205219421982204219821922473219921962472219722012471220121932478220221992477220021952479220422062194220522092196220322122195220722031678220822141677220622101676221022042269221122082268220922132267221322052249221422112248221222072247221622182672221722252671221522282673221922151702222022321701222122331700222222371706222322411705222422461704221822471703222622162499222722502498222522532500222922172612230225626022312257259223222342582228221926222342220835222352231835522362262835422332238835322382221223922362240226122372242224222222363224322402362224422602361224522632366224622482365224122232364224822242214224922452213224722512212225122262487225222492486225022662488225422272616225522652615225622582618225322292617225822302259225522602264226122432262223922572235226422442415226522592418226622542417226322522416226822702211226922772210226722842209227122672369227222872368227322912367227422982373227523032372227622792371227022782370227822682686227922762685228022752684228123062683228223072689228323122688227723192687228522692470228623222469228422882468228822712431228922862434229023232433228722922432229222722293229022942326229523162296232722972330229122992299227343262300229743252301233243242302233343282298230443272304227478162305230278152306230878142303228078132308228145172309230545162310233645152311233945192307231345182313228223142311231523412316234223172294231823252312232023202283214723212318214623222324214523192285214423242289212023252321211923262317212223232293212123282295440523292344440423272345440323312296436423322347436623302300436523342301438623352346438523332337438723372309445923382335445823362348445723402310804123412350804023392314803923432315442323442349442223422328442123462329436923472334436823452331436723492338444023502343443923482340444123522355235323612354236723512374235623512357238023582381235923842360238723552362236223522243236323602242236423912241236523922246236623692245236123682244236823532272236923662271237023652270237123952276237223962275237323762274236723752273237523544004237623734003237723724002237824004008237924014007238024054006237423564005238223578122238324078121238123858120238523588116238623838115238424088114238823593345238924103344239024113348239123933347238723633346239323642734239423902733239523972732239223702731239723713328239823943327239924143331240024023330239623773329240223783436240323993435240424133438240124063437240623793731240724043730240523823732240923863678241024123677240823883676241223893416241324093419241424033418241123983417241624192263241724222266241824252265241524282264242024152435242124302437241924232436242324162451242424212450242224262452242624172548242724242550242524292549242924182564243024272566242824202565243224352287243324382290243424412289243124442288243624312419243724462421243524392420243924322561244024372563243824422562244224332580244324402582244124452581244524342449244624432448244424362447244824502446244924532445244724562444245124472423245224592422245024622424245424482579245524642578245324572577245724492465245824552467245624602466246024512481246124582480245924632482246324522540246424612539246224542541246624682456246724712458246524742457246924652286247024762285246824722284247224662199247324702198247124752197247524672143247624732142247424692141247824802201247924832200247724862202248124772460248224882459248024842461248424782490248524822489248324872491248724792251248824852250248624812252249024922484249124952483248924982485249324892503249425002502249224962501249624902666249724942665249524992667249924912226250024972225249824932227250225042494250325072493250125102492250525012648250625132647250425162649250825022622250925182624250725112623251125032523251225092525251025142524251425052596251525122598251325172597251725062641251825152643251625082642252025232535252125262538252225292537251925322536252425192510252525342512252325272511252725202619252825252621252625302620253025212606253125282608252925332607253325222587253425312589253225242588253625392519253725422522253825452521253525482520254025352463254125502462253925432464254325362574254425412576254225462575254625372555254725442557254525492556254925382425255025472427254825402426255225552553255825542561255125642556255125452557256625472555255925462559255225712560255725732558256225722562255324382563256024402561256524392565255424282566256324302564255624292568257121322569257421312570257721302567258021332572256725582573258225602571257525592575256825422576257325442574257825432578256924552579257624542577258124532581257024412582257924432580257224422584258720882585259020872586259320862583259620892588258325322589259825342587259125332591258426032592258926052590259426042594258526442595259226462593259726452597258625132598259525152596258825142600260326012606260226092599261226042599259026052614259226032607259126072600252926082605253126062610253026102601262826112608263026092613262926132602263526142611263726122604263626162619225426172622225326182625225626152628225526202615252626212630252826192623252726232616250726242621250926222626250826262617263826272624264026252629263926292618260926302627261126282620261026322635154226332638154126342641154426312644154326362631261226372646261426352639261326392632262526402637262726382642262626422633251626432640251826412645251726452634259326462643259526442636259426482650250526492653250426472656250626512647161526522658161726502654161626542648266026552652265926532657266126572649155826582655156026562651155926602662265426612665265326592668265526632659217326642670217526622666217426662660249626672664249526652669249726692661267526702667267426682663267626722674221626732677221526712680221726752671266926762682266826742678267026782672166426792676166326772681166526812673154526822679154726802675154626842690228026852696227926862700227826872704227726882709228326892710228226832691228126912683410726922689410626932713410526942714410426952719410326902697410826972684332626982695332526992722332426962701332327012685272727022699273027032723272927002705272827052686165927062703165827072726165727082716165627092711165527042687165427112688271227082713271527102692271526932716271227172707271827252714272027202694300027212718300327222724300227192698300127242702278727252721279027262717278927232706278827282731270027292735270327302739270227272744270127322727239527332748239427342749239327312736239227362728173427372734173327382754173627352740173527402729276727412738276627422753276527432752276927392745276827452730330727462743330627472751330527482750330927442732330827502733336727512747337227522746337127532742337027542741336927492737336827562758362327572762362227552765362427592755303227602769303127612770303427582775303327632756280027642779279927622782280127662757274127672786274027682787273927692771274327652759274227712760300727722768300627732790300527742791300427702776300827762761290127772774290027782795290327752796290227802763281927812798282127792783282027832764172427842781172327852793172227862788172627822766172527882767272327892785272627902792272527872772272427922773279327892794278427952797279127772797277828752798279428742796278028732800280227632801280527622799280927642803279928222804281228242802281328232806280036162807281536152808281636142805281036172810280117382811280817372812281817402809280317392814280428312815281728332813280628322817280736522818281436542816281136532820282227792821282527812819282827802823281928022824283028042822282628032826282017462827282417452825282917442829282128482830282728472828282328462832283428132833283728152831284028142835283128432836284228452834283828442838283228952839283628942837284128932841283329642842283929632840283529622844284628342845284928362843285228352847284328302848285428292846285028282850284428692851284828682849285328672853284528602854285128592852284728582856285817212857286117202855286417192859285528542860286628532858286228522862285629492863286029482861286529472865285728662863286428592868287028512869287328502867287628492871286728722878287028742874286827982875287227972873287727962877286929062878287529052876287129042880288230902881288630892879288930912883287929112884289229102885289329132882289629122887288030152888289930142886290030132890288128912903289229042889288328942884283928952906283828932897283728972885304528982895304428992901304328962887304629012888277629022898277529032905277829002890277729052891287829062902287729042894287629082910290929142907291829112907288329122921288229132923288529102915288429152908292829162913293129172922293029142919292929192909311829202917311729212924311629182911311529232916355529242912355429222920355329262928292729322925293629292925291429302939291729312941291629282933291529332926295829342931296129352940296029322937295929372927293829352939294229362929294129343593294229303592294029383594294429472945295029462954294329582948294328632949296228622947295128612951294417182952294917172953296517162950295517152955294529562953295729682954295929592946293229602957293529612970293429582963293329632948284229642961284129622966284029662952365729672964365629652969365529692956360029702967359929682960359829722974414129732977414029712982413929752971813929762987813829742991814029782972383029792994382929802995382829813000383229772983383129832973298429812985300329863004298229882988297530182989298630172990300830162987300930192992297681602993301281592994299681622991297881612996297933202997299333192998301133182999300633222995300133213001298027193002299927223003300527213000298427203005298527733006300227723007299827713008301027703004298927743010299032873011300732863012299732853009299232883014301628883015302028873013302428863017301329893018302729883019302929873016302129903021301430733022301930763023302830753020302530743025301530923026302330953027303030943024301730933029302281293030301881313028302681303032303527593033303927583034304327613031304727603036303133913037305033943038305133933035304033923040303236123041303836113042305336103039304436133044303328983045304228973046305428963043304828993048303430583049304630573050305630603047303630593052303780833053305580823051304180813055304535523056305235513054304935503058306130483059306430473060306730503057307030493062305730773063307230793061306530783065305832923066306332943064306832933068305931883069306631903067307131893071306031563072306931583070306231573074307730203075308030233076308330223073308630213078307330613079308830633077308130623081307431533082307931553080308431543084307531693085308231713083308731703087307632953088308532973086307832963090309228803091309628793089310028813093308930243094310330273095310530263092309730253097309031083098309531073099310431103096310131093101309131023099310331063100309331053098417331063094417231043102417431083111309731093115309631103119309931073123309831123107313731133126313631143129313531113116313431163108292131173114292031183128291931153120291831203109312131183122312731193124312431103940312531223939312631303938312331123937312831213129311731303113312731253132313435483133313835473131314235493135313131143136314531133137314731123134313931113139313231503140313731493141314631523138314331513143313335383144314135373145314835363142313535393147314039253148313639243146314439263150315331393151315631383152315931413149316231403154314930803155316430823153315730813157315030703158315530723156316030713160315131853161315831873159316331863163315231723164316131743162315431733166316931993167317231983168317531973165317832003170316530833171318030853169317330843173316631623174317131643172317631633176316731943177317431963175317931953179316832983180317733003178317032993182318532683183318832673184319132663181319432653186318131593187319631613185318931603189318230673190318730693188319230683192318332893193319032913191319532903195318431753196319331773194318631763198320131673199320431663200320731653197321031683202319732173203321232193201320532183205319838993206320339013204320839003208319981503209320681523207321181513211320081633212320981653210320281643214321732293215322032323216322332313213322632303218321332013219322832033217322132023221321481723222321981743220322481733224321538773225322238793223322738783227321639023228322539043226321839033230323332133231323632163232323932153229324232143234322932493235324432513233323732503237323034823238323534843236324034833240323138703241323838723239324338713243323240593244324140613242323440603246324932613247325232643248325532633245325832623250324532333251326032353249325332343253324640563254325140583252325640573256324734573257325434593255325934583259324834733260325734753258325034743262326532453263326932483264327332473261327732463266326131843267328031833268328331823265327031813270326235203271326835193272328235223269327435213274326334103275327234093276328134083273327834113278326433033279327633023280328433013277326633043282327533733283327133763284326733753281327933743286328930113287329230103288329530093285329830123290328531913291330031933289329331923293328630643294329130663292329630653296328730863297329430883295329930873299328831783300329731803298329031793302330532793303331032783304331432773301331832803306330127463307332227453308332327443309332727483305331127473311330234133312330934123313333134153310333234143315330340503316333540493317333640523314331940513319330429973320331729963321334029953322332429993318330629983324330726993325332126983326333926973323332826963328330823973329332623963330333824003331333323993327331223983333331334293334333034283335333734273332331534303337331637973338333437963339332937953340332537993336332037983342334436733343334936753341335336743345334123883346335623873347336223913348336723903344335023893350334234013351334834043352337234033349337334023354334380943355337780933353335780953357334533583355335933803360338133613384335633633363334617083364336117073365338617113366338717103362336817093368334727493369336627543370339027533371339127523372337427513367335127503374335232813375337132843376339432833373337832823378335435093379337635083380338235073377335835103382335935663383337935653381339535673385336036693386339836683384336436673388336536193389340036183390339236213387336936203392337030353393338930383394339630373391337530363396338380913397339380903395339980923399338536363400339736353398338836343402340533493403340833523404341233513401341633503406340136823407341936843405342036833409340232753410342232743411342332733408341332763413340333113414341133103415342633133412341733123417340424113418341524143419342524133416340624123421340737003422342437023420340937013424341034423425342134413426341834403423341434393428343133343429343533333430343933323427344333353432342737933433344637923434344737913431343637943436342824023437343424013438344924043435344024033440342934263441343834253442345034243439344434233444343034543445344234533446345234563443343234553448343337223449345137213447343737233451344137153452344837173450344537163454345734443455346034433456346334463453346634453458345332553459346832573457346132563461345440533462345940553460346440543464345538643465346238663463346738653467345634763468346534783466345834773470347334913471347634903472347934893469348234883474346932583475348432603473347732593477347034663478347534683476348034673480347138613481347838633479348338623483347232363484348132383482347432373486348839323487349239313485349639303489348534723490349934713491350134703488349334693493348635153494349135183495350035173492349735163497348737623498349537613499350237603496348937633501349437123502349037143500349837133504350735343505351135333506351535323503351935353508350333793509352233783510352333773507351233803512350435133510351435253511351635163505349235173514349535183526349435153520349335203506327035213518326935223528327235193508327135243509809635253527809835233513809735273517370735283524370635263521370835303532392935313536392835293540392735333529350535343543350435353545350335323537350635373530314435383535314335393544314235363541314535413531354235393543354635403533354535383561354635343560354435423559354835503132354935533131354735563133355135473056355235583055355035543054355435482924355535522923355335572922355735493580355835553582355635513581356035623546356135653545355935683544356335593564357035623566356635603382356735643381356535693383356935613573357035673572356835633571357235743570357335773569357135803568357535713583357635823585357435783584357835728089357935768088357735818087358135733556358235793558358035753557358435863574358535893576358335923575358735833588359435863590359035843597359135883596358935933595359335852941359435912940359235872942359635983591359736013590359536043589359935952970360036062969359836022968360235963603360036013605360535973643360636033645360435993644360836103626360936143625360736183627361136073041361236213040361336233039361036153042361536082807361636132806361736222805361436192808361936093388362036173387362136243390361836113389362336162756362436122755362236202757362636283608362736313607362536343609362936253637363036363639362836323638363236268084363336308086363136358085363536273400363636333399363436293398363836403628363936433630363736463629364136373649364236483651364036443650364436383604364536423606364336473605364736393666364836453665364636413664365036523640365136553642364936583641365336492816365436602818365236562817365636502967365736542966365536592965365936511741366036571743365836531742366236641714366336671713366136701712366536613648366636723647366436683646366836623386366936663385366736713384367136633672366936703665367436763341367536793343367336823342367736732410367836842409367636802408368036743687368136783686367936833685368336753405368436813407368236773406368636883681368736913680368536943679368936853697369036963699368836923698369236868107369336908106369136958105369536878099369636938101369436898100369837003688369937033690369737063689370136973420370237083422370037043421370436983711370537023710370337073709370736993527370837053526370637013528371037123705371137153704370937183703371337093500371437203502371237163501371637103450371737143452371537193451371937113737372037173736371837133738372237243448372337273447372137303449372537213733372637323735372437283734372837223777372937263776372737313775373137232406373237292405373037252407373437363724373537393726373337423725373737333719373837443718373637403720374037343746374137383745373937433747374337358128374437418127374237378126374637483740374737513739374537543741374937453757375037563759374837523758375237463788375337503790375137553789375537473756375337543749375837603748375937643750375737683749376137573498376237713497376337733496376037653499376537583820376637633823376737723822376437693821376937593770376737713774376837613773376639173774376239193772377039183776377837293777378837283775379137273779377539803780379439793781379539783782380039773783380639763784380539853785380739843786381239833787381139823778381339813789377637513790381937533788382037523792377734333793382434323794379634313791377934343796378033383797379333373798382733363799382833403795380133393801378140793802379940783803383240773804383340763805380840753806378340743800378240733808378442023809380442013810383842063811381442053812378642043807378542033814378738153810381638373817383938183843381938213813378938213790376438223818376738233846376638203825376538253792385838263823385738273847386038243797385938293798297938303850297838313851297738323834298138283802298038343803383538313836385338373840383838153833380938403816394738413836394638423854394538393844394438443817390638453842390538463848390838433822390738483826387338493845387638503856387538473829387438523830414538533855414738513835414638553841818038563852817938543849817838583861382538593864382438603867382738573870382638623857347938633872348138613865348038653858346338663863346538643868346438683859406238693866406438673871406338713860323938723869324138703862324038743877384738753880385038763883384938733886384838783873322338793888322538773881322438813874816938823879817138803884817038843875815638853882815838833887815738873876389338883885389538863878389438903893392038913896392338923899392238893902392138943889388638953904388838933897388738973890815338983895815538963900815439003891320439013898320638993903320539033892322639043901322839023894322739063909384439073913384339083917384639053920384539103905393539113923393439123924393339093914393639143906391539123916392739133918391839073772391939163774391739303773392139083889392239323892392339253891392039103890392539113147392639223146392439283148392839153531392939263530392739313529393139193487393239293486393039213485393439373911393539413910393639443909393339483912393839333126393939513125394039523124393739563123394239348181394339588183394139458182394539353842394639433841394739543840394439493839394939363950394739513953394839383953393939543950395539463952395739573940417139583955417039563942416939603963801039613967800939623971800839593976800739643959666239653985666539663986666439633989666339683960778239693992778139703993778439673972778339723961783739733970783639743998783539754002783439713977783839773962378239783975378139794008378039804007377939814006377839824009378739834014378639844019378539853987378439763964378339873965673739883984673939864023673839903966652139914026652039923994651939893968652239943969647739953991648139964030648039974035647939933999647839993973434740003997434640014040434539984003434840033974237640044001237540054039237440064010238040073980237940083979237840023978237740103981401140054012403840134041400940154015398242964016401342954017404442944018404542984014402042974020398371564021401871554022404871584019402471574024398870934025402270924023402770914027399070754028402570784029404770774026403170764031399564244032402964284033404664274034404364264030403664254036399640374034403840424039401140404004403540004042401263934043403763964044403363954041401663944046401771434047403271424048402871414045402171404050405333154051405633144052405933174049406233164054404934604055406434624053405734614057405032524058405532544056406032534060405132424061405832444059406332434063405238674064406138694062405438684066406980244067407380234068408080264065408580254070406566364071408966354072409266344069407466374074406638064075407238054076409838044077409938034078410338024079410838014073408138004081406778194082407978184083410778174084410978214080408678204086406850324087408450314088411450344085409050334090407050974091408850964089411850984093407152124094412052114095412152104096412552094097412952084098410052074092407552134100407641014097410241344099410441044077269441054102269341064133269241074110269141084082269041034078269541104083453541114106453941124132453841134135453741094115453641154087502241164113502141174138502041144123501941194091514441204122514341184093514541224094511941234119511841244117512141214126512041264095790441274124790341284137790641254130790541304096413141284132413641334111413441054129410141364112795841374131795741384127795641354116795941404142297341414145297241394148297141434139414441504142414641464140385141474144385341454149385241494141415341504147415241484143415141524154415041534157414941514160414841554151416341564162416541544158416441584152818641594156818541574161818441614153813741624159813641604155813541644166415441654169415641634172415541674163416841744166417041704164395841714168395741694173395641734165310541744171310441724167310641764179676141774187676041784193675941754197675841804175521741814200521641824201521541834207521441844213522141854218522041864189521941794188521841884176682941894186683441904185683341914221683241924222683141874194683041944177677341954192677641964226677541934231677441984178675041994234674942004202674841974180675142024181380842034199380742044233381242054229381142064235381042014208380942084182420942064210424142114242421242464207421442144183566042154212565942164249565842174250565742134219566142194184562842204217563142214253563042184190562942234191625642244257625542254237625842224227625742274195428642284225428542294236428942304204428842264232428742324196716842334230716742344203717042314198716942364205423742284238422442394256424042584241424342354209424342105949424442405948424542605947424242475950424742115885424842455884424942515883424642155886425142165887425242485889425042615888425442206145425542636149425642646148425742386147425342236146425942396166426042666165425842446167426242525905426342655907426142545906426542556159426642626161426442596160426842726275426942776274427042816273427142856272426742906276427342676388427442936392427542946391427642996390427242786389427842687692427942767691428043027690427742827693428242696788428342806787428443036786428142866785428642704227428742844226428843064230428942964229428542914228429142714292428942934295429042734295427440164296429240154297428840144298430540184294430040174300427571314301429871304302430471294299427971324304428371534305430171524306429771514303428771544308431143534309431543524310431943554307432443544312430743934313432843924314432943954311433543944316430878814317433878844318433978834315432078824320430943214318432243444323434543194325432543102300432643232299432743482298432843302302432443122301433043137829433143277828433243477833433343427832433443417831432943367830433643144490433743344489433843404492433543164491434043176490434143376489434243336488434343326487434443466486433943216491434643224000434743433999434843313998434543264001435043527873435143567872434943607871435343494308435443634307435543654310435243574309435743504358435543594364435643614361435143724362435943714363436643704360435343734365435823304366435423324364436223314368437023474369437423464367437823454371436743624372438143614373438343604370437543634375436843884376437343914377438243904374437943894379436944064380437744094381438444084378437144074383437678754384437278744382438078764386438823344387439223334385439623354389438543744390439943774391440143764388439343754393438643124394439143114395440043144392439743134397438744644398439544674399440244664396438944654401439444884402439044874400439844864404440623294405441023284403441423274407440343784408441743814409441943804406441143794411440444244412440944274413441844264410441544254415440544164413441744204414440744194412805944204408805844184416805744224424234444234428234344214432234244254421441044264435441344274437441244244429441144294422444244304427444544314436444444284433444344334423443444314435443844324425443744304679443844264681443644344680444044422349444144462348443944502350444344394428444444534431444544554430444244474429444744404460444844454463444944544462444644514461445144418046445244498049445344568048445044438047445544484580445644444579445444524578445844602338445944642337445744682336446144574446446244714449446344734448446044654447446544584396446644634399446744724398446444694397446944594503447044674502447144744501446844614504447344664477447444624476447244704475447644784474447744824473447544864472447944754505448044894508448144934507447844834506448344764573448444814572448544964571448244974574448744774402448845004401448644904400449044794336449144884335449244994338448944944337449444804662449544924665449644984664449344844663449844857888449944957887450044917886449744877885450245054470450345094469450445154468450145204471450645014478450745244481450845284480450545104479451045027827451145087826451245307825451345317824451445357823450945167822451645032309451745142308451845392307451945402311451545212310452145048051452245198050452345458053452045258052452545064589452645234588452745444591452445464590452945074969453045494968452845114970453245125012453345515011453445525014453145365013453645134109453745344113453845554112453945414111453545174110454145184542453845434557454445474545452645404522454745274599454845434601454645584600455045294894455145604893454945324895455345337936455445597938455245567937455645377962455745547961455545427960455945484881456045534883455845504882456245644660456345674659456145714661456545618079456645748078456445758080456845624586456945774585457045784584456745724587457245634484457345704483457445804482457145654485457645664675457745794674457545684673457945694456458045764455457845734454458245848054458345888056458145928055458545814569458645954568458745974567458445894570458945824525459045874524459145964527458845934526459345834594459145954598459245854597459046394598458646414596459446404600460245464601460545484599460845474603459946204604461046194602460646184606460048704607460448694605460948714609460146104607460846034612461448424613461848444611462148434615461148364616462448354617462848384614463348374619461246044620463846034618463946024622461348514623464248534621462548524625461549234626462349224627464549254624462949244629461647124630462747114631465047104632465147094628463447134634461746354632463646554637465646384640463346194640462045964641463745984639465945974643462249654644466249674642464649664646462665114647464465104648466565094649466665144650465265134645463065124652463146534649465446694655465746514635465746364708465846544707465646704706466046414562466146724561465946634563466346434493466446614496466546674495466246474494466746487895466846647894466946717893466646537892467146588076467246688075467046608077467446764577467546794576467346824575467746734678468446764680468046744436468146784438467946834437468346754687468446814686468246774685468646884684468746914683468546944682468946854697469046964699468846924698469246868066469346908068469146958067469546878073469646938072469446898074469847004688469947034690469747064689470146974702470847004704470446984705470247034707470746994658470847054657470647014656471047144631471147184630471247234629471347294628470947304632471547094716473347174734471447194719471064464720471764504721473864494722472564484718472464474724471147464725472247524726472147514727473747504728473647494729473147484723471247474731471347324728473347354730471547354716744347364732744747374727744647384726744547344720744447404742492647414746492847394753492747434739482547444756482447454760482747424747482647474740472347484745472947494765472847504766472747514770472647524774472547464778472447544741494547554781494447534782494647574743791547584785791447594786791747564761791647614744476247594763479247644793476547674760474847674749746047684764745947694796746247664771746147714750731447724769731347734797731247704775731147754751727247764773727147774801727447744779727347794752772547804777772447814804772747784754772647834755511547844807511447854787511747824757511647874758524447884784524347894809524247904810524147914799524047924794523947864762523847944763748847954791748747964798748647934768748547984772531947994795531848004790531747974812532048024776724548034811724448014805724348054780723348064803723248044808723148084783519248094806519148074788519348114789529448124802529648104800529548144817791148154820791048164824791348134828791248184813796948194831797148174832797048214814491948224834491848234835492148204825492048254815474348264823474248274838474548244829474448294816483048274831483748284818483348194840483448364839483248214841483648224615483748334614483848304617483548264616484048424833484148454832483948484834484348394611484448504613484248464612484648404865484748444864484548494863484948414856485048474855484848434854485248544621485348574623485148604622485548514850485648624849485448584848485848524913485948564912485748614911486148534904486248594903486048554902486448664847486548694846486348724845486748634875486848744877486648704876487048644606487148684605486948734607487348657968487448717967487248677966487648784866487748814868487548844867487948754887488048864889487848824888488248764558488348804560488148854559488548777941488648837940488448797939488848904878488948934880488748964879489148874899489248984901489048944900489448884550489548924549489348974551489748895002489848955001489648915000490049024890490149054892489949084891490348994862490449104861490249064860490649004961490749044960490549094959490949014952491049074951490849034950491249144859491349184858491149224857491549114932491649254935491749274934491449194933491949124821492049174820492149264823491849234822492349134625492449214624492549284627492249154626492749204739492849164741492649244740493049324947493149364949492949404948493349294914493449434917493549454916493249374915493749305058493849355057493949445056493649415055494149315127494249395126494349465125494049335128494549384754494649344753494449424755494849504929494949534931494749564930495149474910495249584909495049544908495449484998495549524997495349574999495749494972495849554971495649514973496049624907496149654906495949684905496349594982496449704984496249664983496649604642496749644644496549694643496949614529497049674528496849634530497249744957497349784956497149824958497549715040497649855039497749895042497449795041497949725060498049775059498149925062497849935061498349734962498449964964498249864963498649757848498749847847498849957850498549907849499049767857499149887856499249947855498949807858499449816506499549916505499649876508499349836507499850004954499950034953499750074955500149974898500250114897500050154896500449985135500550185134500650195133500350085136500849995038500950065037501050225036500750125035501250014532501350104531501450214534501150164533501650027928501750147927501850207926501550047925502050054117502150174116502250134115501950094114502450277844502550317843502650357846502350397845502850237991502950427994503050437993502750327992503250244086503350304085503450454088503150364087503650255010503750345009503850465008503550405007504050264975504150384974504250484977503950284976504450295088504550475087504350335089504750375080504850445079504650415078505050525077505150555076504950595075505350495155505450635157505250675156505650504939505750704938505850714937505550604936506050514979506150584978506250744981505950644980506450536601506550626600506650736599506350686602506850547717506950667716507050727719506750567718507250576516507350696515507450656518507150616517507650785051507750815050507550845049507950755048508050865047507850825046508250765124508350805123508150855122508550775104508650835103508450795102508850905044508950935043508750965045509150875099509250985101509050945100509450886647509550926646509350976645509750894090509850954089509650914091510051025090510151055092509951085091510350995086510451105085510251065084510651005151510751045150510551095149510951015142511051075141510851035140511251145139511351185138511151225137511551114783511651254782511751294785511451194784511951124122512051174121512151324124511851334123512351135083512451365082512251265081512651154942512751244941512851354940512551304943513051167902513151287901513251347900512951207899513451215005513551315004513651275003513351235006513851405113513951435112513751465111514151375110514251485109514051445108514451384119514551424118514351474120514751395190514851455189514651415188515051525107515151555106514951585105515351495161515451605163515251565162515651505052515751545054515551595053515951516644516051576643515851536642516251645152516351675154516151705153516551615173516651725175516451685174516851627715516951667714516751717713517151636709517251696711517051656710517451765164517551795166517351825165517751735185517851845187517651805186518051747227518151787226517951837225518351757217518451817216518251777218518651885176518751915178518551945177518951855148519051965147518851925146519251864808519351904807519151954809519551875247519651935246519451895245519852015199520752005214519752225202519752035229520452305205523452065238520152085208519840975209520640965210524440955211524340945212524540935213524840925207521540985215519941825216521341815217525141805218525241795219525641865220526041855221522441845214522341835223520055725224522155715225522055785226526355775227526455765228526855755229523155745222520255735231520375495232522875525233527175515230523575505235520475005236523374995237527274985234523974975239520547925240523747915241527547905242527647895243524647885244521047875238520947865246521151965247524251955245527951945249521267255250528167285251525367275248521667265253521771785254525071775255528271765252525771755257521854515258525554505259528554495256526154525261521954865262525954855263526554885260522554875265522654325266526254315267528754305264526954295269522773545270526773535271527373525268523273555273523653055274527053045275528853035272524053065277524152915278529052935276528452925280524772205281528372195279524972215283525472045284528072065282527872055286525853925287528953915285526653935289527453375290528653395288527753385292529452765293529752785291530052775295529148105296530248125294529848115298529253455299529653445297530153435301529353365302529953355300529553345304530752745305531052735306531352725303531752755308530353325309532053315307532153335311530473465312532473455310531473475314530574965315531274955316532774945313531874935318530647995319531647985320533047975317530848005322530954095323532954115321532554105325531173285326532373275324532873295328531573095329532673085330532273075327531973105332533453085333533753075331534053095335533153025336534253015334533853005338533252885339533652905337534152895341533353845342533953835340533553825344534652995345534952985343535252975347534353555348535453575346535053565350534472425351534872415349535372405353534572125354535172115352534772105356535853465357536153485355536453475359535553675360536653695358536253685362535672515363536072505361536572495365535772005366536371995364535971985368537053585369537353605367537653595371536753795372537853815370537453805374536872795375537272785373537772805377536954485378537554475376537154465380538253705381538553725379538853715383537953425384539053415382538653405386538054055387538454045385538954035389538153965390538753955388538353945392539452865393539752855391540052875395539153905396540253895394539853885398539254445399539654435397540154455401539354425402539954415400539554405404540653875405540953865403541253855407540354285408541454275406541054265410540453215411540853235409541353225413540572755414541172775412540772765416541973325417542373315418542673305415542973335420541555145421543255135422543355125419543755155424541676225425543976245423542776235427541754085428542554075426544054065430541852675431544252665432543452655429542052645434542154755435543154745436544154735433543854765438542273635439543673655437542473645441542854025442543554015440543054005444544653985445544953975443545353995447544353785448545753775446546153765450544452585451546452575452546552565449545452595454544554695455545254725456546854715453545854705458544776765459545676755460546776785457546276775462544871825463546071815464546671805461545071795466545168365467546368355468545968385465545568375470547354535471547754565472548154555469548554545474546954355475548854345476549154335473547854365478547076415479547676405480549076435477548276425482547168655483548068645484548968635481548668625486547252615487548452605488549252635485547452625490548354935491547954965492547554955489548754945494549754895495550454925496551254915493551654905498549362275499551962265500552062255501552562245502553062235503550662295497550562285505549455975506550355965507550255955508553355945509553455935510554055925511554455995504551355985513549554215514551154205515554754195512555054225517549676455518555276445519552176475516549876465521549962855522551862845523555362835524555662875520552662865526550055275524552855605529553655255531553155015532552955335535553055075535550855365532553755285538555955395561553455415541550975545542553975535543556375565540554575555545551073605546554373625544554873615548551473435549554673425547556473445551551573665552555473685550551773675554552273915555555173905553556773925557552374215558556674205559556874195560553774185556552774175562553875405563557075395561554275415565554974095566556974085567555774075564555574065569555876075570556576095568556276085572557952235573558352225574558852295575559252285576559952275577559852265578559752255571560052245580557156815581560356845582560456835579558456825584557255855582558656075587560855835589558955735590558755915612558855935593557455095594559155085595561155075596561355065597560155055598557755045599557655115592557555105601557856195602559656185603561656175600558056205605558157135606561557125607560957155604558557145609558656105606561156145612559456085590561455955695561556105694561656055693561356025692561856215602561956245601562056285600561756325603562256175686562356365685562156375687562556186231562656396230562756406233562456296232562956194218563056274221563156444220562856334219563356205664563456315663563556435662563656425666563256225665563856236193563956416192563756256194564156266126564256386125564356356124564456346128564056306127564656495892564756535891564856575890564556625893565056455739565156665742565256675741564956725740565456465880565556755879565656765882565356585881565856474216565956564215566056804214566156814213565756634217566356485634566456615633566556845632566656685636566256505635566856515708566956655707567056835711567156785710566756735709567356525816567456715815567556775818567256545817567756555678567456795670568056825676565956825660557956835679558256845669558156815664558056865688562256875692562156855696562356895685570356905699570656915701570556885693570456935686561656945691561556955700561456925697561356975687618256985695618156995702618056965689618357015694570256905700569857045707568857055712569157065716569057035720568957085703566857095724566757105723567157115725567057075713566957135704560557145711560457155728560757125717560657175705571857155719572757165721572157065778572257195782572357265781572457095780572057085779572657105727572257285718572557145730573259025731573559045729573959035733572959225734574359245732574759235736573081875737574981905738575081895735574081885740573156495741573856525742575356515739574456505744573361155745574261145746575261135743575461125748573459635749575659655747573659645751573757765752575557755753574557745750574157775755574660795756575160785754574860775758576260845759576660835760577160875761577460865757577860855763575757645782576557835762576757675758576857655769578757705788576657925772575960755773579460745771577560765775576057525776577357515777579557505774577957535779576157205780577757245781579857235782578457225778576357215784576457855781578657975787578957835768578957696051579057866050579157966049578857936048579357706069579457916068579257726070579657765802579757905801579857855800579557805799580058035798580158065797580258095796579958125795580457995819580558145821580358075820580758005844580858055846580658105845581058018213581158088215580958138214581358028197581458118199581258048198581658195673581758225672581858255675581558285674582058155803582158305805581958235804582358168194582458218196582258268195582658175854582758245856582558295855582958185835583058275837582858205836583258355833583858345841583158445836583158285837584658305835583958295839583258515840583758535838584258525842583382165843584082185841584582175845583458065846584358085844583658075848585158635849585458665850585758655847586058645852584758385853586258405851585558395855584858255856585358275854585858265858584981915859585681935857586181925861585082075862585982095860585282085864586758475865587158505866587558495863587958485868586358695882587058855867587258725864593858735870593758745884593658715876593558765865590058775874589958785883589858755880590158805866565458815878565358825886565658795868565558845877424858855873424758865869424658835881424958885890425058895894425258875898425158915887564758925901564658935903564558905895564858955888590858965893591158975902591058945899590958995889587759005897587659015904587558985891587859035896572959045892573159025900573059065908426159075912426359055916426259095905589459105919589759115922589659085913589559135906613159145911613059155924612959125917613259175907616359185915616259165920616459205909595459215918595659195923595559235910573259245921573459225914573359265928595359275932595259255935595159295925603059305938603359315939603259285943603159335926617659345946617559325947617459365927587459375950587359385940587259355929587159405930594159375942594959395944594459315945594259465948594359335948593442445949594542435950594142425947593642455952595459275953595759265951596059255955595159195956596259215954595859205958595259775959595659765957596159755961595359685962595959675960595559665964596657475965596957495963597257485967596359625968597459615966597059605970596460255971596860245969597360235973596560165974597160155972596760145976597859595977598159585975598459575979597559875980598659895978598259885982597661575983598061565981598561585985597761695986598361685984597961705988599059785989599359805987599659795991598759995992599860015990599460005994598861345995599261335993599761355997598959985995599659916000600259906001600559925999600859916003599960116004601060136002600660126006600061176007600461166005600961186009600160106007600860036012601460026013601760046011602060036015601159746016602259736014601859726018601260736019601660726017602160716021601360646022601960636020601560626024602659716025603059706023603459696027602360446028603760476029603960466026603160456031602459286032602959316033603859306030603559296035602582046036603382036037604082066034602782056039603260406028603860366042604460596043604860616041605260606045604160266046605560296047605760286044604960276049604257916050604757906051605657896048605357886053604360546051605560586052604560576050605860466056605460606062604160616065604360596068604260636059602260646070602160626066602060666060606760646065606960696061579360706067579260686063579460726074601960736077601860716080601760756071577260766082577160746078577360786072575660796076575560776081575460816073611060826079610960806075611160846088575860856092575760866096576160876100576060836104575960896083609061036091610560886093609360846094609160956108609260976097608561856098609561846099610761876096610161866101608661236102609961226103610661216104608961206100608761196106609061986107610261976108609861966105609461956110611260816111611660806109611960826113610957466114612357456115612457446112612957436117611060066118613360056116613660076120611161046121614061036122614161026123612561016119611361006125611456426126612256416127614456406128614556446124613056436130611559146131612859136132614959126129615059156134611759946135615259936133613759956137611861386135613961476140614261366120614261216208614361396211614461466210614161266209614661274253614761434257614861384256614961514255614561314254615161326155615261486154615061346153615461566152615561596151615361626150615761535982615861645981615661605983616061544264616161584266615961634265616361555917616461615916616261575918616661684259616761714258616561744260616961655985617061765984616861725986617261666173617061716175617561675934617661735933617461695932617861806179618461776188618161775698618261915697618361935696618061855699618561786097618661836096618761926099618461896098618961796205619061876204619161946207618861816206619361865638619461825637619261905639619661996108619762046107619862086106619562126105620061956201621762026218620362236199620562056196618962066203618862076229619162046230619062096197614162106233614462116234614362086213614262136198621462116215623762166238621762196212620062196201622062166221624162226242621862246224620255016225622255006226624554996227624654986228625054976229623155036223620655026231620756256232622856246233624956276230620956266235621062516236624862546237623962536234621462526239621563536240623663526241624363516238622063546243622163426244624063416245624763406242622563396247622668606248624468596249623568586250623268576246622768616252625562346253625962376254626362366251626762356256625142236257627142226258627242256255626042246260625262616258626262766259626462646253636662656262636562666275636462636268636362686254685562696266685462706274685362716273685262676256685662736257427062746270426962756269426862766265426762726261427162786280739662796283739862776288739762816277763262826293763162806297763362846278552262856300552162866301552062876306552462836289552362896279743962906287743862916309744262926310744162886294744062946281730062956292729962966314730262936315730162986282766262996318766163006302766062976284765963026285632363036299632263046317632163056312632063016307631963076286630863056309631163066290631162916468631263086472631363046471631463166470631062956469631662967670631763137669631863037668631562987667632063246305632163286304632263336303632363386302631963396301632563196326634263276343632463296329632063976330632764016331634664006332633563996328633463986334632168446335633268436336633168486337634568476338634068466333632268456340632362456341633762446342634462436339632562426344632663486345634163476346633663506343633063496348635163446349635563436350635963466347636363456352634762406353636662396354636962386351635662416356634863576354635863686355636063606349637363616358637263626367637163596364637463646350626663656362626563666370626463636352626363686361636963576370635363676365637263756361637363796360637463836359637163886362637663716377639263786393637563806380637263816378638263966379638463846373641563856382641963866395641863876390641763836389641663896374427263906387427663916386427563926394427463886376427363946377404163956391404463966385404363936381404263986402632863996407633264006411633164016415633063976420632964036397645764046423645664056424645564066429645964026408645864086398693964096406694264106432694164076412694064126399770064136410769964146433769864116416770164166400638364176414638764186436638664196426638564156421638464216401642264196423642564206403642564044030642664224034642764184033642864354032642464304031643064056974643164286973643264346972642964096971643464137147643564317146643664277145643364177144643864426499643964466498644064516497644164556496643764606500644364377721644464637720644564647723644264477722644764384718644864454722644964674721645064684720644664524719645264396453645064546472645164566456644064046457645464036458647164026459647364066455646164056461644166976462645967006463647666996460644366986465644472686466647572676467646972706464644872696469644963106470646663146471647463136472645763126468645363116474645870276475647070306476646570296473646270286478648239936479648639976480649239966481649639956477650139946483647765526484650465516485650565546482648765536487647843436488648543426489650843416490650943406491651443396486649343446493647964946491649565136492649764976480644064986495643964996512643865006515643764966502644165026481653565036500653865046518653765016483653665066484499465076517499365086510499665056488499565106489464765116507464665126516464565136498465065146494464965096490464865166499507265176511507165186506507465156503507365206523399165216526399065226529398965196532399265246519653965256534654165236527654065276520667665286525667865266530667765306521662265316528662465296533662365336522659065346531659265326524659165366539650165376542650465386545650365356548650265406535652365416550652565396543652465436536658765446541658965426546658865466537660365476544660565456549660465496538667965506547668165486540668065526555648365536558648265546561648565516564648465566551657165576566657365556559657265596552779465606557779665586562779565626553780165636560780365616565780265656554785965666563786165646556786065686571658365696574658665706577658565676580658465726567655565736582655765716575655665756568786865766573787065746578786965786569776965796576777165776581777065816570778565826579778765806572778665846587656765856590657065866593656965836596656865886583654265896598654465876591654365916584653265926589653465906594653365946585661965956592662165936597662065976586660665986595660865966588660766006603506566016606506466026609506365996612506666046599654566056614654766036607654666076600659666086605659866066610659766106601662866116608663066096613662966136602668266146611668466126604668366166619665866176622666166186625666066156628665966206615659366216630659566196623659466236616652966246621653166226626653066266617667366276624667566256629667466296618660966306627661166286620661066326634671466336638671366316642671266356631407166366645407066376648406966346639407266396632665666406637665566416650665466386643665766436633516066446641515966426646515866466635509566476644509466456649509366496636773366506647773266486640773166526654773466536658773666516662773566556651664066566665663966576667663866546659664166596652661566606657661866616666661766586663661666636653396366646661396666656668396566626655396466676660672366686656672266666664672466706673668566716676668866726679668766696682668666746669662566756684662766736677662666776670652666786675652866766680652766806671654866816678655066796683654966836672661266846681661466826674661366866689666966876693667266886697667166856701667066906685672166916704672066926707671966896694671866946686770766956692770666966706770566936698770866986687646066996696646367006705646266976702646167026688704567036700704467046708704367016690704667066699702667076695702567086691702467056703702367106712517067116715517267096718517167136709663367146722663267126725663167166710722467176728722367156729722267196711669267206732669167216733669067186723668967236713666767246721666667226736666867266714524867276735525167286730525067256716524967306717718767316727718667326734718967296719718867346720674367356731674267366726674167336724674067386740398667396744398867376748398767416737673667426751673567436753673467406745673367456738710267466743710567476752710467446749710367496739419967506747419867516754419767486741420067536746675767546742675667526750675567566758675467576762675367556766675267596755417867606769417767616771417667586763417567636756719167646761719067656770719367626767719267676757680467686765680767696772680667666759680567716764682067726760681967706768681867746777419367756781419667766785419567736789419467786773680367796792680267806795680167776782680067826774716667836780716567846794716467816786716367866775428467876784428367886793428267856790428167906776682867916788682767926796682667896778682567946787691567956783691467966779691367936791691267986800710667996804710867976808710768016797678068026811677968036813677868006805677768056798676668066803676968076812676868046809676768096799687568106807687468116814687368086801687668136806681568146802681768126810681668166818681268176821681468156825681368196815677268206829677168186835677068226816688968236839689268246843689168216849689068266817679268276851679168286852679068256830678968306819418768316828419268326856419168336857419068346862418968296836418868366820546668376834546568386865546868356840546768406822768168416838768068426866767968396844768268446823633468456842633368466869633868476859633768486854633668436870633568506824690568516872690768496826690668536827627068546871626968556847626868566858626768526831627168586832624968596855624868606846624768616868624668576863625068636833548468646861548368656867548268626837548168676841765668686864765568696860765868666845765768716848770468726853770368706850770268746877681068756880680968766883680868736886681168786873689368796888689568776881689468816874701068826879701268806884701168846875696268856882696468836887696368876876693068886885693268866878693168906893682168916896682468926899682368896902682268946889687768956904687968936897687868976890692768986895692968966900692869006891694369016898694568996903694469036892701369046901701569026894701469066908684969076912685169056916685069096905692369106919692669116921692569086913692469136906679669146911679569156920679469126917679369176907769669186915769569196922769469166909769769216914713369226910713569206918713469246927690869256930691169266933691069236936690969286923689669296938689869276931689769316924688669326929688869306934688769346925695969356932696169336937696069376926694669386935694869366928694769406943640769416946641069426949640969396952640869446939689969456954690169436947690069476940693669486945693869466950693769506941696869516948697069496953696969536942701669546951701869526944701769566959699069576962698969586965698869556968698769606955693369616970693569596963693469636956688369646961688569626966688469666957700769676964700969656969700869696958694969706967695169686960695069726975643269736978643169746981643069716984642969766971699169776986699369756979699269796972711669806977711869786982711769826973708269836980708469816985708369856974705069866983705269846976705169886991695869896994695769906997695669877000695569926987697569937002697769916995697669956988704769966993704969946998704869986989706369996996706569977001706470016990711970026999712170006992712070047007701970057010702270067013702170037016702070087003696570097018696770077011696670117004688070127009688270107014688170147005690270157012690470137017690370177006695270187015695470167008695370207023700370217027700670227031700570197035700470247019670870257038670770267041670670237028670570287020647370297026647670307040647570277032647470327021768670337030768570347039768470317036768370367022719570377034719470387042719770357024719670407033725570417029725470427025725370397037725270447047670370457050670270467053670170437056670470487043699470497058699670477051699570517044698470527049698670507054698570547045707970557052708170537057708070577046706670587055706870567048706770607063709670617066709570627069709470597072709770647059699770657074699970637067699870677060705670687065705870667070705770707061708870717068709070697073708970737062712270747071712470727064712370767079402670777082402970787085402870757088402770807075705370817090705570797083705470837076698170847081698370827086698270867077711370877084711570857089711470897078706970907087707170887080707070927094402570937098402470917102402370957091706170967105706070977107705970947099706270997092717371007097717271017106717170987103717471037093674471047101674771057108674671027095674571077100679771087096679971067104679871107113713971117116713871127119713771097122713671147109708571157124708771137117708671177110697871187115698071167120697971207111700071217118700271197123700171237112707271247121707471227114707371267129715971277133716271287136716171257140716071307125430171317143430071327144429971297148430271347126692071357150692271337137692171377127711271387135711171397146711071367141710971417128404871427139404771437145404671407130404571457131643671467142643571477138643471447149643371497132768771507147768971487134768871527155430571537159430471547163430371517167430671567151402071577170401971587173402271557160402171607152712571617158712871627172712771597164712671647153678471657162678371667171678271637168678171687154423271697166423171707174423471677156423371727165710071737161709971747157709871717169710171767179525571777183525471787186525371757190525271807175546471817193546371827194546271797198546171847176720171857200720371837187720271877177673071887185672971897196673271867191673171917178676371927189676271937195676571907180676471957181703671967192703571977188703871947199703771997182536672007197536571987184536472027204718372037207718572017210718472057201528272067212528472047208528372087202721572097206721472077211721372117203535472127209535372107205535272147216720972157219720872137222720772177213518372187224518272167220518472207214528072217218527972197223528172237215671772247221671672227217671572267228518172277231518072257234517972297225723772307236723972287232723872327226480672337230480572317235480472357227773072367233772972347229772872387240722872397243723072377246722972417237535172427248535072407244534972447238480372457242480272437247480172477239726272487245726172467241726072507252536372517256536272497260536172537249704272547263704172557267704072527257703972577250728872587255729172597270729072567271728972617251724872627274724772607264724672647253770972657262771272667273771172637268771072687254646572697266646472707272646772677258646672727259477572737269477472747265477772717261477672767278541272777281541472757284541372797275537472807288537372787292537572827276762172837296762072817285761972857277730372867283730672877299730572847289730472897279725672907287725972917302725872887293725772937280767472947291767372957301767272927297767172977282762572987295762772967300762673007286629473017298629373027294629672997290629573047307728473057311728773067315728673037319728573087303532973097322532873107325532773077312533073127304477373137310477273147324477173117316477073167305745873177314745773187323745673157320745573207306758473217318758373227326758273197308758573247317747273257313747173267309747473237321747373287330532573297334532473277338532673317327541773327341541673337343541573307335541873357328734873367333735173377342735073347339734973397329757573407337757473417344757773387331757673437336554873447332554773427340554973467348531173477352531073457356531273497345733473507359733773517361733673487353733573537346527073547351526973557360526873527357527173577347756573587355756473597362756773567349756673617354554473627350554673607358554573647366543773657369543973637372543873677363555073687374555273667370555173707364737673717368737573697373737773737365763773747371763973727367763873767378737073777381736973757384737173797375738773807386738973787382738873827376761773837380761673817385761873857377762973867383762873847379763073887390737873897393738073877396737973917387555473927398555373907394555573947388740173957392740073937397739973977389627773987395627973967391627874007402739574017406739473997410739374037399743774047413743674057415743574027407743474077400556774087405556674097414556574067411556474117401758074127409757974137416757874107403758174157408761174167404761074147412761274187422556074197426555974207431555874217434555774177438555674237417742474427425744374227427742774187428742574297447743074487426745274327419760274337454760174317435760374357420740574367433740474377455740374347439740274397421628974407437628874417458629274427444629174387423629074447424473474457441473874467457473774477449473674437428473574497429746874507446746774517456747074487453746974537430751674547451751574527432751774567436731874577450731774587445731674557440731574607463476774617467476674627471476974597475476874647459746574787466747974637468746874607449746974667448747074817451746774727450747274617324747374707323747474827326747174767325747674627489747774747492747874847491747574647490748074657509748174837511747974697510748374737595748474807597748274777596748674894796748774934795748874974794748575014793749074857475749175047478749275077477748974947476749474865316749574925315749675065314749374985313749874875237749974965236750075055235749775025234750274887503750075047508750174907506749975637507749575627508749175617505750375607510751274797511751574817509751874807513750975147520751275167516751074537517751474527515751974547519751175237520751775227518751375217522752475207523752775197521753075187525752175337526753275357524752875347528752276047529752676067527753176057531752375997532752975987530752576007534753675247535753975267533754275257537753375387544753675407540753455627541753855617539754355637543753575597544754175587542753775577546754975477553754875577545756075507545523075517563523375527564523275497554523175547546554175557552554075567567554375537558554275587547754475597556754375577568754275617548750875627570750775637565750675607550750575657551735775667562735675677569735975647555735875697559759375707566759275687561759475727574758975737578759175717582759075757571733975767585733875777587734175747579734075797572741275807577741175817586741075787583741375837573732175847581732075857588731975827575732275877580761375887576761575867584761475907592757175917595757375897598757275937589756975947600756875927596757075967590748275977594748475957599748375997591753176007597753075987593753276027604743276037607743176017610743376057601752776067612752976047608752876087602556876097606557076077611556976117603741576127609741476107605741676147616758676157619758876137622758776177613738276187624738176167620738376207614728376217618728276197623728176237615542376247621542576227617542476267628729676277631729876257634729776297625738576307636738476287632738676327626628176337630628076317635628276357627765076367633764976347629764876387640737276397644737476377648737376417637547876427651547776437655548076407645547976457638551776467643551676477658551976447659551876497639763676507662763576487652763476527641766576537650766476547661766376517656766676567642686776577654686676587660686976557646686876607647630076617657629976627653629876597649629776647667765376657671765276667675765176637679765476687663631876697682631776707685631676677672631576727664729576737670729476747684729376717676729276767665545876777674545776787683546076757680545976807666684176817678684076827686683976797668684276847677703476857673703376867669703276837681703176887690714876897694715076877698714976917687427976927701427876937703427776907695428076957688691876967693691776977702691676947699691976997689641377007697641277017704641176987691641477037696687277047692687177027700687077067709669577077713669477087716669377057720669677107705726377117723726677127724726577097728726477147706516977157730516877137717516777177707506877187715506777197726507077167721506977217708644377227719644277237725644577207710644477257711477977267722477877277718478177247729478077297712723677307727723577287714723477327734665077337737664977317740664877357731665177367743665377347746665277387732800177397748800377377741800277417733803077427739803277407744803177447735802077457742802277437747802177477736775377487745775577467738775477507753776577517756776877527759776777497762776677547749774677557764774877537757774777577750801777587755801977567760801877607751797977617758798177597763798077637752800477647761800677627754800577667769774977677772775277687775775177657778775077707765657777717780657977697773657877737766786577747771786777727776786677767767780777777774780977757779780877797768778877807777779077787770778977827785396877837788396777847791397077817794396977867781658077877796658277857789658177897782777877907787778077887792777977927783780477937790780677917795780577957784655877967793656077947786655977987801785177997804785478007807785377977810785278027797656178037812656378017805656278057798779178067803779378047808779278087799777578097806777778077811777678117800786278127809786478107802786378147817230678157822230578167828230478137834230378187813408278197838408178207839408078217843408478177823408378237814451478247821451378257846451278267847451178277830451078227829450978297815433078307827432978317826433478327850433378337851433278287835433178357816397478367833397378377854397278387840397178347818397578407819797778417837797678427853797578397844797878447820502478457842502378467848502678437824502578487825498678497845498578507852498878477831498778527832779778537849780078547841779978517836779878567859499178577862499078587865498978557868499278607855656478617870656678597863656578637856781078647861781278627866781178667857777278677864777478657869777378697858657478707867657678687860657578727874435178737877435078717881434978757871438378767885438278747889438478787872787978917880789278777882788278734315788378804318788478954317788178864316788678754500788778844499788878944498788578964497789078768063789178988065788978788064789378794669789478974668789578874667789278834666789778888071789878938070789678908069790079035132790179075131790279105130789979145129790478994126790579174125790679184128790379224127790879007929790979247931790779117930791179014814791279094813791379204816791079154815791579024757791679134756791779194759791479044758791979057920791679217912791879237923790679477924792179467922790879457926792950187927793250177928793650167925793950157930792579077931794279097929793379087933792679497934793179487935794479517932793779507937792745527938793545547936794045537940792848867941793848857939794348847943793079647944794179637942793479657946794879247947795279237945795679227949794579337950795979327951796179357948795379347953794679547951795579607952795779577947413779587955413679597962413579567949413879617954455779627950455679607958455579647966794379657969794279637972794479677963487479687974487379667970487279707964481779717968481979697973481879737965797479717972796779767979784179777982784079787985783979757988784279807975775979817990776179797983776079837976801479847981801679827986801579867977803679877984803879857989803779897978799579907987799779887980799679927995502779937998503079948001502979918004502879967991798879978006799079957999798979997992803380007997803579988002803480027993773780038000773980018005773880057994776280068003776480047996776380088011396280098014396180108017396080078020395980128007802780138022802980118015802880158008798280168013798480148018798380188009775680198016775880178021775780218010774380228019774580208012774480248027406680258030406580268033406880238036406780288023801180298038801380278031801280318024774080328029774280308034774180348025799880358032800080338037799980378026798580388035798780368028798680408042234180418046234080398050233980438039804480538045805580428047804780404450804880454453804980544452804680514451805180414521805280494520805380564523805080434522805580484581805680444583805480524582805880604420805980634419805780664418806180578062806880608064806480587889806580627891806380677890806780594691806880654693806680614692807080727898807180757897806980787896807380694695807480804694807280764696807680704671807780744670807580794672807980714565808080774564807880734566808280843053808380873052808180903051808580813631808680923633808480883632808880823579808980863578808780913577809180833396809280893395809080853397809480963354809580993353809381023355809780933523809881043525809681003524810080943694810180983696809981033695810380958104810181028097810681083693810781113692810581143691810981058110811681088112811281068119811381108118811181158117811581072386811681132385811481092384811881208113811981238112811781268111812181172383812281282382812081242381812481188125812281238127812781193744812881253743812681213742813081323028813181353030812981383029813381298143813481408142813281368141813681304162813781344161813581394160813981312975814081372974813881332976814281448134814381478133814181508132814581418177814681538176814481568175814881428166814981588168814781518167815181433207815281493209815081543208815481453896815581523898815381573897815781463883815881553885815681483884816081632992816181662991816281692994815981722993816481593210816581743212816381673211816781608147816881658149816681708148817081613880817181683882816981733881817381623220817481713222817281643221817681788146817781818145817581848144817981753856818081863855817881823854818281763941818381803943818181853942818581774159818681834158818481794157818881915735818981945738819081975737818782005736819281875857819382025859819181955858819581885822819681935824819481985823819881895812819981965814819782015813820181908210820281998212820081928211820482076035820582106034820682136037820382166036820882035860820982185862820782115861821182048200821282098202821082148201821482055809821582125811821382175810821782065841821882155843821682085842822082228343822182268342821982308341822382191682822482331681822582351680822282271679822782208228822582298234822682318231822182498232822982488233823682518230822382508235822882368224823482328238824083158239824483148237824883138241823782608242825182598243825282628240825682618245823883228246825883258247825483248244824983238249823982318250824782308251825382338248824182328253824217588254825017618255824617608252825717598257824383828258825583818256824583838260826382418261826782408262827082438259827382428264825982658276826682778263826882688260831782698266831682678280831882718261839282728279839182708274839082748262177282758272177582768278177482738264177382788265828282798275828182808271828482778269828382828285827882838289827782848293828082818296827982868281181882878298182182888299182082858290181982908282219829182882188292830221782898294220829482838308829582928307829383018309829782848389829883008388829682868387830082878328830182978327830282958326829982918329830483078305831083068313830383168308830382948309831882938307831182958311830483218312830983208310831483198314830582398315831282388313831782378317830682688318831582678316830882698320832283128321832683118319833083108323831982448324833382478325833482468322833882458327832083018328834083008329833682998326833183028331832115583328329154833383351538330832315683358324837083368332837383378328837283348339837183398325838583408337838483388327838683428344822183438348822083418352821983458341158834683551578347835716083448349159834983428350834783518356834883538353834322338354835122368355835822358352834522348357835083588346835683548360836217638361836617628359837017648363835926483648373263836583752668362836726583678360180683688365180583698374180483668371180383718361833483728369833783738376833683708363833583758368182383768364182283748372182483788381179883798384179783808387179683778390179583828377825783838392825683818385825883858378833983868383833883848388834083888379829883898386829783878391829683918380827283928389827183908382827083948396165839584011678393840516683978393267839884092718399841027084008413269839684022688402839418448403840018438404841618428401840618458406839565840784046984088415688409841167840583976684118398132618412840813260841084141326284148399190584158412190484168407190784138403190684188420198284198424198184178428198384218417202842284312018423843320484208425203842584181958842684231957842784321956842484291955842984198198430842782284318434821842884218208433842689684348422895843284308948436843884378442843584468439843520678440844920668441845120698438844320688443843684448441844584508442844784478437101438448844510142844984521014184468439101448451844463584528440637845084486368454845610196845584601019884538464101978457845366284588467661845984696608456846165984618454846284598463846884608465846584558473846684638472846784708471846484578474846984628470845884688466847284758466847384808465847484858464847184908467847684718477849484788495847985008475848184818472848284798483850484848505848084868486847310202848784841020684888508102058489850910204848584911020384918474710849284897148493851271384948496712849084767118496847785408497849385448498851185438499851385428495850185418501847810358850284991035785038516103568504850610355850084821035985068483102578507850310260850885151025985058487102588510848810677851185141067685128497106758509849210674851484981039285158510103918516850710390851385021038985188522851985278520853185218534851785408523851773385248544737852585457368526855273585228528734852885189605852985269604853085549603852785329602853285199584853385309583853185559582853585208765853685578770853785588769853885498768853985488767853485418766854185218495854285398499854385478498854485468497854085238496854685248596854785438602854885428601854985388600855085378599855185618598854585628597855385259609855485649611855285299610855685338797855785598796855585358795855985368706856085568709856185638708855885508707856385518627856485608629856285538628856685681064585678571106448565857610646856985651062385708580106258568858410624857285667238573858972285748590726857585967258571857772485778567106838578857510682857986021068585768603106848581856910492858286061049185838607104908580858510493858585701054385868583105428587860910541858886101054085898591105398584857210538859185738668859285888667859386138672859486148671859585988670859085978669859785748545859885958551859985948550860086168549860186178548860286048547859685788546860485791039586058601103948606862010393860385811039686088582107078609862110709860785861070886118587984486128623984386138624984286108592984586158593979186168626979386148599979286188600981486198625981786208622981686178605981586228608129038623861912905862186111290486258612983186268618983086248615983286288630856286298634856486278638856386318627868786328641868686338643868586308635868486358628962086368633962386378642962286348639962186398629871586408637871486418644871386388631871686438636965486448632965686428640965586468649107718647865610770864886621076986458667107728650864593698651867293688652867193678653867393668654867793658655865893648649865793708657864697478658865597468659865497458660868097448661868197498656866397488663864777286648661771866586837708666868476986628668773866886488591866986668590867086878595867186748594867286518593866786508592867486528702867586708705867686868704867386788703867886539669867986769672868086889671867786599670868286601078486838690107838681866410782868586658633868686898632868786758631868486698630868986799659869086859658868886829657869286958722869386988721869487028720869187068723869686918802869787098801869587108803869986929673870087129676870187139675869887039674870386938673870487018676870587168675870287078674870786948558870887058561870987158560870686968559871186971006787128714100668710869910065871487008640871587118639871687088638871387048641871887209391871987249393871787289392872187178693872287318692872387338691872087258694872587188773872687238772872787328771872487298774872987198845873087278844873187348843872887218846873387268814873487228813873287308815873687388821873787428820873587478819873987358935874087508938874187548937873887438936874387368744874187458759874687608742876587488737881187498770881087478771881287518739947387528774947287538775947187508755947487558740949687568753949587578778949487588779949387598761949887548744949787618745103708762875810369876387811036887648782103728760876610371876687468534876787648539876887858538876987868537877087728536876587488535877287498726877387698725877487888724877187518727877687529942877787899941877887929940877587569943878087571300787818794130068779876213008878387639802878487939801878587919800878287679803878787689790878887909789878687739788879087761304487918787130438789878413042879387771303287948783130318792878013030879687988557879788018556879588048555879987958807880088068809879888028808880287968696880388008695880188058697880587979572880688039571880487999570880888108798880988138800880788168799881188078748881288188747881088148749881488088733881588128732881388178734881788098836881888158835881688118834882088228737882188258736881988288735882388198831882488308833882288268832882688208827882488258829882988218922883088278921882888238920883288348822883388378824883188408823883588318818883688428817883488388816883888328877883988368876883788418875884188338868884288398867884088358866884488478730884588508729884688548728884388578731884888438863884988608865884788518864885188449470885288499469885388629468885088559467885588459415885688539414885488589413885888469441885988569440885788619442886188488973886288598975886088528974886488668847886588698849886388728848886788638842886888748841886688708840887088648918887188688917886988738919887388658892887488718891887288678890887688788839887788818838887588848837887988758887888088868889887888828888888288769565888388809564888188859566888588778886888388848879888888908878888988938880888788968879889188878874889289008873889089048872889488889545889589079544889388979543889788898898889588998910889689018901889189478902889989508903891389498900890589488905889289688906890389678904891489698908889499768909891699758907891199748911889890708912890990698913891590688910890290678915890699858916891299848914890899838918892088708919892388698917892788718921891788308922893188298920893588288924891894758925893894788926893994778923892894768928891989438929892689468930894289458927893289448932892189338930893489418931893689368922873889378934874189388940874089358924873989408925915589418937915489428933915389398929915689448947892789458951893089468955892989438959892889488943890089498962890389508965890289478952890189528944895389508954896489518956895689459126895789549125895889639124895589609127896089468980896189588979896289668982895989488981896489579044896589539043896689499042896389619041896889708905896989738904896789768906897189678991897289788993897089748992897489688860897589728862897389778861897789699453897889759452897689719454898089838960898189878959898289918962897989948961898489799129898589979128898689989131898389889130898889809465898989869464899090019463898789929466899289818970899389908972899190028971899589829018899690049017899789999016899489849019899989859385900089969384900190039387899889899386900389939427900490009426900289959425900690099160900790139159900890169158900590209157901090059192901190259191901290269190900990329189901490069325901590359324901390389326901790078996901890408995901990418994901690218997902190089091902290199096902390449095902490459094902590279093902090109092902790119028902490299050903090519031905490269057903390121316090349059131599032903613158903690141314490379034131439035906013142903990159419904090649421903890179420904290188966904390678965904490468964904190228963904690239047904390489070904990719050905290459028905290291097390539049109729051907410971905590301092590569077109249054905810926905890311316190599056131639057903313162906190379710906290799713906390809712906090659711906590399991906690639990906490689989906890428913906990668912907090828911906790478910907290481095590739081109549071907510953907590531094590769073109449074907810943907890551092090799076109199077906110918908190629952908290729951908090699953908490879174908590919173908690979176908391049175908890839203908991089202909091129201908790929200909290849020909390909025909491179024909591189023909691249022909191289021909890859383909991319382910091329381910191369380910291429379910391439378909791059377910590861276191069103127649107914812763910491091276291099088128429110910712841911191471284491089113128439113908991149111911591469116914991179119911290939119909491209116912191529122913991239153911891259125909589579126912389569127915689559124912989589129909689849130912789839131913389869128909889859133909994599134913094629135915594619132913794609137910095169138913595229139915495219140912195209141915195199142914495189136910195179144910211155914591411115491469150111539147911411152914891101115191439106111569150911511332915191451133191529140113309149912011333915491228941915591388940915691348939915391268942915891619008915991649007916091679006915791709005916291579177916391729179916191659178916591589334916691639336916491689335916891599254916991669256916791719255917191609222917291699224917091629223917491779084917591809083917691839086917391869085917891739161917991889163917791819162918191749219918291799221918091849220918491759235918591829237918391879236918791769337918891859339918691789338919091939012919191969011919292009010918992049009919491891315391959207131529193920813154919791909198921091999211919692019201919190909202919990899203921490889200920590879205919292169206920392159207921392189204919492179209919513094921092121309392089197130959212919813080921392091307992149206130789211920213077921692199205921792229204921892259207921592289206922092159180922192309182921992239181922392169170922492219172922292269171922692179251922792249253922592299252922992189238923092279240922892209239923292359265923392389264923492419263923192449266923692319183923792469185923592399184923992329228924092379230923892429229924292339260924392409262924192459261924592349340924692439342924492369341924892519315924992549314925092579313924792609312925292479225925392629227925192559226925592489167925692539169925492589168925892499331925992569333925792619332926192509241926292599243926092529242926492679233926592709232926692739231926392769234926892639281926992789280926792719279927192641283892729269128409270927412839927492651276592759272127679273927712766927792661275292789275127549276926812753928092829269928192859268927992889267928392791283092849291128299282929412831928692801275192879296127509285928912749928992819297929092879299928892929298929292831271792939290127169291929512715929592841278892969293127879294928612789929893009288929993039290929793069289930192979309930293089311930093049310930492981272793059302127299303930712728930792999345930893059344930693019343931093129300931193169302930993209301931393099250931493239249931593259248931293179247931793101314893189315131479319932413146931693211314593219311934693229319934993239326934893209313934793259318901493269314901393249322901593289331935793299334936093309337935993279340935893329327925793339342925993319335925893359328916493369333916693349338916593389329918693399336918893379341918793419330924493429339924693409332924593449346930893459350930793439353930693479343932093489357932393499361932293469364932193519344126999352937012698935093711269793549345127459355937612748935693771274793539358127469358934793279359935693309360938393299357938493289362934894229363938794249361938894239365934986549366939086539367939186529368939486519369939786509370937286499364935186559372935210750937393691074993749400107489375940110747937693781074693719354107519378935591039379937591029380940491019381940591009382940990999383938590989377935990979385936089999386938289989387941290019384936290009389936394319390941394339388936594329392936687179393941587199391939587189395936797869396939397859394941697879398936898569399941898599400940298589397937398579402937412684940393991268394049406126829401937912681940693809944940794039947940894179946940594109945941093819455941194089458941294149457940993869456941493898856941594118855941393928854941793969885941894079887941693989886942094229038942194259040941994289039942394199361942494309363942294269362942694209004942794249003942594299002942994219448943094279447942894239446943294349388943394379390943194409389943594319443943694429445943494389444943894329664943994369663943794419665944194338858944294398857944094358859944494469434944594499436944394529435944794439430944894549429944694509428945094449994945194489993944994539992945394458977945494518976945294478978945694599409945794639412945894679411945594719410946094559132946194749135946294779134945994649133946494568989946594628988946694768987946394688990946894578853946994668852947094758851946794728850947294588752947394708751947494788750947194608753947694698923947794658926947894618925947594738924948094821301194819485130109479948913009948394791300394849493130059482949913004948694801261994879503126189488950412617948595121262094909481992994919515993294929516993194899494993094949483875794959492875694969522875594979521875494989523875994939528875895009484103269501953110325950295321032495039505103239499948610322950594871119195069502111909507953611189950895371118895099542111879510954111194951195181119395049513111929513948812665951495111266895159517126679512949012666951794919136951895149142951995109141952095409140952195249139952294969138951694959137952494979525952095269539952795349523952995299498103679530952710366953195331036595289500103649533950195349530953595269536953895329506953895071124995399535112489540952511247954195191125295429509112519537950811250954495468895954595498894954395528893954795439548955495469550955095441000195519548100039549955310002955395459557955495519556955295479555955695589554955795619553955595649552955995559560956695589562956295569569956395609568956195659567956595578882956695638881956495598883956895709563956995739562956795769561957195678806957295788805957095748804957495689580957595729579957395779581957795691006895789575100709576957110069958095829574958195859573957995889575958395798533958495908532958295868531958695809587958495859589958995819592959095879591958895839593959295949589959395989588959196029590959595919596960595979607959495999599959210082960095971008596019606100849598960310083960395938530960496018529960596088528960295958527960796007529608959675496069604753961096128552961196168554960996208553961396097519614962375096159625749961296177489617961010081961896151008096199624100799616962110078962196118634962296198637962396268636962096138635962596189629962696149628962496229627962896309626962996339625962796369624963196279639963296389641963096349640963496287689635963276796339637766963796291005096389635100499636963110048964096429630964196459632963996489631964396399651964496509653964296469652964696401078896479644107909645964910789964996411003096509647100299648964310028965296549642965396579644965196609643965596518642965696628644965496588643965896528690965996568689965796618688966196539685966296599684966096559686966496669438966596699437966396739439966796639987966896779986966696809988967096648677967196838680967296848679966996748678967496658698967596728701967696868700967396878699967896679982967996899981967796819980968196689709968296799708968396909707968096709706968596719661968696929660968496759662968896761001296899691100119687967810010969196821002096929688100199690968510021969496961082996959700108289693970310827969796939727969897069730969997109729969697019728970196941088097029699108799700971410881970496951082197059717108239703970710822970796979683970897059682970997209681970697119680971196989060971297099063971397199062971097159061971597021090997169713109119714971810910971897049960971997169959972097129958971797089961972297241083797239727108369721973110838972597211084897269734108509724973710849972897229696972997399699973097409698972797449697973297231079897339749107979731975010799973597251109597369754110949734975511096973897261087397399761108759737972810874974197291313397429764131329743976713135974097451313497459730865997469743865897479770865797489773865697499751866197449732866097519733800975297487999753977780397549756802975097358019756973697579753975897769759977897609782975597629762973810927976397601092997619784109289765974113127976697831312697649781131289768974212735976997801273497679771127339771974612703977297691270597709774127049774974710767977597721076697769779107659777975710764977397521076897799758111239780977511126978197681112597789766111249783975913172978497651317197829763131709786978893959787979193949785979493969789978587889790979687879788979287869792978686149793979086169791979586159795978798749796979398739794978998759798980013035979998041303497979807130339801979787849802980987839803981087829800981487859805979898289806981798279804981898299808979913028980998211302798079801130299811980210293981298231029298139824102959810981510294981598038617981698138620981798198619981498058618981998061290898209816129079818982612906982298081298398239825129829821981112984982598121291198269822129109824982012909982898309805982998339804982798369806983198278625983298388624983098348626983498289869983598329868983398379867983798299841983898359840983698319839984098429838984198469837983998499836984398398612984498518611984598528610984298568613984798409882984898599884984698609883985098411290198519864129009849984312902985398441056998549866105689855986210567985298571056698579845939798589855940098599861939998569847939898619848989198629858989498639854989398609865989298659850128789866986312877986498531287698689870983598699873983498679876983398719867987998729878988198709874988098749868979598759872979498739877979698779869130399878987513041987698711304098809882987098819885987298799888987198839879984698849890984898829886984798869880941698879884941898859889941798899881995098909887994998889883994898929895986098939898986398949901986298919904986198969891991198979906991398959899991298999892126599900989712661989899021266099029893128649903990012866990199051286599059894126919906990312693990498961269299089911993699099914993599109917993499079920993399129907989599139922989799119915989699159908126889916991312690991499181268999189909126729919991612674991799211267399219910126629922991912664992099121266399249926130139925992913012992399331301499279923130249928993713026992699401302599309924948999319943949299329944949199299934949099349925991099359932990999369947990899339948990799389927130369939995013038993799411303799419928877799429939877699439945877599409930877899459931940599469942940899479949940799449935940699499936989099509946988999489938988899529954908199539958908099519962908299559951109609956996510963995799681096299549959109619959995297199960995797189961997097179958996397209963995399719964996199739962996699729966995511102996799641110199659969111009969995611050997099671104999689960110519972997499629973997799649971998099639975997189099976998289089974997889079978997299979979997699969977998199959981997396799982997996789980997596779984998689169985998989159983999289149987998396679988999496669986999096689990998490669991998890659989999390649993998594519994999194509992998794499996999899799997100019978999510004997799999995100071000010006100099998100021000810002999695491000310000955110001100059550100059997111081000610003111071000499991110610008100109998100091001310000100071001699991001110007968910012100189688100101001496871001410008100611001510012100601001310017100591001710009100331001810015100321001610011100311002010022969110021100259690100191002896921002310019100341002410030100361002210026100351002610020108201002710024108191002510029108181002910021965010030100279649100281002396481003210034100181003310037100171003110041100161003510031100221003610044100241003410048100231003810032100741003910050100771004010051100761003710055100751004210033110991004310058110981004110045110971004510035110421004610043110411004710057110401004410053110391004910036963810050100529637100481003896361005210039744100531004974710054100477461005110056745100561004010057100541005810046100551004210060100621001510061100651001410059100681001310063100591007110064100701007310062100661007210066100608712100671006487111006510069871010069100619576100701006795781006810063957710072100741006210073100781006410071100821006310075100711003710076100851004010077100871003910074100791003810079100729619100801007796181008110086961710078100839616100831007395981008410081960110085100889600100821007595991008710080742100881007674110086100847431009010093860100911009785910092101028581008910106861100941008910095101091009610110100931009810098100908071009910096806101001011480510101101138041009710103808101031009110130101041010110129101051011210128101021010710131101071009210108101051010910111101061009410111100951073610112101081073510113101041073910114101001073810110100991073710116101211051110117101271051010118101281050910119101321050810120101371050710115101221051210122101156961012310120695101241014069410125101417001012610145699101271012969810121101166971012910117101041013010126101031013110148101021012810133101051013310118101341013110135101471013610143101321013810138101191013910136101401014210137101231014210124844810143101398447101441013584461014110146844910146101258481014710144847101481013484610145101308451015010152101771015110157101761014910162101751015310149102071015410165102111015510166102101015610169102091015210158102081015810150101591015610160101711016110172101571016310163101516701016410161669101651016767210162101536711016710154106531016810164106551016610174106541017010155102341017110173102331016910159102321017310160105951017410170105941017210168105961017610178101511017710181101501017510184101491017910175665101801018666410178101826631018210176101831018010181101851018510177101921018610183101911018410179101901018810190667101891019366610187101966681019110187101861019210198101851019010194101841019410188102011019510192102001019310197101991019710189845310198101958455101961019184541020010202101951020110207101941019910212101931020310199848510204102158489102051021684881020610220848710202102088486102081020010152102091020610156102101022210155102111021810154102071021310153102131020168510214102116841021510217687102121020368610217102041070310218102141070210219102101070110216102211070010221102051023510222102191023710220102091023610224102261024710225102291024610223102321024510227102231026510228102351026410226102381026610230102241042510231102401042410229102331042310233102251017110234102311017010232102361016910236102271022010237102341022210235102391022110239102281041410240102371041310238102301041510242102451024310248102441025110241102541024610241102251024710256102241024510249102231024910242102611025010247102631024810252102621025210243102861025310250102881025110255102871025510244104261025610253104281025410246104271025810261850510259102648508102601026785071025710270850610262102571024810263102721025010261102651024910265102581022710266102631022610264102681022810268102591041010269102661041210267102711041110271102601027710272102691027910270102621027810274102771033210275102801033510276102831033410273102861033310278102731027010279102881027210277102811027110281102741040710282102791040910280102841040810284102751042910285102821043110283102871043010287102761025110288102851025310286102781025210290102921297710291102961297610289103001297810293102899811102941030398101029510309981310292103139812102971029012941102981031512940102991031612939102961032212942103011029113000103021032613002103001030413001103041029310353103051030210352103061032510351103071032710350103081033210349103031031010354103101029410380103111030810379103121033510378103091033610377103141029512918103151033912920103131029712919103171029810524103181034110523103191034210522103201034510521103211032910520103161032310525103231029995031032410321950210325103289501103261030595001032210301949910328103061032910324103301032010331103481032710333103331030710273103341033110276103351034710275103321031110274103371031210480103381034310479103361034010481103401031410711103411033810710103391031710712103431031810463103441033710462103421034610461103461031910452103471034410451103481033410450103451033010449103501035510307103511036010306103521036410305103531036810304103541037210303103491035610308103561034985031035710354850210358103718501103591037385001035510361850410361103501036210359103631037610360103651036510351953110366103639530103671037595291036410369952810369103528762103701036787611037110374876010372103578764103681035387631037410358103751037010376103661037310362103781038110312103791038510311103801038910310103771039310309103821037710486103831039610489103841039710488103811038610487103861037810403103871038410406103881039910405103851039010404103901037985161039110388851510392104008514103891039485131039410380860510395103928604103961040286031039310382860610398103831069010399104011068910397103871069110401103911068710402103981068610400103951068810404104071038510405104101038810406104131038710403104161038610408104031028010409104181028210407104111028110411104041026710412104091026910410104141026810414104051023910415104121023810413104171024010417104061043210418104151043410416104081043310420104231044510421104261044810422104291044710419104321044610424104191023110425104341023010423104271022910427104201025410428104251025610426104301025510430104211028310431104281028510429104331028410433104221041610434104311041810432104241041710436104381058610437104421058510435104451058710439104351044010448104411044910438104531044310436105771044410456105761044210457105781044610437104191044710460104221044810450104211044510439104201045010440103481045110447103471045210459103461044910454103451045410441105161045510452105191045610458105181045310443105171045810444104661045910455104651046010451104641045710446104671046210464103441046310468103431046110472103421046510461104591046610475104581046710477104571046410469104601046910462104821047010467104851047110476104841046810473104831047310463105541047410471105531047510478105521047210465105511047710470106171047810466106161047610474106181048010482103371048110486103361047910490103381048310479104681048410493104711048510495104701048210487104691048710480103811048810485103841048910494103831048610491103821049110481858210492104898581104931049685801049010483858310495104881062610496104841062810494104921062710498105031049910507105001051310501105161050210520104971052610504104971050510531105061053210503105081050810498101191050910506101181051010537101171051110538101161051210544101151050710514101201051410499106671051510512106661051310548106651051710500104531051810550104561051910551104551051610521104541052110501103201052210519103191052310554103181052410555103171052510558103161052010527103211052710502112251052810525112241052910561112291053010562112281053110533112271052610504112261053310505107401053410530107451053510565107441053610566107431053710539107421053210509107411053910510858910540105368588105411056985871054210556858610543105538585105381054585841054510511106221054610543106211054710552106201054410549106191054910515105751055010547105741054810517105731055210518104751055310546104741055410542104731055110522104721055610523107141055710541107131055510570107151055910524126041056010572126031056110563126021055810528126011056310529128601056410560128591056510567128581056210534128571056710535985510568105649854105691057198531056610540985210571105571287410572105681287310570105591287510574105761055010575105791054910573105821054810577105731044310578105841044210576105801044410580105741061110581105781061010579105831060910583105751060210584105811060110582105771060010586105881043610587105911043510585105941043710589105851059710590105961059910588105921059810592105861059310590105911059510595105871017310596105931017210594105891017410598106001058810599106031059010597106061058910601105971058410602106081058310600106041058210604105981066110605106021066010603106071065910607105991065210608106051065110606106011065010610106121058110611106161058010609106191057910613106091063210614106221063510615106231063410612106261063310617106101047710618106281047610616106201047810620106111054710621106181054610622106241054510619106131054410624106148568106251062185701062310627856910627106151049410628106251049610626106171049510630106321064710631106361064910629106401064810633106291061210634106431061510635106451061410632106371061310637106307181063810635721106391064472010636106417191064110631106991064210639106981064310646106971064010633106961064510638856610646106348565106441064285671064810650106291064910653106311064710656106301065110647106081065210658106071065010654106061065410648101661065510652101681065310657101671065710649689106581065568810656106516901066010662106051066110665106041065910668106031066310659692106641067069110662106666931066610660105151066710664105141066510669105131066910661106701066710668106631067210674738106731067874010671106827391067510671851210676106858511106771068785101067410679850910679106721069410680106771069310681106861069210678106831069510683106738577106841068185761068510688857910682106758578106871068010401106881067610400106861068410402106901069210398106911069610397106891070010399106931068910680106941070310679106951070510678106921069710681106971069010643106981069510642106991070410641106961070110640107011069110219107021069910218107031070610217107001069310216107051069871710706106947161070410702715107081071086071070910713860910707107168608107111070710340107121071810339107101071410341107141070810556107151071210555107131071710557107171070912892107181071512891107161071112893107201072310721107291072210735107191074010724107191113710725107451114210726107461114110727107521114010728107561113910723107301113810730107201073110728107321075910733107601073410764107291073610736107211011110737107341011010738107681011410739107691011310735107411011210741107221053210742107391053710743107721053610744107481053510745107471053410740107241053310747107259375107481074493741074910743937310750107719372107511077393711074610753937610753107261277710754107511278010755107761277910752107571277810757107271304510758107551304810759107611304710756107311304610761107321112710762107581113010763107781112910760107651112810765107339776107661076397751076710774977410768107709773107641073797771077010738864710771107678646107721074986451076910742864810774107501270010775107661270210773107771270110777107541271010778107751270910776107621271110780107827981078110785797107791078879610783107798683107841079086821078210786868110786107801079310787107841079210785107891079110789107819645107901078796471078810783964610792107941078710793107971078610791108001078510795107911080310796108021080510794107981080410798107929732107991079697311079710801973310801107938181080210799817108001079581610804108061079410805108091079610803108121079510807108031081510808108141081710806108101081610810108041083110811108081083010809108131083210813108051086510814108111086410812108071086610816108181080610817108211080810815108241080710819108151002710820108261002610818108221002510822108169703108231082097051082110825970410825108171105410826108231105310824108191105210828108309695108291083396941082710836969310831108271081010832108381080910830108341081110834108281084010835108321083910833108371084110837108299722108381083597211083610831972310840108421083410841108451083310839108481083510843108391086110844108511086310842108551086210846108401087810847108581087710845108491087610849108419724108501084797261084810852972510852108431108510853108501108410854108601108310851108561108210856108441106610857108541106510855108591106410859108461088510860108571088710858108531088610862108641084210863108671084410861108701084310865108611081310866108721081210864108681081410868108621104510869108661104410867108711104310871108637941087210869793108701086579510874108769737108751087997391087310882973810877108731084710878108841084610876108801084510880108749701108811087897001087910883970210883108751090210884108811090110882108771090010886108881085810887108911086010885108941085910889108851089710890108961089910888108921089810892108861089310890108911089510895108871093810896108931093710894108891093610898109001088810899109031089010897109061088910901108971088410902109081088310900109041088210904108981092310905109021092210903109071092110907108991091410908109051091310906109011091210910109129714109111091597161090910918971510913109091090810914109201090710912109161090610916109101093410917109141093310915109191093510919109119079109201091790781091810913907710922109241090510923109271090410921109301090310925109219055109261093290541092410928905610928109229761109291092697631092710931976210931109231093210929109301092510934109361091610935109391091510933109431091710937109331089610938109461089510936109501089410940109341095910941109521095810942109481095710939109441095610944109359076109451094290751094310947907410947109371097510948109451097410949109411097710946109511097610951109381105710952109491105610950109401105510954109569073109551096090721095310964907110957109531094210958109671094110959109691094010956109611093910961109549954109621095999571096310968995610960109659955109651095510966109631096710970109641095710969109621104710970109581104610968109661104810972109749053109731097890521097110982905110975109711094710976109851094610977109871094910974109791094810979109721098010977109811098610978109831098310973109841098110985109881098210975109871098010989109881097610991109861098410990109901099210986109911099510988109891099810987109931098910994110001099210996109961099010997109941099510999109991099111003110001099711002109981099311001110021100411000110031100710999110011101010998110051100111013110061101211015110041100811014110081100211069110091100611068110071101111067110111100311061110121100911063110101100511062110141101611004110151101911006110131102211005110171101311018110241101611020110201101479111021110187901101911023792110231101511026110241102111025110221101711027110261102811023110271103211022110251103511024110291102576411030110387631103111039762110281104376511033110261106011034110451105911032110461105811036110271103711048110381104011035110291104011030100471104111037100461104211049100451103911052100441104411031108691104511054108681104311033108671104711034109691104811050109681104611036109701105011041996911051110479968110491105399701105311042108261105411051108251105211044108241105611058109521105711061109511105511064109501105911055110341106011066110331105811062110321106211056110101106311060110121106111065110111106511057108571106611063108561106411059108551106811070110091106911073110081106711076110071107111067110791107211078110811107011074110801107411068815110751107281411073110778131107711069110781107511076110711108011082110701108111086110721107911090110711108311079108541108411093108531108511095108521108211087108511108711080812110881108581111089110948101108611091809110911108111092110891109311096110901108311095110889735110961108497341109411092973611098111001004311099111031004211097111061004111101110979967111021110899661110011104996511104110981110511102111031110711107110991000611108111051000511106111011000411110111121309711111111161309611109111201309811113111091111411123111151112711112111171111711110127961111811115127951111911130127941111611131127931112111111131201112211134131221112011124131211112411113977811125111229781111261113697801112311128977911128111141076011129111261076311130111321076211127111181076111132111191271911133111291271811131111351272011135111211274111136111331274011134111251273911138111431072311139111471072811140111511072711141111561072611142111551072511137111571072411144111371114511162111461116311143111481114811138111491114611150111681114711152111521113991471115311150914611154111679145111551115891441115611141914311151111409148111581114211197111591115411196111601116611195111611116511200111621116411199111571114411198111641114511359111651116111358111661116011357111671115911362111681115311361111631114911360111701117312072111711117912071111721118312074111691118712073111741116911852111751119411851111761119511856111771120111855111781120511854111731118011853111801117012046111811117812045111821120812048111791121412047111841117111995111851121711994111861121811993111831118811996111881117295081118911186950711190112239506111911122495051119211229950411193112289511111941119695101118711174950911196111751115911197111931115811198112271115711199112301116211200112361116111195112021116011202111761163311203112001163211204112391163111201112061163011206111771161911207112041161811205112401161711209111811152311210112421152211211112431152111212112331152011213112201151911208112151151811215111821203411216112131203711217112191203611214111841203511219111851122011216112211121211222112321122311225112181118911225111901052711226112221052611227112311053111228111971053011229111921052911224111911052811231111981123211226112331122111234112111123511246112301123711237111991145711238112351146011239112451145911236112031145811241112071156511242112441156411240112091156311244112101149811245112411149711246112381149611243112341149511248112539539112491125795381125011264953711251112689542112521127295411124711277954011254112471125511281112561128211253112581125811248112591125611260112871126111288112621129111263112941125711265112651124912009112661126312012112671129712011112641126912010112691125011904112701126711903112711130011902112681127311901112731125111829112741127111828112751130311827112761130411826112721127811830112781125211325112791127611329112801130811328112811128311327112771125411326112831125511284112801128511307112861130911287112891128211259112891126012427112901128612426112881131312425112921126112184112931131612183112911129512185112951126212196112961129312195112941129812197112981126612597112991129612596112971130112595113011127011929113021129911928113031131911927113001127411930113051127511422113061132111421113071131011420113081128411424113041127911423113101128512365113111130612364113121132212363113091131412366113141129012397113151131212396113131131712395113171129212385113181131512384113161132412383113201130212324113211132312323113191130512322113231131112341113241132012340113221131812342113261133011277113271133411281113281133811280113291134211279113251134611278113311132591511133211345915011333113479149113301133591521133511326113361133311337113501133411339113391132711340113371134111349113381134311343113281138911344113411138811345113481138711346113311138611342113291139011348113321134911344113501134011347113361135211354116391135311357116381135111363116401135511351116571135611368116561135411372116581135811352111651135911375111641136011376111631136111382111681136211386111671135711364111661136411353118341136511362118331136611390118321136711391118311136311369118351136911355117011137011367117001137111395116991136811400117021137311356114561137411403114551137511377114541137211358114531137711359113781137411379114021138011398113811140411376113831138311360113841138111385114081138211387113871136111345113881138511344113891140711343113901139211342113861136511346113921136611450113931138911449113941140611452113911139611451113961137011747113971139411751113981140511750113991137911749113951140111748114011137111718114021139911721114031137811720114001137311719114051138011406113971140711393114081138811404113841141011413123601141111417123591141211420123621140911425123611141411409124971141511429124961141611430124951141311436124981141811410124991141911439125011141711440125001142111411113061142211442113051142311443113041142411449113081142011426113071142611412114271142411428114521142911431114251141411431114151173611432114281173511433114511173411434114471173311435114461173811430114371173711437114161226711438114351226611439114451226511436114181226811441114191231411442114441231311440114211231511444114221181211445114411181111446114381181011447114341180911448114331181411443114501181311450114231139211451114481139111452114321139411449114271139311454114571137511455114611137411456114651137311453114691137211458114531123611459114721123911460114751123811457114621123711462114541146311460114641147411461114661146611455117171146711464117161146811473117151146511470117141147011456116541147111468116531147211476116521146911458116551147411467114921147511463114911147611459114941147311471114931147811480125601147911484125591147711488125611148111477114821149111483114951148011485114851147811545114861148311544114871149811543114841149911546114891147911803114901150211805114881149211804114921148111474114931149011473114941150411476114911149611475114961148211246114971149411245114981150011244114951148611243115001148711570115011149711569114991150311571115031148911600115041150111599115021149311601115061150912026115071151312025115081151812024115051152412023115101150512090115111152812093115121153212092115091151412091115141150611515115121151611537115171153811513115191151911507112131152011517112121152111542112111152211543112101152311547112091151811525112081152511508120621152611523120611152711550120641152411529120631152911510122911153011527122901153111553122891152811533122881153311511125161153411531125151153511556125201153611557125191153711539125181153211515125171153911516115401153611541115601154211544115381152011544115211148611545115411148511546115621148411543115481148711548115221156611549115461156811547115511156711551115261157611552115491157511550115541157711554115301187811555115521188111556115581188011553115341187911558115351257011559115551256911557115611256811561115401255311562115591255511560115451255411564115661124211565115691124111563115721124011567115631154711568115741154911566115701154811570115641150011571115681149911569115731150111573115651159211574115711159111572115671159011576115781155111577115811155011575115841155211579115751158711580115861158911578115821158811582115761186311583115801186211581115851186111585115771167311586115831167511584115791167411588115901157811589115931158011587115961157911591115871157411592115981157311590115941157211594115881161311595115921161211593115971161111597115891160411598115951160311596115911160211600116021150311601116051150211599116081150411603115991159811604116101159711602116061159611606116001167011607116041167211605116091167111609116011164311610116071164211608116031164111612116141159511613116171159411611116201159311615116111162311616116221162511614116181162411618116121120711619116161120611617116211120511621116131186511622116191186411620116151186611624116261161411625116301161611623116341161511627116231164411628116371164711629116391164611626116311164511631116241120411632116291120311633116381120211630116351120111635116251185911636116331185811637116401185711634116271186011639116321135211640116281135111638116361135311642116441161011643116481160911641116521160811645116411162611646116551162911647116571162811644116491162711649116421168311650116471168611651116561168511648116531168411653116431147111654116511147011655116581146911652116451147211657116501135511658116461135411656116541135611660116621180611661116661180811659116701180711663116591187211664116731187111665116761187011662116671187311667116601168211668116651168111669116781168011666116711167911671116611160511672116691160711670116741160611674116631158411675116721158611673116771158511677116641184011678116751184211676116681184111680116831166911681116871166811682116911166711679116951166611684116791164811685116981165111686117011165011683116881164911688116801183911689116861183811690117001183711687116921183611692116811173011693116901172911694116991173211691116961173111696116821170411697116941170311698117021170611695116841170511700116931137011701116891136911702116851136811699116971137111704117071169611705117111169511706117141169811703117181169711708117031174311709117211174611710117221174511707117261174411712117041180111713117281180011711117151180211715117051146811716117131146711717117241146611714117191146511719117061140011720117171140311721117231140211718117081140111723117091172411720117251171611722117271172711710117821172811725117841172611712117831173011733116921173111739116911173211743116941172911747116931173411729114331173511751114321173611752114311173711756114301173811761114351173311740114341174011730118751174111738118741174211760118771173911762118761174411731117071174511765117101174611768117091174311748117081174811732113951174911746113991175011772113981175111753113971174711734113961175311735117541175011755117711175211757117571173612526117581175512525117591177012524117601176312523117611174112522117561173712521117631174212573117641175912572117621176612571117661174411775117671176411774117651176911773117691174511770117671177111758117721175411768117491177411776117671177511779117661177311782117651177711773117781178411776117801178011774117871178111778117861177911783117851178311775117261178411781117281178211777117271178611788117811178711791117801178511794117791178911785117971179011796117991178811792117981179211786125641179311790125631179111795125621179511787125661179611793125651179411789125671179811800117881179911803117901179711806117891180111797117121180211808117111180011804117131180411798114881180511802114901180311807114891180711799116591180811805116611180611801116601181011815114461181111818114451181211822114441181311826114431181411831114481180911836114471181611809118681181711840118671181511819118691181911810123041182011817123031182111843123021181811823123051182311811119201182411821119231182511847119221182211827119211182711812112751182811825112741182911850112731183011851112721182611832112761183211813113661183311830113651183411856113641183511857113631183111837113671183711814116901183811835116891183911860116881183611841116871184111816116761184211839116781184011861116771184411820120511184511863120501184611853120491184311848120521184811824118881184911846118871185011852118861184711828118851185211829111741185311849111731185411845111781185511864111771185611858111761185111833111751185811834116361185911855116351186011866116341185711838116371186211842115831186311865115821186111844115811186511854116211186611862116201186411859116221186811870118161186911874118151186711878118171187111867116641187211881116631187311883116621187011875116651187511868117401187611873117391187711882117421187411879117411187911869115531188011877115561188111884115551187811871115541188311876125751188411872125741188211880125761188611889118501188711892118491188811895118481188511898118471189011885119051189111900119071188911893119061189311886120781189411891120801189211896120791189611887119841189711894119861189511899119851189911888119521190011897119541189811890119531190211905112711190311908112701190411911112691190111914112681190611901118891190711916118911190511909118901190911902119491191011907119511190811912119501191211903119651191311910119671191111915119661191511904120811191611913120831191411906120821191811920123161191911924123181191711927123171192111917118221192211930118251192311931118241192011935118231192511918125811192611938125801192411939125821192811919113021192911942113011193011932113001192711921113031193211922119461193311929119451193411944119481193111936119471193611923123071193711934123061193811940123091193511925123081194011926122351194111937122341193911943122361194311928125901194411941125891194211933125911194611949119321194711952119311194811955119341194511958119331195011945119081195111960119101194911953119091195311946118981195411951119001195211956118991195611947119811195711954119831195511959119821195911948119681196011957119701195811950119691196211965120081196311968120071196411971120061196111974120051196611961119111196711976119131196511969119121196911962119581197011967119601196811972119591197211963119901197311970119921197111975119911197511964120841197611973120861197411966120851197811981120551197911984120541198011987120531197711990120561198211977119551198311992119571198111985119561198511978118951198611983118971198411988118961198811979120751198911986120771198711991120761199111980119711199211989119731199011982119721199411997111851199512001111841199612005111831199312009111861199811993119991201212000120131199712002120021199412033120031200012032120041201512031120011200612030120061199511964120071200411963120081201611962120051201011961120101199611264120111200811267120121201811266120091199811265120141199912220120151201712219120131200312221120171200712598120181201412600120161201112599120201202312060120211202712059120221203012058120191203412057120241201911508120251203711507120261203811506120231204211505120281202012105120291204412107120271203112106120311202112004120321202912003120331204012002120301203512001120351202211214120361203311217120371203911216120341202411215120391202512040120361204112032120381204312043120261208712044120411208912042120281208812046120491118012047120531117912048120571118212045120611118112050120451184512051120641184412052120651184312049120541184612054120461197912055120521197812056120671197712053120581198012058120471202212059120561202112060120681202012057120621201912062120481152512063120601152412064120701152712061120501152612066120511229612067120691229512065120551229712069120591229312070120661229212068120631229412072120751117012073120781116912074120811117212071120841117112076120711198712077120861198912075120791198812079120721189212080120771189412078120821189312082120731191412083120801191612081120851191512085120741197412086120831197612084120761197512088120901204212089120941204412087120981204312091120871150912092121011151212093121031151112090120951151012095120881211512096120931211812097121021211712094120991211612099120891210012097121011210412098120911210312096121381210412092121371210212100121391210612108120271210712112120291210512115120281210912105122821211012118122811211112119122801210812122122831211312106122231211412124122221211212116122241211612107120941211712114120971211812120120961211512109120951212012110121501212112117121521211912123121511212312111122271212412121122261212212113122251212612129125321212712133125311212812137125341212512140125331213012125124581213112143124571213212144124601212912134124591213412126122601213512132122591213612147122581213312150122611213812127121031213912152121021213712141121041214112128121421213912143121451214012130121451213112154121461214212153121441214812155121481213512245121491214612244121471215112243121511213612119121521214912121121501213812120121541215612145121551215912144121531216212146121571215312158121641215612160121601215412445121611215812444121591216312443121631215512167121641216112166121621215712165121661216812164121671217112163121651217412162121691216512177121701217612179121681217212178121721216612388121731217012387121711217512386121751216712242121761217312241121741216912240121781218012168121791218312170121771218612169121811217712182121881218012184121841217811292121851218211291121831218711293121871217912191121881218512190121861218112189121901219212188121911219512187121891219812186121931218912194122001219212196121961219011295121971219411294121951219911296121991219112203122001219712202121981219312201122021220412200122031220712199122011221012198122051220112213122061221212215122041220812214122081220212594122091220612593122071221112592122111220312230122121220912229122101220512228122141221612204122151221912206122131222212205122171221312218122241221612220122201221412014122211221812013122191222312015122231221512113122241222112112122221221712114122261222812124122271223112123122251223412122122291222512212122301223612211122281223212210122321222612238122331223012237122311223512239122351222711940122361223311939122341222911941122381224012232122391224312231122371224612233122411223712176122421224812175122401224412174122441223812149122451224212148122431224712147122471223912584122481224512583122461224112585122501225212577122511225512579122491225812578122531224912312122541226212311122521226512310122561225012509122571226812508122551226912510122591225112135122601227212134122611227312133122581226312136122631225312278122641226112277122621227612279122661225411438122671227511437122681227011436122651225611439122701225712494122711226712493122721227412492122691225912491122741226012514122751227112513122761226612512122731226412511122781228012263122791228412262122771228812264122811227712110122821229112109122831229312108122801228512111122851227812300122861228312299122871229212298122841228912301122891227911531122901228711530122911229411529122881228111528122931228612069122941228212068122921229012070122961229812066122971230212065122951230612067122991229512286123001230912285123011231112284122981230312287123031229611820123041230111819123051231011818123021230711821123071229711936123081230511935123091231211938123061229911937123111230412254123121230012253123101230812252123141231611441123151231911440123131232211442123171231311917123181232411919123161232011918123201231412327123211231812326123191232312325123231231511321123241232111320123221231711319123261232812321123271233112320123251233412319123291232512337123301233612339123281233212338123321232612588123331233012587123311233512586123351232712505123361233312507123341232912506123381234012328123391234312330123371234612329123411233711323123421234811322123401234411324123441233812379123451234212378123431234712377123471233912352123481234512354123461234112353123501235212504123511235512503123491235912502123531234912346123541236312348123521236712347123561235012480123571237012479123581237312482123551236012481123601235111410123611235811409123621237611412123591236411411123641235311311123651236211310123661237511309123631236811312123681235412392123691236612394123671237112393123711235612402123721236912401123701237412403123741235712375123721237612365123731236112378123801234512379123831234412377123861234312381123771238912382123881239112380123841239012384123781131812385123821131712383123871131612387123791217312388123851217212386123811217112390123921238012391123951238212389123981238112393123891236712394124001236912392123961236812396123901131512397123941131412395123991131312399123911241812400123971241712398123931241612402124041237112403124071237012401124101237212405124011241312406124121241512404124081241412408124021247312409124061247212407124111247412411124031241212409124101240512414124161240412415124191240612413124221240512417124131240012418124241239912416124201239812420124141243912421124181243812419124231243712423124151243012424124211242912422124171242812426124281129012427124311128912425124341128812429124251242412430124361242312428124321242212432124261243312430124311243512435124271243612433124341242912438124401242112439124431242012437124461241912441124371244212448124401244412444124381216112445124421216012443124471215912447124391246312448124451246212446124411246112450124531245112457124521246112449124641245412449125511245512467125501245612468125491245312458125521245812450121301245912456121291246012471121321245712462121311246212451124481246312460124471246112472124461246512452124661247412467124691246412454124691245512477124701246612476124711247312475124681245912478124731246312408124741247012407124721246512409124761247912470124771248312469124781248712468124751249112471124801247512356124811249412355124821249712358124791248412357124841247612485124821248612496124831248812488124771253012489124861252912490124951252812487124921252712492124781227212493124901227112494124981227012491124801226912496124891141512497124851141412498124811141312495124931141612500125021141712501125051141912499125081141812503124991235112504125101235012502125061234912506125001233412507125041233612505125091233512509125011225612510125071225512508125031225712512125151227612513125211227512514125271227412511125311227312516125111153312517125341153212518125351153712519125401153612520125231153512515125221153412522125121176112523125201176012524125191175912525125431175812526125441175712521125281175612528125131249012529125261248912530125481248812527125491248712532125141212612533125521212512534125361212812531125161212712536125171253712533125381255112539125461253512541125411251812542125391254312545125401252412545125251254612542125471253812548125501254412529125501253012455125511254712454125521253712453125491253212456125541255611560125551255911562125531256211561125571255312558125641255612560125601255411478125611255811477125591256311479125631255511793125641256111792125621255711791125661256811795125671257111794125651257411796125691256511559125701257611558125681257211557125721256611764125731257011763125711257511762125751256711883125761257311882125741256911884125781258012249125791258312251125771258612250125811257711925125821258811924125801258411926125841257812247125851258212246125831258712248125871257912333125881258512332125861258112331125901259211943125911259511942125891259811944125931258912209125941260012208125921259612207125961259011299125971259411298125951259911297125991259112016126001259712018125981259312017126021260510561126031260810560126041261110559126011261410558126061260112621126071261612623126051260912622126091260212646126101260712648126081261212647126121260312933126131261012935126111261512934126151260412943126161261312945126141260612944126181262194871261912624948612620126279485126171263094881262212617126051262312632126071262112625126061262512618129521262612623129541262412628129531262812619129561262912626129551262712631129571263112620126371263212629126391263012622126381263412637126491263512640126521263612643126511263312646126501263812633126301263912648126321263712641126311264112634129651264212639129641264012644129661264412635129361264512642129381264312647129371264712636126081264812645126101264612638126091265012653126331265112656126361265212659126351264912662126341265412649126691265512664126711265312657126701265712650128671265812655128691265612660128681266012651989812661126589900126591266398991266312652992012664126619922126621265499211266612669951212667126729515126681267595141266512678951312670126651265312671126801265512669126731265412673126669917126741267199191267212676991812676126671268512677126741268712675126791268612679126681287012680126771287212678126701287112682126859404126831268894031268412691940212681126949401126861268112675126871269612677126851268912676126891268299141269012687991612688126929915126921268399041269312690990612691126959905126951268412861126961269312863126941268612862126981270093521269912703935112697127069350127011269710773127021270810775127001270410774127041269897701270512702977212703127079771127071269912726127081270512725127061270112724127101271210777127111271510776127091271810778127131270912721127141272012723127121271612722127161271092931271712714929212715127199291127191271111132127201271711131127181271311133127221272412712127231272712714127211273012713127251272112708127261273212707127241272812706127281272293031272912726930512727127319304127311272312738127321272912737127301272512736127341273697691273512739976812733127429767127371273312732127381274412731127361274012730127401273411136127411273811135127391274311134127431273513137127441274113136127421273713138127461274993531274712752935612748127559355127451275893541275012745928712751127609286127491275392851275312746927612754127519278127521275692771275612747127741275712754127761275512759127751275912748127901276012757127921275812750127911276212765910412763127689107127641277191061276112774910512766127619273127671277692751276512769927412769127621283512770127671283712768127721283612772127631278112773127701278312771127751278212775127641275512776127731275712774127661275612778127811075212779127841075512780127871075412777127901075312782127771277112783127921277312781127851277212785127781283212786127831283412784127881283312788127799295127891278692941278712791929612791127801275812792127891276012790127821275912794127971111912795128001111812796128031111712793128061111612798127931281312799128081281512797128011281412801127941305512802127991305712800128041305612804127951307412805128021307612803128071307512807127961308712808128051308912806127981308812810128131282512811128161282812812128191282712809128221282612814128091279712815128241279912813128171279812817128101308412818128151308612816128201308512820128111284512821128181284712819128231284612823128121305812824128211306012822128141305912826128291280912827128321281212828128351281112825128381281012830128259283128311284092821282912833928412833128261278412834128311278612832128361278512836128271276812837128341277012835128391276912839128289270128401283792721283812830927112842128459109128431284891081284412851911112841128549110128461284112819128471285612821128451284912820128491284213081128501284713083128481285213082128521284313068128531285013070128511285513069128551284413049128561285313051128541284613050128581286110565128591286410564128601286710563128571287010562128621285712694128631287212696128611286512695128651285899011286612863990312864128689902128681285912656128691286612658128671287112657128711286012678128721286912680128701286212679128741287610571128751287910570128731288210572128771287398661287812884986512876128809864128801287412886128811287812885128791288312887128831287512925128841288112924128821287712926128861288812880128871289112879128851289412881128891288512897128901289612899128881289212898128921288610717128931289010716128911289510718128951288712914128961289312913128941288912912128981290012888128991290312890128971290612889129011289798501290212908984912900129049851129041289886211290512902862312903129078622129071289998201290812905981912906129019818129101291298261291112915982512909129189824129131290912896129141292012895129121291612894129161291012922129171291412921129151291912923129191291110313129201291710315129181291310314129221292412916129231292712915129211293012917129251292112883129261293312882129241293612884129281292212969129291293812968129271293112967129311292312946129321292912948129301293412947129341292512611129351293212613129331293712612129371292612643129381293512645129361292812644129401294310298129411294610297129421294910296129391295210299129441293912614129451295412616129431294712615129471294012930129481294512932129461295012931129501294112960129511294812959129491295312958129531294212624129541295112626129521294412625129561295812628129571296112627129551296412629129591295512951129601296712950129581297012949129621295613015129631297213017129611296513016129651295712641129661296312640129641296812642129681295912929129691296612928129671297112927129711296012973129721296912975129701296212974129741297612970129751297912972129731298212971129771297310290129781298410289129761298010291129801297412986129811297812985129791298312987129831297598221298412981982112982129779823129861298812980129871299112979129851299412981129891298512997129901299612999129881299212998129921298613019129931299013018129911299513020129951298713022129961299313021129941298913023129981300012988129991300312990129971300612989130011299710300130021300810302130001300410301130041299894821300513002948413003130079483130071299987801300813005877913006130018781130101301294811301113015948013009130189479130131300999241301413020992313012130169925130161301012961130171301412963130151301912962130191301112992130201301712991130181301312993130221302412995130231302712994130211303012996130251302199261302613032992813024130289927130281302298081302913026980713027130319809130311302387941303213029879313030130258792130341303697991303513039979813033130429797130371303399371303813044993913036130409938130401303498761304113038987813039130439877130431303587911304413041879013042130378789130461304910756130471305210759130481305510758130451305810757130501304512854130511306012856130491305312855130531304613065130541305113067130521305613066130561304712800130571305412802130551305912801130591304812822130601305712824130581305012823130621306513063130681306413071130611307413066130611305213067130761305413065130691305313069130621285113070130671285313068130721285213072130631309013073130701309213071130751309113075130641280313076130731280513074130661280413078130819214130791308492131308013087921213077130909211130821307712848130831309212850130811308512849130851307812816130861308312818130841308812817130881307912806130891308612808130871309112807130911308013071130921308913073130901308213072130941309692091309513099920813093131029210130971309311110130981310411109130961310011111131001309413106131011309813105130991310313107131031309513104131011310213097131061310813100131071311113099131051311413101131091310513117131101311613119131081311213118131121310613156131131311013155131111311513157131151310713168131161311313167131141310913169131181312013108131191312313110131171312613109131211311711120131221312811122131201312411121131241311813131131251312213130131231312713129131271311997651312813125976413126131219766131301313213125131311313613124131291313913123131331312997411313413142974013135131459743131321313797421313713130127431313813135127421313613148127441314013131131501314113147131491313913143131511314313133903713144131419036131421314690351314613134931913147131449318131481314093171314513138931613150131521314013151131551313913149131581314113153131499194131541316091931315213156919513156131501311213157131541311113155131591311313159131519034131601315790331315813153903213162131649057131631316790591316113170905813165131611316613172131641316813168131621311513169131661311413167131711311613171131639784131721316997831317013165978213174131771317513180131761318313173131861317813173137513179131881377131771318113761318113174131931318213179131951318013184131941318413175132181318513182132201318313187132191318713176134313188131851345131861317813441319013193347131911319634613192131993451318913202344131941318913180131951320413182131931319713181131971319013721319813195137413196132001373132001319113591320113198136113199132031360132031319213209132041320113211132021319413210132061320913224132071321213227132081321513226132051321813225132101320513202132111322013204132091321313203132131320613561321413211135813212132161357132161320713461321713214134813215132191347132191320813183132201321713185132181321013184132221322432813223132283271322113232326132251322113205132261323513208132271323713207132241322913206132291322210591323013227105813231132361057132281323310601323313223132421323413231132451323513238132441323213225132431323713230403132381322640213236132344041324013242323132411324632513239132503241324313239132321324413253132351324513255132341324213247132331324713240531324813245521324913254511324613251541325113241132521324913253132561325013243132551324838413256132443831325413252382132581326035813259132633601325713266359132611325784111326213268841013260132648412132641325818911326513262189313263132671892132671325914991326813265150113266132611500voidN4CGAL7Point_3INS_5EpickEEE1

0.117844-0.279766999999999991.0801099999999999

2

0.12497800000000001-0.2311821.10005

3

0.102602-0.2671481.0492999999999999

6

0.0388902-0.2793121.0804499999999999

18

0.19981599999999999-0.189063000000000011.1170599999999999

19

0.199542-0.280426000000000011.0801099999999999

23

0.19949900000000001-0.2486941.00169

31

0.19963500000000001-0.3373411.21516

32

0.19964799999999999-0.350347999999999991.24569

33

0.19983400000000001-0.298489999999999981.2520500000000001

34

0.19982800000000001-0.291057000000000011.2347300000000001

37

0.199629-0.318180999999999991.17014

44

0.18806300000000001-0.131585000000000011.2445900000000001

45

0.20033999999999999-0.1425421.27013

46

0.19999800000000001-0.246601999999999991.2583299999999999

50

0.19999800000000001-0.244914999999999991.2543899999999999

53

0.199827-0.271780000000000021.1895199999999999

58

0.19999700000000001-0.225421000000000011.20892

59

0.19983000000000001-0.1878591.1194599999999999

69

0.20033799999999999-0.129069999999999991.2384900000000001

73

0.20033300000000001-0.132843999999999991.2473799999999999

87

0.00047471600000000003-0.170576000000000011.3386899999999999

88

-0.00154631-0.287034999999999981.10025

94

0.00047977300000000002-0.171026000000000011.3397399999999999

95

-0.00092792899999999997-0.355862000000000011.2609300000000001

99

0.199633-0.356613999999999991.2602100000000001

115

0.20041100000000001-0.1723991.3392200000000001

120

0.20000200000000001-0.2645941.29992

121

0.199819-0.310630000000000021.2801

140

0.14515800000000001-0.0937962999999999991.1551800000000001

141

0.056482200000000003-0.0193921999999999980.96907699999999997

142

0.028358299999999999-0.2072830.89990999999999999

146

-0.0021599200000000001-0.206747999999999990.90009099999999997

147

-0.0014654399999999999-0.279057999999999971.0805499999999999

151

0.00054492500000000003-0.0928771000000000041.1554199999999999

156

2.5080899999999999e-05-0.0188470999999999990.96922699999999995

190

0.00048502099999999998-0.1698461.3402400000000001

191

0.20083500000000001-0.0588112999999999971.3878699999999999

200

0.20044600000000001-0.1122471.2735700000000001

219

0.172281999999999990.0908555000000000061.2290000000000001

220

0.00242347000000000010.0925283999999999971.22939

224

0.00196770000000000020.0120239000000000011.4180900000000001

234

0.201150.0647792999999999981.29135

239

0.2013240.0109126999999999991.4175500000000001

257

0.19931499999999999-0.208530999999999990.89939899999999995

261

0.19972799999999999-0.1145190.93437199999999998

262

0.20008400000000001-0.0202812999999999990.96860599999999997

266

0.20030600000000001-0.0939948000000000031.15533

270

0.199821-0.187178000000000011.11782

283

0.40013300000000002-0.0938908999999999991.1543699999999999

284

0.36662800000000001-0.0940180000000000041.1545000000000001

285

0.40018300000000001-0.0870120999999999951.13757

288

0.400422-0.187233000000000011.1175900000000001

289

0.30010799999999999-0.187342000000000011.11758

290

0.30016199999999998-0.1321891.1397299999999999

294

0.203152-0.187179000000000011.11782

297

0.40080900000000003-0.209802999999999990.90342599999999995

301

0.40053299999999997-0.280559999999999981.07992

306

0.30004900000000001-0.280532999999999981.07979

324

0.24987799999999999-0.318145000000000011.1699600000000001

328

0.24998600000000001-0.271867000000000031.1894400000000001

331

0.30011500000000002-0.318195000000000011.1699299999999999

343

0.25009900000000002-0.225533000000000011.2088300000000001

346

0.300151-0.271911999999999991.1893899999999999

351

0.300201-0.2255751.2087000000000001

373

0.24981-0.356800000000000011.2600899999999999

374

0.249858-0.337422999999999971.2150399999999999

377

0.20679600000000001-0.356615999999999991.2601599999999999

380

0.24996099999999999-0.310794999999999991.2800400000000001

381

0.24998799999999999-0.291192999999999981.2347399999999999

392

0.21351000000000001-0.3106681.28007

423

0.233657-0.172554000000000011.33914

426

0.22022-0.264651000000000031.2998400000000001

429

0.32215500000000002-0.254041000000000021.5217799999999999

430

0.200547-0.253684000000000021.5221

434

0.199577-0.436485999999999991.44076

445

0.29531600000000002-0.436999000000000031.4406300000000001

474

-0.00076064399999999999-0.435755999999999981.44174

478

0.00054402599999999997-0.252589000000000011.5226

489

0.21029900000000001-0.296960999999999971.27474

497

0.212812-0.271388999999999991.28311

536

0.22497200000000001-0.2778351.2672399999999999

585

0.25009399999999998-0.2647331.29976

596

0.39995399999999998-0.437394999999999981.4405699999999999

597

0.40034700000000001-0.357051999999999981.2600199999999999

598

0.30000300000000002-0.3569561.2600199999999999

602

0.30011500000000002-0.310927000000000011.2799700000000001

606

0.30020599999999997-0.2648451.29962

610

0.30038799999999999-0.172696999999999991.33894

615

0.40038400000000002-0.1726781.33876

616

0.40049299999999999-0.254203000000000011.52166

625

0.40039200000000003-0.2648761.2997000000000001

636

0.40064499999999997-0.3279281.68306

641

0.39993099999999998-0.519595000000000031.62103

642

0.40029799999999999-0.428543000000000011.6624699999999999

643

0.40038200000000002-0.407584999999999981.6719900000000001

647

0.39764500000000003-0.426111000000000021.6635800000000001

648

0.39729399999999998-0.4285331.66248

649

0.38385399999999997-0.519534999999999971.62104

669

0.40048299999999998-0.382979000000000011.6831100000000001

672

0.35047400000000001-0.382809999999999981.6832499999999999

675

0.40067199999999997-0.337426999999999981.70374

687

0.35026499999999999-0.428348999999999981.6625700000000001

690

0.35068700000000003-0.337266000000000011.7038800000000001

697

0.30069400000000002-0.3370861.70401

698

0.200707-0.336641000000000021.70438

708

0.19967499999999999-0.518866000000000051.62155

709

0.29978700000000003-0.519236000000000031.62121

713

0.30023899999999998-0.428153999999999981.66269

717

0.30047000000000001-0.3826291.6834

726

0.20019799999999999-0.427771000000000011.66303

730

0.199936-0.473318000000000021.64229

741

0.149622-0.518631999999999981.6216999999999999

742

0.14990000000000001-0.473082999999999981.64246

746

0.099565299999999995-0.518388999999999991.62185

747

0.099857500000000002-0.472847999999999991.64262

750

0.150174-0.427543999999999981.6632199999999999

760

-0.00058322799999999998-0.517901999999999971.6222700000000001

761

0.0495004-0.5181541.6220399999999999

765

0.0498025-0.472598000000000021.6428100000000001

771

0.100151-0.4273191.6633899999999999

772

0.10073699999999999-0.336212000000000011.70459

787

0.000777942-0.335712999999999981.7049000000000001

788

9.4738299999999994e-05-0.426810000000000021.6636899999999999

789

-0.00024393400000000001-0.472347000000000021.64297

795

0.050126200000000003-0.427066999999999971.66354

819

0.25451000000000001-0.02876951.40052

825

0.27286300000000002-0.000829878999999999951.44391

826

0.20135700000000001-0.0165888000000000011.48028

830

0.20149300000000001-0.0711814000000000061.60324

839

0.348856-0.0715579999999999971.6028100000000001

861

0.00188744-0.0700559999999999931.60395

865

0.0019103900000000001-0.06005461.58165

915

0.25010700000000002-0.245018000000000011.2543

975

0.27498699999999998-0.324072000000000031.2474400000000001

987

0.30013299999999998-0.291306999999999981.2346900000000001

1007

0.27510099999999998-0.277967000000000021.2671600000000001

1096

0.30022500000000002-0.245105999999999991.2541899999999999

1153

0.300315-0.133124999999999991.2470300000000001

1196

0.40040799999999999-0.2256841.20865

1200

0.40031699999999998-0.1330171.2468399999999999

1225

0.30005599999999999-0.337492999999999991.2149799999999999

1238

0.40060200000000001-0.318037000000000011.1699600000000001

1339

0.27501900000000001-0.304674999999999971.20228

1417

0.30029499999999998-0.1082281.18811

1492

0.30021199999999998-0.0941974000000000011.1547400000000001

1529

0.30012899999999998-0.0203218000000000010.96852499999999997

1530

0.40021899999999999-0.0201366000000000010.96883900000000001

1534

0.40061200000000002-0.114445000000000010.93452299999999999

1535

0.40078999999999998-0.2081520.89916799999999997

1539

0.30012699999999998-0.208542000000000010.89914700000000003

1544

0.30022399999999999-0.11470.93445

1566

0.40010299999999999-0.0748806999999999941.16204

1580

0.201110000000000010.0906914999999999941.22885

1581

0.399880999999999990.0905684999999999961.22888

1585

0.399382000000000010.167051.03746

1597

0.2008230.166671999999999991.03792

1607

0.40085999999999999-0.0800494000000000070.84255999999999998

1608

0.30037399999999997-0.0803436000000000010.84245999999999999

1613

0.400270000000000010.0147103000000000010.87509599999999998

1614

0.300186000000000010.0142795000000000010.87487800000000004

1639

0.400264000000000010.0477056999999999970.78095999999999999

1640

0.300292999999999980.0474429000000000030.78081

1643

0.200134000000000010.01443350.87471699999999997

1652

0.398347999999999980.238354000000000010.84065599999999996

1657

0.200531999999999990.236749999999999990.84198499999999998

1658

0.200466000000000010.1421840.81079299999999999

1659

0.2002960.0475131000000000030.78036899999999998

1679

0.000361116999999999990.02521340.84892599999999996

1680

0.00272124000000000020.233612999999999990.85728599999999999

1681

0.0840498999999999970.1667641.03739

1685

0.000183888999999999990.0489513999999999990.78082399999999996

1686

0.001572590.143915999999999990.811832

1687

0.00216972999999999990.1911390.82775699999999997

1688

0.00269146000000000010.2380140.84397900000000003

1692

0.05219650.237336999999999990.84293600000000002

1693

0.1016890.237028999999999990.84223300000000001

1705

0.1002730.0481349000000000010.78058700000000003

1710

0.1010460.1427620.81110099999999996

1711

0.0513042000000000010.143330000000000010.81148500000000001

1717

0.0517545000000000020.1905490.82693799999999995

1724

0.1013840.1900290.82640599999999997

1749

0.1113450.0501016000000000031.0915699999999999

1757

0.1094680.0316868999999999971.0865899999999999

1775

0.1330180.0539550999999999991.13964

1794

0.1206310.0106487000000000011.1093299999999999

1862

0.324830999999999980.01078671.41726

1863

0.400181999999999980.0275115000000000011.37849

1880

0.260255999999999990.0108216000000000011.4173100000000001

1916

0.400320000000000010.01089291.4169799999999999

2064

0.40092299999999997-0.0714091.6024700000000001

2084

0.40123500000000001-0.175247999999999990.80882600000000004

2085

0.30043799999999998-0.175115999999999990.80884199999999995

2115

0.30053400000000002-0.0483827000000000010.75009400000000004

2116

0.40109699999999998-0.0478292000000000020.75012000000000001

2121

0.300728-0.143834999999999990.71839299999999995

2122

0.40166200000000002-0.143242000000000010.71887100000000004

2196

0.199958-0.0481183000000000030.74973900000000004

2227

0.20002300000000001-0.0803235000000000060.84224500000000002

2236

-0.0019564299999999999-0.183739999999999990.83724200000000004

2240

-0.0020446000000000001-0.1417080.71859099999999998

2244

0.19971-0.143604000000000010.71893300000000004

2255

0.19969000000000001-0.175669999999999990.808894

2273

0.19968900000000001-0.0877262000000000040.53740699999999997

2274

0.200053000000000010.00941944999999999940.56376599999999999

2275

0.200411000000000010.10650.58969700000000003

2276

0.200251000000000010.0780093000000000040.68549099999999996

2281

0.300462000000000010.106731000000000010.58962300000000001

2282

0.400455000000000010.1078930.58954899999999999

2295

0.40256199999999998-0.0868125000000000010.53750299999999995

2296

0.35188900000000001-0.0873609000000000050.53744999999999998

2297

0.30118-0.0877157999999999970.53736499999999998

2301

0.30102099999999998-0.0392484999999999990.55103800000000003

2302

0.300785000000000020.009376110.56378600000000001

2310

0.351202999999999990.00982718999999999950.56393300000000002

2311

0.401600999999999990.0103101000000000010.56415400000000004

2315

0.40211400000000003-0.0382943000000000030.55121299999999995

2329

0.35157899999999997-0.03885570.55115000000000003

2351

-0.0026936500000000001-0.0860023000000000040.53851700000000002

2357

0.000130297999999999990.1085170.59035199999999999

2358

0.0002023650.0943940999999999950.63808500000000001

2359

0.000247973000000000020.0798914000000000010.68592299999999995

2378

0.1003160.107180.58980500000000002

2379

0.05024870.1077970.590059

2383

0.0502729000000000020.0939104999999999940.63789499999999999

2389

0.0502920999999999990.0793275999999999980.68581700000000001

2390

0.1002730.0788499000000000010.68564099999999994

2399

0.1002610.0932719999999999940.63769799999999999

2421

0.25017-0.1118030.77996699999999997

2509

0.249948-0.144611999999999990.871286

2693

0.398687999999999990.299111000000000020.64017400000000002

2694

0.200645999999999990.298875999999999980.63922800000000002

2695

0.2004010.202659000000000010.61493399999999998

2699

0.2006870.173991000000000010.71349099999999999

2718

0.2009060.268158999999999980.741093

2742

0.1010390.1588340.76249999999999996

2743

0.1011470.174394999999999990.71353699999999998

2747

0.100709000000000010.126623999999999990.69958399999999998

2756

0.101444000000000010.206276999999999990.77726499999999998

2761

0.101513000000000010.221961999999999990.72765000000000002

2774

0.1019660.269168000000000020.74179300000000004

2778

0.101917999999999990.2533010.79208599999999996

2807

0.0518090999999999970.206769000000000010.77763099999999996

2836

0.0524026000000000010.2537780.79263899999999998

2879

0.0526198000000000010.269720999999999990.74208099999999999

2880

0.0520069000000000020.222403999999999990.72782400000000003

2909

0.00326240999999999990.270322000000000010.74241900000000005

2917

0.002602750.2231870.72796099999999997

2927

0.00310343999999999980.254327000000000030.79294399999999998

2935

0.00246661000000000020.207321000000000010.77786100000000002

2971

0.1021280.284480999999999980.69102600000000003

2972

0.1016610.2512450.62760499999999997

2973

0.1020350.299070.63970099999999996

2976

0.1015940.2369570.67769599999999997

2979

0.1012120.2033160.61503099999999999

2993

0.1011760.1892160.66434700000000002

3023

0.0521141999999999990.237637999999999990.67779100000000003

3037

0.0514599000000000030.1749840.71370500000000003

3038

0.05135580.159360.76272499999999999

3063

0.0765552000000000040.205962000000000010.695878

3099

0.0527600999999999970.284901000000000020.69114600000000004

3113

0.00275257000000000020.2382590.677952

3122

0.003443850.285621000000000010.69123100000000004

3141

0.05147910.1897710.66444199999999998

3203

0.0766128999999999980.220532000000000010.646262

3216

0.0515709999999999990.2039020.61501899999999998

3235

0.0760860000000000010.1726270.63322000000000001

3247

0.100695999999999990.141311999999999990.65099700000000005

3248

0.0508643000000000010.141863999999999990.65115000000000001

3272

0.0508390000000000020.127145000000000010.69983499999999998

3316

0.100764999999999990.155397000000000010.60218700000000003

3355

0.00104316999999999990.127786000000000010.69998000000000005

3359

0.001792430.175585999999999990.71399000000000001

3360

0.00168673999999999990.1600530.76307000000000003

3433

0.0509015000000000020.156006000000000010.60229200000000005

3487

0.00188155000000000010.1905220.66465099999999999

3495

0.001099020.1426510.65146599999999999

3750

0.00107696000000000010.156683999999999990.60245599999999999

3767

0.001942310.2046520.61499000000000004

3782

0.200193000000000010.131380.49307000000000001

3783

0.200133000000000010.142976999999999990.444438

3784

0.200032999999999990.154074999999999990.39557100000000001

3785

0.150098000000000010.154402000000000010.39549000000000001

3786

0.1001190.1548620.395569

3787

0.0001808860.156519999999999990.39613300000000001

3804

0.200896999999999990.348681000000000020.43234

3810

0.00382960999999999980.350428999999999990.43259999999999998

3816

0.00351810000000000010.300464999999999980.63944400000000001

3817

0.00276868999999999990.252556999999999980.627444

3836

0.05276020.299651999999999970.63971599999999995

3842

0.0522000999999999990.251761999999999990.62761299999999998

3960

0.199990.0942735999999999990.43423699999999998

3961

0.200070.0826743000000000060.481991

3966

0.199967000000000010.104969000000000010.386299

3969

0.200070.0451452999999999990.42386200000000002

3970

0.200061999999999990.03389760.47072000000000003

3991

0.199914000000000010.0554716999999999990.37699100000000002

3996

0.199853-0.0435405999999999990.35662199999999999

3997

0.19998099999999999-0.0642110999999999930.44650200000000001

4012

-0.0033956799999999999-0.0414655999999999980.35677399999999998

4013

-0.00190716999999999990.0575125000000000010.37738899999999997

4017

0.0990628999999999950.0560372999999999980.377475

4018

0.0995599000000000070.1054320.38634600000000002

4022

0.149761000000000010.1050210.38620599999999999

4029

0.149484000000000010.0554906999999999970.37731799999999999

4034

0.098035800000000006-0.0429847999999999970.357157

4065

0.250161000000000020.143221999999999990.44444800000000001

4068

0.250213999999999990.1318230.49288300000000002

4071

0.250078000000000020.154047999999999990.39552700000000002

4084

0.300275999999999990.132148999999999990.492919

4088

0.300223000000000020.1434560.44444299999999998

4094

0.300177000000000030.154073999999999990.39547100000000002

4095

0.350310000000000010.154523999999999990.39563100000000001

4096

0.400357000000000020.1550880.39570699999999998

4097

0.398162999999999990.349739000000000020.43179400000000001

4112

0.400384999999999990.1328230.49301800000000001

4113

0.350335000000000010.1324960.49283300000000002

4117

0.350339999999999980.1438980.444546

4128

0.400405000000000010.144302000000000010.44460499999999997

4175

0.2001550.1633310.34617500000000001

4176

0.2001840.172284999999999990.29699900000000001

4177

0.1501970.172381000000000010.29702600000000001

4178

0.150163999999999990.1636010.346024

4183

0.200827000000000010.3829630.21926499999999999

4184

0.200396999999999990.2852460.207425

4185

0.200227999999999990.186596000000000010.19827600000000001

4186

0.200130.1797820.24778600000000001

4191

0.1000080.187486000000000010.198853

4192

0.1000630.172907000000000010.296962

4196

0.100070000000000010.163985999999999990.34615000000000001

4210

0.00433835000000000040.384608000000000010.22039

4211

0.0533348999999999980.383720999999999980.21967800000000001

4212

0.1024330.383130000000000030.219416

4216

0.101880.334388000000000020.21304200000000001

4217

0.1012440.285399999999999990.20762700000000001

4224

-0.000370418999999999980.188790999999999990.198294

4225

-0.0002064220.174386999999999990.29714099999999999

4239

0.00220696999999999990.286939999999999970.20857100000000001

4240

0.003389890.335953999999999970.214058

4245

0.0525720999999999970.335100999999999980.21335499999999999

4255

0.0517241999999999980.2860550.208066

4267

-0.00243613999999999980.0756296999999999940.283252

4268

0.09880920.0740438000000000070.28294399999999997

4269

0.0994116000000000030.123412999999999990.29017799999999999

4276

0.0989494000000000070.0654102000000000020.33025100000000002

4280

0.0993953999999999950.1150.33835199999999999

4308

0.30116300000000001-0.02669740.50499499999999997

4309

0.30138999999999999-0.0759115999999999960.49224800000000002

4314

0.300831999999999990.02216270.51725299999999996

4317

0.30119899999999999-0.01496340.45896700000000001

4318

0.30152299999999999-0.0641660000000000010.44722400000000001

4333

0.250508999999999980.0339722000000000010.47067100000000001

4334

0.300906999999999980.0341954000000000010.47061799999999998

4351

0.35215400000000002-0.0754694000000000060.49230699999999999

4377

0.35174299999999997-0.02626680.50511499999999998

4413

0.40294200000000002-0.0748896000000000010.49256299999999997

4431

0.40240500000000001-0.0258558000000000020.50533099999999997

4449

0.351256999999999990.02264190.51736199999999999

4481

0.351364999999999980.0346209999999999990.47087299999999999

4485

0.35183199999999998-0.0146082999999999990.45913999999999999

4512

0.300599999999999980.0831742000000000040.48178300000000002

4523

0.401743999999999990.0231250999999999990.51753099999999996

4527

0.4018350.0351821000000000010.47092899999999999

4533

0.350850.0835850000000000070.48182999999999998

4543

0.401121000000000010.0840927000000000060.48195399999999999

4562

0.402445-0.01400650.45940300000000001

4604

0.401876000000000010.0463010999999999980.42408400000000002

4611

0.351410.0457090.423875

4616

0.351472999999999980.0561962999999999980.37702200000000002

4617

0.402015000000000010.0567642000000000010.37726999999999999

4623

0.300945999999999990.0453404000000000030.42380600000000002

4627

0.3009870.0558113000000000010.37698300000000001

4631

0.301705-0.0434898000000000020.35713800000000001

4632

0.40362999999999999-0.0423327000000000010.35805300000000001

4636

0.40312999999999999-0.06337160.447853

4654

0.35227799999999998-0.0637630.44734099999999999

4716

0.40373900000000001-0.0255785000000000010.26778299999999999

4717

0.30180099999999999-0.0265414999999999990.26737300000000003

4721

0.301101999999999980.0735299999999999980.28298600000000002

4722

0.300976999999999990.0649967999999999930.32999800000000001

4727

0.351663999999999980.0740579999999999990.28323300000000001

4728

0.402245000000000020.0748333999999999940.28363500000000003

4739

0.350860000000000010.105358999999999990.38639200000000001

4744

0.4011440.1058790.38653199999999999

4755

0.300603000000000010.1050910.38633499999999998

4763

0.400289000000000010.173691000000000010.29770999999999997

4764

0.401287999999999980.1242910.29065800000000003

4769

0.350910999999999970.123632000000000010.29048600000000002

4773

0.300615000000000020.123390.290273

4777

0.3005640.1145680.33829300000000001

4789

0.300148000000000030.1638250.34619100000000003

4790

0.300043999999999980.1729590.29724699999999998

4791

0.350152999999999990.1734010.29740899999999998

4813

0.401075999999999990.0954590000000000020.43426700000000001

4814

0.350847000000000020.0949225999999999960.43421999999999999

4931

0.3005890.0945527000000000030.43416500000000002

4976

0.250354000000000020.0829352000000000010.48179100000000002

4977

0.250313999999999980.09433540.43415399999999998

4981

0.2504980.0452238999999999970.42375000000000002

5054

0.250236000000000010.104884000000000010.386187

5066

0.250456999999999990.0556031000000000030.37690200000000001

5166

0.250269000000000020.1144810.338231

5197

0.398307000000000020.382931999999999990.21734500000000001

5203

0.400129999999999990.188795999999999990.19968900000000001

5204

0.4002290.181350000000000010.24874499999999999

5226

0.250203999999999980.186798999999999990.198354

5227

0.300204000000000030.187156999999999990.19864000000000001

5228

0.350196000000000010.1879140.19911200000000001

5233

0.350181999999999990.181027999999999990.24851899999999999

5250

0.250074000000000020.163645000000000010.34616799999999998

5255

0.250107000000000020.1727660.29711399999999999

5259

0.250112999999999970.1800360.24798100000000001

5267

0.300190000000000010.1804810.24815899999999999

5312

0.350936000000000030.131367000000000010.24251900000000001

5323

0.300663000000000010.1307490.242177

5360

0.2503090.1230620.290184

5372

0.2503610.130563000000000010.24211199999999999

5416

0.300696000000000020.137413000000000010.194156

5422

0.250410999999999990.1369570.194053

5456

0.200063999999999990.130393000000000010.24199599999999999

5460

0.199999000000000010.122815999999999990.29011900000000002

5480

0.2000420.136728999999999990.19383700000000001

5499

0.199927999999999990.0867356999999999990.188689

5500

0.199603-0.0140204000000000010.179504

5501

0.2000000000000000100

5502

0.200000000000000010.200000000000000010

5503

0.2001310.1956840.099080100000000004

5508

0.400000000000000020.200000000000000010

5518

0.250524000000000020.0870510000000000030.18872700000000001

5523

0.301157999999999980.0872970.188636

5524

0.30174400000000001-0.01372640.17893500000000001

5528

0.40399400000000002-0.01291220.17947399999999999

5529

0.4000000000000000200

5538

0.4023330.0881122000000000020.18914800000000001

5539

0.401264000000000010.138416000000000010.19476099999999999

5543

0.351003000000000010.137887000000000010.19450500000000001

5558

0.351758999999999990.0877186999999999970.188911

5581

0.2007390.295308999999999990.10353800000000001

5582

0.2008770.391861999999999990.109846

5586

0.200000000000000010.400000000000000020

5587

0.400000000000000020.400000000000000020

5606

0.200000000000000010.299999999999999990

5623

0.1007550.295735000000000030.103321

5626

0.0999643999999999950.196205999999999990.099184400000000006

5635

0.101028999999999990.291053000000000010.15569

5646

0.1016890.340048000000000020.16007099999999999

5652

0.1012880.344453000000000010.10657800000000001

5655

0.1022960.388469000000000010.16456999999999999

5671

0.1017170.392940000000000010.10996300000000001

5690

0.100000000000000010.299999999999999990

5719

0.100000000000000010.400000000000000020

5730

0.0523490.340505999999999980.16022500000000001

5734

0.0515617000000000020.291627000000000030.15612300000000001

5737

0.0518387999999999970.344833999999999970.106724

5746

0.0511949000000000020.295827999999999980.103876

5758

00.299999999999999990

5759

0.001696690.296248999999999980.10425

5765

00.400000000000000020

5769

0.003650880.394150.11046

5770

0.00277328999999999990.345254999999999980.107351

5786

0.0525665999999999980.393496999999999990.110224

5805

0.0770925999999999970.366823999999999980.13545399999999999

5833

0.0530706000000000020.389056999999999990.164822

5926

0.003294230.341401000000000010.16089200000000001

5931

0.00416199999999999990.389946999999999990.16537199999999999

5992

0.002111080.292200000000000020.15648999999999999

6090

-0.000168421000000000010.1967660.099037

6091

00.200000000000000010

6095

0.100000000000000010.200000000000000010

6201

000

6215

-0.002527320.0886471000000000060.18867300000000001

6216

-0.0045258399999999997-0.01179770.17880399999999999

6221

0.097567899999999999-0.01290590.17840200000000001

6236

0.0986848000000000030.0872242000000000020.18840000000000001

6277

0.301148000000000030.0810011999999999950.235961

6282

0.2505310.0807739999999999990.23592099999999999

6296

0.250522000000000020.0732522000000000030.28297

6299

0.199948999999999990.0803853999999999960.23594300000000001

6304

0.1999310.0731815999999999990.28309299999999998

6305

0.19969999999999999-0.0269309000000000010.267538

6327

0.097791400000000001-0.0264536000000000010.26771400000000001

6332

0.149333999999999990.0734937999999999980.28291100000000002

6358

-0.0040554700000000003-0.0248315999999999990.268009

6406

0.199945000000000010.0648515000000000060.33001799999999998

6410

0.149415999999999990.0650562999999999970.33017600000000003

6444

0.250477000000000010.0649629000000000040.32994899999999999

6525

0.225177999999999990.0750929000000000040.40531099999999998

6557

0.225233999999999990.0641103999999999980.45266499999999998

6691

0.200000000000000010.1142360.33821499999999999

6779

0.149718999999999990.123020.29011100000000001

6780

0.149741000000000010.114474000000000010.33829300000000001

6879

0.174746000000000010.0939770999999999940.31032700000000002

6977

0.1747580.0850300999999999970.35805799999999999

7318

0.351698999999999980.0815297999999999990.23610400000000001

7430

0.402289000000000010.0820212000000000020.23638899999999999

7465

0.401307000000000020.132015999999999990.24260399999999999

7739

0.2251910.112990999999999990.46343699999999999

8229

0.00211825999999999980.1672631.0377099999999999

8238

0.1008960.0365819000000000011.09802

8437

0.40120400000000001-0.1209851.71123

8455

0.40029999999999999-0.431367999999999971.6686300000000001

8463

0.39994400000000002-0.534703999999999961.65381

8478

0.29984100000000002-0.560871000000000011.71157

8479

0.39991199999999999-0.5612531.71133

8483

0.40035300000000001-0.4703331.75308

8484

0.40032000000000001-0.4494051.70777

8488

0.35029500000000002-0.449218000000000011.7078899999999999

8498

0.30027999999999999-0.449029000000000011.7080299999999999

8499

0.30031400000000003-0.469947999999999981.75335

8503

0.35033300000000001-0.4701381.7532099999999999

8519

0.19970599999999999-0.539641000000000041.6667099999999999

8520

0.19975799999999999-0.560466000000000021.7118800000000001

8530

0.19997699999999999-0.494120999999999981.6875500000000001

8536

0.20002-0.515013000000000051.7327900000000001

8537

0.20028299999999999-0.469534999999999981.7536499999999999

8538

0.25029899999999999-0.469737999999999991.75349

8551

0.20024-0.448631999999999981.70834

8565

0.30051099999999997-0.403517000000000011.72878

8570

0.30074400000000001-0.358018999999999981.7494799999999999

8582

0.30055199999999999-0.424460999999999981.7741400000000001

8583

0.30079099999999998-0.378971999999999981.7948999999999999

8587

0.25080200000000002-0.378767000000000021.7950600000000001

8588

0.20081099999999999-0.378560999999999981.79522

8593

0.20055100000000001-0.424049999999999981.77444

8612

0.25054999999999999-0.424260000000000031.7742899999999999

8632

0.15022099999999999-0.448396999999999991.70852

8637

0.14994299999999999-0.493908999999999991.68771

8646

0.100824-0.378076000000000021.79552

8653

0.15026400000000001-0.469303000000000031.7538100000000001

8654

0.100246-0.469065999999999981.7539800000000001

8655

0.100539-0.423574999999999981.7747599999999999

8660

0.100199-0.448172000000000011.70868

8692

0.14998800000000001-0.514785999999999971.7329600000000001

8719

0.20032900000000001-0.490483999999999981.79895

8727

0.20005400000000001-0.535942000000000031.77806

8736

0.19978499999999999-0.581381000000000041.7571099999999999

8740

0.20009299999999999-0.556899000000000031.82334

8741

0.19981699999999999-0.602323000000000051.8023800000000001

8745

0.29987200000000003-0.602744999999999981.8020700000000001

8753

0.20036499999999999-0.511471000000000011.84426

8757

0.25037599999999999-0.511693999999999981.84412

8758

0.30038700000000002-0.511905999999999971.84398

8763

0.30034899999999998-0.490914999999999991.7986599999999999

8777

0.25033899999999998-0.490703999999999971.7988

8824

0.14974999999999999-0.581153000000000031.7572700000000001

8849

0.15003-0.535712999999999991.7782199999999999

8853

0.15031-0.490252999999999991.79911

8880

0.14971000000000001-0.560257000000000011.7120500000000001

8895

0.099662100000000003-0.560019000000000041.71221

8899

0.099712800000000004-0.580915999999999991.7574399999999999

8903

0.10000199999999999-0.535476999999999981.7783899999999999

8909

0.099956000000000003-0.514557000000000041.7331300000000001

8926

0.15007499999999999-0.556668000000000051.8234999999999999

8930

0.14979100000000001-0.602095000000000051.80254

8954

0.099757999999999999-0.601855999999999951.8027

8958

0.100051-0.5564271.8236600000000001

8985

0.100344-0.510993999999999951.84459

8986

0.15035499999999999-0.511229999999999961.8444199999999999

8996

0.10029200000000001-0.490018999999999981.79928

9005

0.0503305-0.510738000000000031.84476

9006

0.050279299999999999-0.489765999999999981.7994399999999999

9011

0.000316862-0.510480999999999961.84493

9012

0.000260852-0.489509000000000031.79962

9024

-0.00029369500000000001-0.601345000000000021.80305

9029

-0.00042972399999999998-0.559505000000000031.71255

9030

-0.000119459-0.514040000000000051.7334799999999999

9031

0.00019950100000000001-0.4685591.7543200000000001

9034

0.050223799999999999-0.468814000000000011.75414

9049

0.049618000000000002-0.559768999999999961.7123900000000001

9062

0.049919199999999997-0.514306999999999961.7333000000000001

9083

0.050634199999999997-0.465276000000000021.86561

9086

0.100634-0.465536000000000011.8654500000000001

9089

0.00062858300000000005-0.465021999999999991.8657900000000001

9101

0.20063800000000001-0.466019000000000021.86514

9102

0.20091100000000001-0.420571.88601

9103

0.100925-0.420086999999999991.88632

9107

0.050931900000000002-0.419833000000000011.8864799999999999

9111

0.00094082300000000003-0.419563000000000021.8866400000000001

9115

0.0011012800000000001-0.503658999999999972.06819

9116

-8.5875299999999994e-05-0.685243000000000051.98431

9121

0.19994100000000001-0.686262999999999961.9836800000000001

9141

0.2011-0.504681000000000052.0675300000000001

9163

0.075460899999999997-0.477644000000000011.8324400000000001

9195

0.050580899999999998-0.444288999999999991.8202700000000001

9198

0.00057624599999999998-0.444031000000000011.8204400000000001

9234

0.10058499999999999-0.444535999999999991.8201099999999999

9269

0.075756799999999999-0.4321761.85328

9284

0.050883100000000001-0.3988141.84108

9287

0.10087699999999999-0.399069000000000011.8409199999999999

9374

0.20085900000000001-0.3995651.8406100000000001

9399

0.20059299999999999-0.445020000000000031.81979

9480

0.30063800000000002-0.466449999999999981.8648400000000001

9481

0.250639-0.466241999999999991.8649899999999999

9487

0.30089199999999999-0.420997999999999981.8856999999999999

9488

0.25090099999999999-0.420789000000000021.88585

9501

0.40040399999999998-0.512294999999999941.8436699999999999

9502

0.40087400000000001-0.421393999999999991.8854

9507

0.40109099999999998-0.505624999999999992.0668899999999999

9508

0.35109200000000002-0.505399000000000042.0670500000000001

9509

0.30109399999999997-0.5051662.0672100000000002

9526

0.39997700000000003-0.687205999999999981.98302

9527

0.39991700000000002-0.603156000000000031.8017799999999999

9548

0.14965700000000001-0.539403999999999991.6668499999999999

9679

0.099904599999999996-0.493671000000000031.68788

9694

0.050173200000000001-0.447919999999999981.7088399999999999

9695

0.049865199999999998-0.493427999999999981.6880599999999999

9726

0.000141364-0.4476541.7090099999999999

9742

0.050530199999999997-0.423329000000000011.7749299999999999

9758

0.00084863600000000005-0.377560000000000011.79583

9759

0.00052356899999999999-0.423061999999999991.7750900000000001

9769

0.050834799999999999-0.377827000000000021.7956799999999999

9799

0.25059500000000001-0.445232999999999991.8196399999999999

9812

0.30059399999999997-0.445444000000000011.8194900000000001

9854

0.25085099999999999-0.399770000000000011.84046

9897

0.22574900000000001-0.4328961.8528100000000001

9956

0.099611599999999995-0.539166000000000031.667

10095

0.0021201900000000001-0.153593000000000011.78742

10105

0.201768-0.154811.78684

10119

0.40152500000000002-0.155489999999999991.7862499999999999

10155

0.35051399999999999-0.403702000000000011.7286300000000001

10160

0.40052500000000002-0.403882999999999991.7284999999999999

10224

0.37543199999999999-0.437016999999999991.7408699999999999

10244

0.400565-0.424844999999999971.77386

10275

0.35055900000000001-0.424659999999999981.77399

10298

0.300846-0.3999741.8403

10319

0.35078500000000001-0.3791621.7947599999999999

10320

0.40077299999999999-0.379354000000000021.79461

10436

0.400723-0.358379999999999981.74919

10444

0.35073799999999999-0.358202000000000021.7493399999999999

10497

0.40181499999999998-0.2396471.96879

10505

0.20199900000000001-0.2388711.96943

10720

0.0021884399999999998-0.237888999999999991.9701200000000001

10732

0.00089668199999999999-0.398554999999999991.84124

10854

-0.00018396100000000001-0.493161999999999991.68824

10941

0.0495583-0.538915999999999951.6671899999999999

10981

-0.00050419799999999997-0.538669999999999981.6673899999999999

11145

0.202269-0.323170000000000012.1513499999999999

11146

0.00235272-0.322045000000000032.1519400000000002

11160

0.20168-0.413916000000000012.10941

11161

0.20197200000000001-0.368543999999999982.1303700000000001

11170

0.301375-0.459772999999999992.0881400000000001

11171

0.35136899999999999-0.460000999999999992.0879799999999999

11177

0.251668-0.414152999999999992.1092499999999998

11178

0.30165799999999998-0.414389999999999982.1090900000000001

11182

0.35164699999999999-0.414611999999999982.1089199999999999

11185

0.40136100000000002-0.460222999999999992.0878199999999998

11204

0.25195499999999998-0.368781000000000032.13022

11210

0.30193799999999998-0.369012000000000012.1300599999999998

11211

0.30221399999999998-0.323635000000000012.15103

11212

0.402167-0.324066999999999992.1506599999999998

11213

0.40163300000000002-0.414829999999999982.1087500000000001

11235

0.25224000000000002-0.3234072.1511900000000002

11255

0.20008600000000001-0.770259000000000032.16513

11256

0.40010800000000002-0.771221999999999962.1645099999999999

11260

0.40126400000000001-0.589705999999999952.2484099999999998

11261

0.401223-0.568713000000000022.20302

11262

0.40117900000000001-0.547707999999999972.1576399999999998

11263

0.40113599999999999-0.526672999999999952.1122700000000001

11267

0.35113499999999997-0.526434999999999992.1124299999999998

11271

0.30113800000000002-0.526201000000000032.11259

11275

0.30118099999999998-0.547224999999999962.1579600000000001

11276

0.201179-0.546730000000000052.15828

11280

0.20125799999999999-0.588709000000000042.2490600000000001

11285

0.30126399999999998-0.589211000000000042.2487400000000002

11286

0.35126600000000002-0.589458000000000042.24857

11293

0.35117999999999999-0.547468999999999982.1577999999999999

11306

0.30122399999999999-0.568223000000000032.2033499999999999

11312

0.35122399999999998-0.568466999999999942.2031900000000002

11337

7.3296799999999999e-05-0.769220000000000012.16581

11341

0.0012577000000000001-0.587647000000000032.2496999999999998

11351

0.20172499999999999-0.434946999999999972.1547999999999998

11356

0.202016-0.3895732.17577

11367

0.20177-0.455961999999999982.2002000000000002

11371

0.202066-0.410584999999999982.2211699999999999

11374

0.20231399999999999-0.344198999999999982.1967500000000002

11379

0.20236899999999999-0.3652052.2421500000000001

11380

0.20244999999999999-0.407171999999999982.3329300000000002

11381

0.0024716199999999999-0.4060532.3335400000000002

11394

0.201849-0.497933000000000012.2909799999999998

11409

0.30156100000000002-0.543815000000000052.2696900000000002

11410

0.30151699999999998-0.522834000000000022.2242999999999999

11415

0.30185600000000001-0.498427000000000012.2906499999999999

11416

0.30181000000000002-0.477447999999999982.24526

11419

0.30147200000000002-0.501835000000000032.1789200000000002

11434

0.25176700000000002-0.456206999999999972.20004

11435

0.30176199999999997-0.456448999999999992.1998700000000002

11464

0.25229499999999999-0.344436999999999992.1966000000000001

11468

0.25200699999999998-0.389811000000000022.1756099999999998

11478

0.30227900000000002-0.344671999999999982.1964299999999999

11479

0.30199799999999999-0.390048000000000012.1754500000000001

11505

0.35170499999999999-0.435655000000000012.1543199999999998

11506

0.40169700000000003-0.435881999999999992.15415

11511

0.35175800000000002-0.456683999999999982.1997100000000001

11512

0.401754-0.456915999999999992.1995300000000002

11516

0.40232499999999999-0.366153000000000012.2414800000000001

11527

0.30171199999999998-0.435427000000000012.15448

11535

0.30204999999999999-0.411067000000000022.2208399999999999

11536

0.30233700000000002-0.365690000000000022.2418300000000002

11580

0.25171900000000003-0.435188999999999992.1546500000000002

11660

0.252058-0.410828000000000032.2210100000000002

11710

0.25235099999999999-0.3654482.2419899999999999

11755

0.30244500000000002-0.4076632.3325999999999998

11821

0.301427-0.480810000000000022.1335299999999999

11891

0.32625799999999999-0.493105000000000022.1002900000000002

11926

0.35147-0.502071999999999962.17875

11934

0.35142099999999998-0.481044000000000032.1333700000000002

12000

0.40141500000000002-0.481275999999999982.1332

12097

0.40146500000000002-0.502310000000000032.1785899999999998

12125

0.401806-0.477924000000000022.24492

12126

0.35180800000000001-0.4776862.2450899999999998

12131

0.40151399999999998-0.5233162.22397

12132

0.35151700000000002-0.523077000000000012.2241399999999998

12357

0.35156300000000001-0.544054000000000042.26953

12406

0.401561-0.544301000000000032.2693599999999998

12449

0.40185900000000002-0.498902999999999992.2903199999999999

12455

0.351858-0.4986642.2904900000000001

12539

0.40243899999999999-0.408127000000000022.3322500000000002

12607

0.27574500000000002-0.433107999999999991.85266

12799

0.025760000000000002-0.431916000000000021.85344

11Volume_infovoid
\ No newline at end of file diff --git a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp b/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp new file mode 100644 index 00000000000..87f1fe88bfe --- /dev/null +++ b/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_vtk_io.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +int main() +{ + CGAL::Linear_cell_complex_for_combinatorial_map<3> lcc; + std::ifstream is("data/beam-with-mixed-cells.3map"); + if(!is) + { + std::cout<<"Error opening data/beam-with-mixed-cells.3map."<>lcc; + // Compute per-volume vertex count + std::vector volume_scalars; + for(auto it=lcc.template one_dart_per_cell<3>().begin(), + itend=lcc.template one_dart_per_cell<3>().end(); it!=itend; ++it) + { + std::size_t nbv=lcc.template one_dart_per_incident_cell<0,3>(it).size(); + volume_scalars.push_back(nbv); + } + + if(!CGAL::IO::write_VTK("beam-with-mixed-cells.vtk", lcc, nullptr, + &volume_scalars)) + { + std::cout<<"Error for write_VTK."< + +#ifndef CGAL_LCC_IO_VTK_H +#define CGAL_LCC_IO_VTK_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { +namespace IO { + +/* + * Functions to import/export 3D Linear_cell_complex from/to VTK legacy ASCII + * format. + * + * Only supports: + * - Linear_cell_complex_for_combinatorial_map<3,3> + * - VTK legacy ASCII format (.vtk files) + * - Optional scalar fields for vertices and volumes + * + * Supported VTK cell types: + * - VTK_TETRA (10): Tetrahedron + * - VTK_VOXEL (11): Voxel (special hexahedron ordering) + * - VTK_HEXAHEDRON (12): Hexahedron + * - VTK_WEDGE (13): Prism/Wedge + * - VTK_PYRAMID (14): Pyramid + * - VTK_PENTAGONAL_PRISM (15): Pentagonal prism + * - VTK_HEXAGONAL_PRISM (16): Hexagonal prism + * - VTK_POLYHEDRON (42): Generic polyhedron + */ + +// ============================================================================ +// Declarations +// ============================================================================ + +/* + * Read a VTK legacy ASCII file and load it into a 3D Linear_cell_complex. + * + * \tparam LCC must be a Linear_cell_complex_for_combinatorial_map<3,3> + * \tparam VertexScalarType Type for vertex scalar data (default: float) + * \tparam VolumeScalarType Type for volume scalar data (default: float) + * \param alcc The Linear_cell_complex to populate (will be cleared first) + * \param filename Path to the VTK file + * \param vertex_scalars Optional output vector to store per-vertex scalar values. + * If provided, will be resized to match number of vertices. + * \param volume_scalars Optional output vector to store per-volume scalar values. + * If provided, will be resized to match number of volumes. + * \return `true` if loading was successful, `false` otherwise + */ +template +bool read_VTK(const char* filename, + LCC& alcc, + std::vector* vertex_scalars, + std::vector* volume_scalars); + +/* + * Write a 3D Linear_cell_complex to a VTK legacy ASCII file. + * + * \tparam LCC must be a Linear_cell_complex_for_combinatorial_map<3,3> + * \tparam VertexScalarType Type for vertex scalar data (default: float) + * \tparam VolumeScalarType Type for volume scalar data (default: float) + * \param alcc The Linear_cell_complex to export + * \param filename Path to the output VTK file + * \param vertex_scalars Optional per-vertex scalar data. If provided, must have + * same size as number of vertex attributes in the LCC. + * \param volume_scalars Optional per-volume scalar data. If provided, must have + * same size as number of 3-cells in the LCC. + * \return `true` if writing was successful, `false` otherwise + */ +template +bool write_VTK(const char* filename, + const LCC& alcc, + const std::vector* vertex_scalars, + const std::vector* volume_scalars); + +// "Advanced" versions with functors +template +bool write_VTK_with_fct(const char* filename, const LCC& alcc, + PointFunctor ptval, CellFunctor cellval); + +// ============================================================================ +// Implementation details +// ============================================================================ + +namespace internal +{ + ///////////////////////////////////////////////////////////////////////////// + // VTK type name mapping + // bit, unsigned_char, char, unsigned_short, short, unsigned_int, int, + // unsigned_long, long, float, double. + template + struct gettype + { static std::string name() { return "unknown"; }}; + template<> + struct gettype + { static std::string name() { return "bit"; }}; + template<> + struct gettype + { static std::string name() { return "unsigned_char"; }}; + template<> + struct gettype + { static std::string name() { return "char"; }}; + template<> + struct gettype + { static std::string name() { return "unsigned_short"; }}; + template<> + struct gettype + { static std::string name() { return "short"; }}; + template<> + struct gettype + { static std::string name() { return "unsigned_int"; }}; + template<> + struct gettype + { static std::string name() { return "int"; }}; + template<> + struct gettype + { static std::string name() { return "unsigned_long"; }}; + template<> + struct gettype + { static std::string name() { return "long"; }}; + template<> + struct gettype + { static std::string name() { return "float"; }}; + template<> + struct gettype + { static std::string name() { return "double"; }}; + ///////////////////////////////////////////////////////////////////////////// + // VTK cell type constants + enum VTK_Cell_Type + { + VTK_TETRA = 10, + VTK_VOXEL = 11, + VTK_HEXAHEDRON = 12, + VTK_WEDGE = 13, // Prism + VTK_PYRAMID = 14, + VTK_PENTAGONAL_PRISM = 15, + VTK_HEXAGONAL_PRISM = 16, + VTK_POLYHEDRON = 42 // Generic cell + }; + ///////////////////////////////////////////////////////////////////////////// + /// Write cell_data. + template + struct Write_cell_data + { + /// nb is the number of cells, + /// fct is a function having 3 parameters: a lcc, a dart_descriptor, + /// an the index of the cell. + template + static void run(std::ofstream& fo, LCC& lcc, std::size_t nb, FCT fct) + { + fo<<"CELL_DATA "<::name() + <<" 1"<().begin(), + itvolend=lcc.template one_dart_per_cell<3>().end(); + itvol!=itvolend; ++itvol, ++i) + { fo< + struct Write_cell_data + { + template + static void run(std::ofstream&, LCC&, std::size_t, std::nullptr_t) + {} + }; + ///////////////////////////////////////////////////////////////////////////// + /// Write point_data. + template + struct Write_point_data + { + /// nb is the number of cells, + /// fct is a function having 3 parameters: a lcc, a dart_descriptor, + /// an the index of the cell. + template + static void run(std::ofstream& fo, LCC& lcc, std::size_t nb, FCT fct) + { + fo<<"POINT_DATA "<::name() + <<" 1"<(itv), i)< + struct Write_point_data + { + template + static void run(std::ofstream&, LCC&, std::size_t, std::nullptr_t) + {} + }; + ///////////////////////////////////////////////////////////////////////////// + // Read data, stored values as T. + template + bool read_data(std::istream& fi, std::string& line, std::vector& data) + { + std::string txt, data_type; + std::size_t nb; + std::istringstream inputline(line); + inputline>>txt>>nb; // "CELL_DATA xxx" + fi>>txt>>txt; // "SCALARS cell_scalars " + fi>>data_type>>txt; // type for data + fi>>txt>>txt; // "LOOKUP_TABLE default" + if(!fi.good()) + { return false; } + data.clear(); + data.reserve(nb); + for(std::size_t i=0; i>txt)) + { return false; } + + std::stringstream ss{txt}; + T t; + ss>>t; + + data.push_back(t); + } + return true; + } + ///////////////////////////////////////////////////////////////////////////// + // Helper: detect VTK cell type from a 3-cell + template + VTK_Cell_Type get_vtk_cell_type(const LCC& lcc, + typename LCC::Dart_const_descriptor itvol, + typename LCC::Dart_const_descriptor& sd) + { + using namespace CGAL::CMap::Element_topo; + cell_topo vol_type=get_cell_topo<3>(lcc, itvol, sd); + switch(vol_type) + { + case TETRAHEDRON: return VTK_TETRA; + case PYRAMID: return VTK_PYRAMID; + case PRISM: return VTK_WEDGE; + case HEXAHEDRON: return VTK_HEXAHEDRON; + // case PENTAGONAL_PRISM: return VTK_PENTAGONAL_PRISM; + // case HEXAGONAL_PRISM: return VTK_HEXAGONAL_PRISM; + // 24 QUADRATIC_TETRA + // 25 QUADRATIC_HEXAHEDRON + // 26 QUADRATIC_WEDGE + // 27 QUADRATIC_PYRAMID + default: break; + } + return VTK_POLYHEDRON; + } + ///////////////////////////////////////////////////////////////////////////// +template +bool read_lcc_from_vtk_ascii(std::istream& is, LCC& alcc, + std::vector* vertex_scalars=nullptr, + std::vector* cell_scalars=nullptr) +{ + static_assert(LCC::dimension==3 && LCC::ambient_dimension==3, + "read_VTK() only supports 3D Linear_cell_complexes (3,3)"); + + using Point=typename LCC::Point; + using FT=typename LCC::FT; + + Linear_cell_complex_incremental_builder_3 ib(alcc); + + std::string line, tmp; + std::size_t npoints, ncells; + + // Skip to POINTS section + while(std::getline(is, line) && line.find("POINTS")==std::string::npos) + {} + if(is.eof()) + { + std::cerr<<"[ERROR] read_VTK: POINTS section not found"<>npoints; + + // Read points + std::vector points(npoints); + for(std::size_t i=0; i>x>>y>>z)) + { + std::cerr<<"[ERROR] read_VTK: failed to read point "<>ncells; + + // Read connectivity + std::vector> faces(ncells); + std::size_t points_per_cell; + for(std::size_t i=0; i>points_per_cell)) + { + std::cerr<<"[ERROR] read_VTK: failed to read cell "<>faces[i][j])) + { + std::cerr<<"[ERROR] read_VTK: failed to read cell "< error_types; + for(std::size_t i = 0; i>cell_type)) + { + std::cerr<<"[ERROR] read_VTK: failed to read cell type "<(itv)==alcc.null_descriptor) + { alcc.erase_vertex_attribute(itv); } + } + + if(vertex_scalars!=nullptr) + { vertex_scalars->clear(); } + if(cell_scalars!=nullptr) + { cell_scalars->clear(); } + + while(std::getline(is, line)) + { + // Read POINT_DATA scalars if present + if(vertex_scalars!=nullptr && line.find("POINT_DATA")!=std::string::npos) + { + if(!read_data(is, line, *vertex_scalars)) + { + std::cerr<<"[ERROR] read_VTK: error when reading POINT_DATA." + < +bool write_lcc_topo_to_vtk_ascii(std::ostream& os, const LCC& alcc, + std::size_t& nbpts, std::size_t& nbcells) +{ + static_assert(LCC::dimension==3 && LCC::ambient_dimension==3, + "write_VTK() only supports 3D Linear_cell_complexes (3,3)"); + + // Write VTK header + os<<"# vtk DataFile Version 2.0\n"; + os<<"CGAL Linear_cell_complex\n"; + os<<"ASCII\n"; + os<<"DATASET UNSTRUCTURED_GRID\n\n"; + + // Build vertex index map and write points + std::unordered_map + index; + nbpts=0; + os<<"POINTS "<point()<::const_iterator + itvol=alcc.template one_dart_per_cell<3>().begin(), + itvolend=alcc.template one_dart_per_cell<3>().end(); + itvol!=itvolend; ++itvol) + { + ++nbcells; + ++total_size; // for the number of vertices + VTK_Cell_Type cell_type=get_vtk_cell_type(alcc, itvol, sd); + type_stream<(cell_type)<(sd))]<<" " + <(sd))]<<" " + <(sd))]<(sd))]<<" " + <(sd))]<<" " + <(sd))]<<" " + <(sd))]<(sd))]<<" " + <(sd))]<<" "; + // Move to the up face + typename LCC::Dart_const_descriptor d2=alcc.template beta<2, 1, 1, 2>(sd); + cell_stream<(d2))]<<" " + <(d2))]<(sd); + } + typename LCC::Dart_const_descriptor d2=alcc.template beta<2, 1, 1, 2, 1>(sd); + // Darts associated with particles 4, 5, 6, 7 + for(unsigned int i = 0; i < 4; i++) + { + cell_stream<(d2); + } + cell_stream<> faces; + std::size_t cell_size=1; // Start with 1 for number of faces + ++total_size; // for the same reason + for(auto itface=alcc.template one_dart_per_incident_cell<2, 3, 2>(itvol).begin(), + itfaceend=alcc.template one_dart_per_incident_cell<2, 3, 2>(itvol).end(); + itface!=itfaceend; ++itface) + { + faces.push_back(std::vector()); + typename LCC::Dart_const_descriptor curdh=itface; + do + { + faces.back().push_back(index[alcc.vertex_attribute(curdh)]); + curdh=alcc.template beta<1>(curdh); + } + while(curdh!=itface); + cell_size+=faces.back().size()+1; // +1 for the number of vertices in the face + } + cell_stream< +bool read_VTK(const char* filename, LCC& alcc, + std::vector* vertex_scalars, + std::vector* volume_scalars) +{ + CGAL_assertion(filename!=nullptr); + std::ifstream file(filename); + if(!file.is_open()) + { + std::cerr<<"[ERROR] read_VTK: cannot open file "< +bool read_VTK(const char* filename, LCC& alcc) +{ return read_VTK(filename, alcc, nullptr, nullptr); } + +template +bool read_VTK(const char* filename, LCC& alcc, + std::vector* vertex_scalars) +{ return read_VTK + (filename, alcc, vertex_scalars, nullptr); } + +template +bool read_VTK(const char* filename, LCC& alcc, + std::nullptr_t, + std::vector* volume_scalars) +{ return read_VTK + (filename, alcc, nullptr, volume_scalars); } +//////////////////////////////////////////////////////////////////////////////////// +template +inline bool write_VTK_with_fct(const char* filename, const LCC& alcc, + PointFunctor pointfct, CellFunctor cellfct) +{ + CGAL_assertion(filename!=nullptr); + std::ofstream file(filename); + if(!file.good()) + { + std::cerr<<"[ERROR] write_VTK: cannot open file "<:: + run(file, alcc, nbpts, pointfct); } + if(cellfct) + { internal::Write_cell_data:: + run(file, alcc, nbcells, cellfct); } + } + file.close(); + return true; +} +//////////////////////////////////////////////////////////////////////////////////// +template +bool write_VTK(const char* filename, const LCC& alcc, + const std::vector* vertex_scalars, + const std::vector* volume_scalars) +{ + std::function vertexfct; + std::function cellfct; + if(vertex_scalars!=nullptr) + { + vertexfct=[&vertex_scalars](const LCC&, typename LCC::Dart_const_descriptor, + std::size_t i) -> VertexScalarType + { return (*vertex_scalars)[i]; }; + } + + if(volume_scalars!=nullptr) + { + cellfct=[&volume_scalars](const LCC&, typename LCC::Dart_const_descriptor, + std::size_t i) -> VolumeScalarType + { return (*volume_scalars)[i]; }; + } + + return write_VTK_with_fct(filename, alcc, vertexfct, cellfct); +} + +template +bool write_VTK(const char* filename, const LCC& alcc) +{ + return write_VTK(filename, alcc, nullptr, nullptr); +} + +template +bool write_VTK(const char* filename, const LCC& alcc, + const std::vector* vertex_scalars) +{ + return write_VTK(filename, alcc, vertex_scalars, + nullptr); +} + +template +bool write_VTK(const char* filename, const LCC& alcc, + std::nullptr_t, + const std::vector* volume_scalars) +{ + return write_VTK(filename, alcc, nullptr, + volume_scalars); +} +//////////////////////////////////////////////////////////////////////////////////// + +} // namespace IO +} // namespace CGAL + +#endif // CGAL_LCC_IO_VTK_H diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h index 3204c4e3bd1..85962114a78 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h @@ -213,7 +213,7 @@ namespace CGAL { return *this; } - /** Create a vertex attribute. + /** Creates a vertex attribute. * @return a handle on the new attribute. */ template @@ -221,7 +221,7 @@ namespace CGAL { { return Base::template create_attribute<0>(args...); } /** - * Create a new dart associated with a handle through an attribute. + * Creates a new dart associated with a handle through an attribute. * @param ahandle the point handle to associated with the dart. * @return a Dart_descriptor on the new dart. */ @@ -232,7 +232,7 @@ namespace CGAL { return res; } - /** Create a new dart associated with a point. + /** Creates a new dart associated with a point. * @param apoint the point to associated with the dart. * @return a Dart_descriptor on the new dart. */ @@ -307,7 +307,7 @@ namespace CGAL { return point_of_vertex_attribute(this->template attribute<0>(adart)); } - /** Test if the lcc is valid. + /** Tests if the lcc is valid. * A Linear_cell_complex is valid if it is a valid Combinatorial_map with * an attribute associated to each dart. * @return true iff the map is valid. @@ -550,7 +550,7 @@ namespace CGAL { return res; } - /** Create a segment given 2 points. + /** Creates a segment given 2 points. * @param p0 the first point. * @param p1 the second point. * if closed==true, the edge has no 2-free dart. @@ -564,7 +564,7 @@ namespace CGAL { closed); } - /** Create a triangle given 3 points. + /** Creates a triangle given 3 points. * @param p0 the first point. * @param p1 the second point. * @param p2 the third point. @@ -579,7 +579,7 @@ namespace CGAL { create_vertex_attribute(p2)); } - /** Create a quadrangle given 4 points. + /** Creates a quadrangle given 4 points. * @param p0 the first point. * @param p1 the second point. * @param p2 the third point. @@ -598,7 +598,7 @@ namespace CGAL { } - /** Create a tetrahedron given 4 Vertex_attribute_descriptor. + /** Creates a tetrahedron given 4 Vertex_attribute_descriptor. * @param h0 the first vertex handle. * @param h1 the second vertex handle. * @param h2 the third vertex handle. @@ -619,7 +619,7 @@ namespace CGAL { return this->make_combinatorial_tetrahedron(d1, d2, d3, d4); } - /** Create a tetrahedron given 4 points. + /** Creates a tetrahedron given 4 points. * @param p0 the first point. * @param p1 the second point. * @param p2 the third point. @@ -638,7 +638,7 @@ namespace CGAL { create_vertex_attribute(p3)); } - /** Create an hexahedron given 8 Vertex_attribute_descriptor. + /** Creates an hexahedron given 8 Vertex_attribute_descriptor. * (8 vertices, 12 edges and 6 facets) * \verbatim * 4----7 @@ -660,13 +660,13 @@ namespace CGAL { * h0,h5 and to the facet (h0,h5,h6,h1). */ Dart_descriptor make_hexahedron(Vertex_attribute_descriptor h0, - Vertex_attribute_descriptor h1, - Vertex_attribute_descriptor h2, - Vertex_attribute_descriptor h3, - Vertex_attribute_descriptor h4, - Vertex_attribute_descriptor h5, - Vertex_attribute_descriptor h6, - Vertex_attribute_descriptor h7) + Vertex_attribute_descriptor h1, + Vertex_attribute_descriptor h2, + Vertex_attribute_descriptor h3, + Vertex_attribute_descriptor h4, + Vertex_attribute_descriptor h5, + Vertex_attribute_descriptor h6, + Vertex_attribute_descriptor h7) { Dart_descriptor d1 = make_quadrangle(h0, h5, h6, h1); Dart_descriptor d2 = make_quadrangle(h1, h6, h7, h2); @@ -678,7 +678,7 @@ namespace CGAL { return this->make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6); } - /** Create an hexahedron given 8 points. + /** Creates an hexahedron given 8 points. * \verbatim * 4----7 * /| /| @@ -717,6 +717,133 @@ namespace CGAL { create_vertex_attribute(p7)); } + /** Creates a prism given 6 Vertex_attribute_descriptor. + * (6 vertices, 9 edges and 5 facets) + * \verbatim + * 3---4 + * |\ /| + * 0-5-1 + * \|/ + * 2 + * \endverbatim + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @param h2 the third vertex handle. + * @param h3 the fourth vertex handle. + * @param h4 the fifth vertex handle. + * @param h5 the sixth vertex handle. + * @return the dart of the new prism incident to h0 and to + * the facet (h0,h1,h2). + */ + Dart_descriptor make_prism(Vertex_attribute_descriptor h0, + Vertex_attribute_descriptor h1, + Vertex_attribute_descriptor h2, + Vertex_attribute_descriptor h3, + Vertex_attribute_descriptor h4, + Vertex_attribute_descriptor h5) + { + Dart_descriptor d1=make_triangle(h0, h1, h2); + Dart_descriptor d2=make_quadrangle(h1, h0, h3, h4); + Dart_descriptor d3=make_quadrangle(h2, h1, h4, h5); + Dart_descriptor d4=make_quadrangle(h0, h2, h5, h3); + Dart_descriptor d5=make_triangle(h4, h3, h5); + + return make_combinatorial_prism(d1, d2, d3, d4, d5); + } + + /** Creates a prism given 6 points. + * \verbatim + * 3---4 + * |\ /| + * 0-5-1 + * \|/ + * 2 + * \endverbatim + * @param p0 the first point. + * @param p1 the second point. + * @param p2 the third point. + * @param p3 the fourth point. + * @param p4 the fifth point. + * @param p5 the sixth point. + * @return the dart of the new prism incident to p0 and to + * the facet (p0,p1,p2). + */ + Dart_descriptor make_prism(const Point& p0, + const Point& p1, + const Point& p2, + const Point& p3, + const Point& p4, + const Point& p5) + { + return make_prism(create_vertex_attribute(p0), + create_vertex_attribute(p1), + create_vertex_attribute(p2), + create_vertex_attribute(p3), + create_vertex_attribute(p4), + create_vertex_attribute(p5)); + } + + /** Creates a pyramid given 5 Vertex_attribute_descriptor. + * (5 vertices, 8 edges and 5 facets) + * \verbatim + * 4 + * /|\ + * 0-|-1 + * | | | + * 3---2 + * \endverbatim + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @param h2 the third vertex handle. + * @param h3 the fourth vertex handle. + * @param h4 the fifth vertex handle. + * @return the dart of the new pyramid incident to h0 and to + * the facet (h0,h1,h2,h3). + */ + Dart_descriptor make_pyramid(Vertex_attribute_descriptor h0, + Vertex_attribute_descriptor h1, + Vertex_attribute_descriptor h2, + Vertex_attribute_descriptor h3, + Vertex_attribute_descriptor h4) + { + Dart_descriptor d1=make_quadrangle(h0, h1, h2, h3); + Dart_descriptor d2=make_triangle(h1, h0, h4); + Dart_descriptor d3=make_triangle(h0, h3, h4); + Dart_descriptor d4=make_triangle(h3, h2, h4); + Dart_descriptor d5=make_triangle(h2, h1, h4); + + return make_combinatorial_pyramid(d1, d2, d3, d4, d5); + } + + /** Creates a pyramid given 5 points. + * \verbatim + * 4 + * /|\ + * 0-|-1 + * | | | + * 3---2 + * \endverbatim + * @param p0 the first point. + * @param p1 the second point. + * @param p2 the third point. + * @param p3 the fourth point. + * @param p4 the fifth point. + * @return the dart of the new pyramid incident to p0 and to + * the facet (p0,p1,p2,p3). + */ + Dart_descriptor make_pyramid(const Point& p0, + const Point& p1, + const Point& p2, + const Point& p3, + const Point& p4) + { + return make_pyramid(create_vertex_attribute(p0), + create_vertex_attribute(p1), + create_vertex_attribute(p2), + create_vertex_attribute(p3), + create_vertex_attribute(p4)); + } + /** Compute the barycenter of a given cell. * @param adart a dart incident to the cell. * @param adim the dimension of the cell. diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder_3.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder_3.h index 8efa806a91e..d88208ad181 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder_3.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder_3.h @@ -261,7 +261,7 @@ public: prev_dart =lcc.null_descriptor; } - void add_vertex_to_facet(size_type i) + void add_vertex_to_facet(size_type i, std::vector* tabdarts = nullptr) { CGAL_assertion(ipush_back(cur_dart); } } // End of the facet. Return the first dart of this facet. @@ -325,11 +326,12 @@ public: return first_dart; } - DH add_facet(std::initializer_list l) + DH add_facet(std::initializer_list l, std::vector* tabdarts = nullptr) { + if(tabdarts != nullptr) { tabdarts->reserve(tabdarts->size() + l.size()); } begin_facet(); for (size_type i:l) - { add_vertex_to_facet(i); } + { add_vertex_to_facet(i, tabdarts); } return end_facet(); } @@ -404,5 +406,197 @@ private: } //namespace CGAL +/////////////////////////////////////////////////////////////////////////////// +/* Create an hexahedron, given the indices of its vertices (in the following +* order), the vertex must already have been added in the incremental builder. +* 3 +* /|\ +* 0-|-2 +* \|/ +* 1 +*/ +template +typename IncrementalBuilder::LCC::Dart_descriptor +make_tetrahedron_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::vector* + tabdarts=nullptr) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2}, tabdarts); + ib.add_facet({i1,i0,i3}, tabdarts); + ib.add_facet({i2,i1,i3}, tabdarts); + ib.add_facet({i0,i2,i3}, tabdarts); + return ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +/* 4 + * /|\ + * 0-|-3 + * | | | + * 1---2 + */ +template +typename IncrementalBuilder::LCC::Dart_descriptor + make_pyramid_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::size_t i4, + std::vector* + tabdarts=nullptr) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2,i3}, tabdarts); + ib.add_facet({i1,i0,i4}, tabdarts); + ib.add_facet({i2,i1,i4}, tabdarts); + ib.add_facet({i3,i2,i4}, tabdarts); + ib.add_facet({i0,i3,i4}, tabdarts); + return ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +/* 3 + * /|\ + * 4---5 + * | | | + * | 0 | + * |/ \| + * 1---2 + */ +template +typename IncrementalBuilder::LCC::Dart_descriptor + make_prism_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::size_t i4, + std::size_t i5, + std::vector* + tabdarts=nullptr) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2}, tabdarts); + ib.add_facet({i1,i0,i3,i4}, tabdarts); + ib.add_facet({i2,i1,i4,i5}, tabdarts); + ib.add_facet({i0,i2,i5,i3}, tabdarts); + ib.add_facet({i5,i4,i3}, tabdarts); + return ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +/* 7----6 + * /| /| + * 4----5 | + * | 3--|-2 + * |/ |/ + * 0----1 + */ +template +typename IncrementalBuilder::LCC::Dart_descriptor + make_hexahedron_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::size_t i4, + std::size_t i5, + std::size_t i6, + std::size_t i7, + std::vector* + tabdarts=nullptr) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2,i3}, tabdarts); + ib.add_facet({i1,i0,i4,i5}, tabdarts); + ib.add_facet({i2,i1,i5,i6}, tabdarts); + ib.add_facet({i3,i2,i6,i7}, tabdarts); + ib.add_facet({i0,i3,i7,i4}, tabdarts); + ib.add_facet({i7,i6,i5,i4}, tabdarts); + return ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +template +typename IncrementalBuilder::LCC::Dart_descriptor + make_pentagonal_prism_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::size_t i4, + std::size_t i5, + std::size_t i6, + std::size_t i7, + std::size_t i8, + std::size_t i9, + std::vector* + tabdarts=nullptr) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2,i3,i4}, tabdarts); + ib.add_facet({i1,i0,i5,i6}, tabdarts); + ib.add_facet({i2,i1,i6,i7}, tabdarts); + ib.add_facet({i3,i2,i7,i8}, tabdarts); + ib.add_facet({i4,i3,i8,i9}, tabdarts); + ib.add_facet({i0,i4,i9,i5}, tabdarts); + ib.add_facet({i9,i8,i7,i6,i5}, tabdarts); + return ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +template +typename IncrementalBuilder::LCC::Dart_descriptor + make_hexagonal_prism_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::size_t i4, + std::size_t i5, + std::size_t i6, + std::size_t i7, + std::size_t i8, + std::size_t i9, + std::size_t i10, + std::size_t i11, + std::vector* + tabdarts=nullptr) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2,i3,i4,i5}, tabdarts); + ib.add_facet({i1,i0,i6,i7}, tabdarts); + ib.add_facet({i2,i1,i7,i8}, tabdarts); + ib.add_facet({i3,i2,i8,i9}, tabdarts); + ib.add_facet({i4,i3,i9,i10}, tabdarts); + ib.add_facet({i5,i4,i10,i11}, tabdarts); + ib.add_facet({i0,i5,i11,i6}, tabdarts); + ib.add_facet({i11,i10,i9,i8,i7,i6}, tabdarts); + return ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +template +typename IncrementalBuilder::LCC::Dart_descriptor + make_generic_cell_with_builder(IncrementalBuilder& ib, + const std::vector& faces, + std::vector* + tabdarts=nullptr) +{ + ib.begin_surface(); + std::size_t i=1, end; // Start to 1 because faces[0] is the number of faces + for(; i -void make_tetrahedron_with_builder(IncrementalBuilder& ib, - std::size_t i0, - std::size_t i1, - std::size_t i2, - std::size_t i3) -{ - ib.begin_surface(); - ib.add_facet({i0,i1,i2}); - ib.add_facet({i1,i0,i3}); - ib.add_facet({i2,i1,i3}); - ib.add_facet({i0,i2,i3}); - ib.end_surface(); -} -/////////////////////////////////////////////////////////////////////////////// -/* 4 - * /|\ - * 0-|-3 - * | | | - * 1---2 - */ -template -void make_pyramid_with_builder(IncrementalBuilder& ib, - std::size_t i0, - std::size_t i1, - std::size_t i2, - std::size_t i3, - std::size_t i4) -{ - ib.begin_surface(); - ib.add_facet({i0,i1,i2,i3}); - ib.add_facet({i1,i0,i4}); - ib.add_facet({i2,i1,i4}); - ib.add_facet({i3,i2,i4}); - ib.add_facet({i0,i3,i4}); - ib.end_surface(); -} -/////////////////////////////////////////////////////////////////////////////// -/* 3 - * /|\ - * 4---5 - * | | | - * | 0 | - * |/ \| - * 1---2 - */ -template -void make_prism_with_builder(IncrementalBuilder& ib, - std::size_t i0, - std::size_t i1, - std::size_t i2, - std::size_t i3, - std::size_t i4, - std::size_t i5) -{ - ib.begin_surface(); - ib.add_facet({i0,i1,i2}); - ib.add_facet({i1,i0,i3,i4}); - ib.add_facet({i2,i1,i4,i5}); - ib.add_facet({i0,i2,i5,i3}); - ib.add_facet({i5,i4,i3}); - ib.end_surface(); -} -/////////////////////////////////////////////////////////////////////////////// -/* 7----6 - * /| /| - * 4----5 | - * | 3--|-2 - * |/ |/ - * 0----1 - */ -template -void make_hexahedron_with_builder(IncrementalBuilder& ib, - std::size_t i0, - std::size_t i1, - std::size_t i2, - std::size_t i3, - std::size_t i4, - std::size_t i5, - std::size_t i6, - std::size_t i7) -{ - ib.begin_surface(); - ib.add_facet({i0,i1,i2,i3}); - ib.add_facet({i1,i0,i4,i5}); - ib.add_facet({i2,i1,i5,i6}); - ib.add_facet({i3,i2,i6,i7}); - ib.add_facet({i0,i3,i7,i4}); - ib.add_facet({i7,i6,i5,i4}); - ib.end_surface(); -} /////////////////////////////////////////////////////////////////////////////// template bool test_ib(const char* filename) diff --git a/Linear_cell_complex/test/Linear_cell_complex/Linear_cell_complex_vtk_io_test.cpp b/Linear_cell_complex/test/Linear_cell_complex/Linear_cell_complex_vtk_io_test.cpp new file mode 100644 index 00000000000..179961092f5 --- /dev/null +++ b/Linear_cell_complex/test/Linear_cell_complex/Linear_cell_complex_vtk_io_test.cpp @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Linear_cell_complex_for_combinatorial_map<3, 3> LCC; + +bool test_file(const char* filename) +{ + LCC lcc1, lcc2; + std::vector vertex_scalars1, vertex_scalars2; + std::vector volume_scalars1, volume_scalars2; + + bool res=CGAL::IO::read_VTK(filename, lcc1); + if(!res) + { + std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK in test_file"<(i); } + + std::size_t nb_volumes=0; + for(auto itvol=lcc1.one_dart_per_cell<3>().begin(), + itvolend=lcc1.one_dart_per_cell<3>().end(); itvol!=itvolend; ++itvol) + { ++nb_volumes; } + + volume_scalars1.reserve(nb_volumes); + for(auto itvol=lcc1.one_dart_per_cell<3>().begin(), + itvolend=lcc1.one_dart_per_cell<3>().end(); itvol!=itvolend; ++itvol) + { + std::size_t nbv=lcc1.template one_dart_per_incident_cell<0,3>(itvol).size(); + volume_scalars1.push_back(nbv); + } + + res=CGAL::IO::write_VTK("output.vtk", lcc1, + &vertex_scalars1, &volume_scalars1); + if(!res) + { + std::cerr<<"[ERROR] LCC_vtk_io_test error write_VTK in test_file"< vertex_scalars; + std::vector volume_scalars; + + /// Read the last file generated by test_file("data/beam-with-mixed-cells.vtk") + /// i.e. beam-with-mixed-cells.vtk with point and cells scalars. + if(!CGAL::IO::read_VTK("output.vtk", lcc, + &vertex_scalars, &volume_scalars) || + vertex_scalars.size()!=719 || volume_scalars.size()!=615) + { + std::cerr<<"[ERROR] LCC_vtk_io_test error read_VTK in test_different_scalars"< + + VTK Legacy File Format for Linear Cell Complex + + + Input + 3D Volumetric Mesh + `CGAL::Linear_cell_complex_for_combinatorial_map<3,3>` + \link PkgLinearCellComplexRefIOVTK `CGAL::IO::read_VTK()` \endlink + + + Output + 3D Volumetric Mesh + `CGAL::Linear_cell_complex_for_combinatorial_map<3,3>` + \link PkgLinearCellComplexRefIOVTK `CGAL::IO::Write_VTK()` \endlink + + \section IOStreamAvizo Avizo File Format diff --git a/Stream_support/doc/Stream_support/dependencies b/Stream_support/doc/Stream_support/dependencies index 5437858c829..9e6ac2f626c 100644 --- a/Stream_support/doc/Stream_support/dependencies +++ b/Stream_support/doc/Stream_support/dependencies @@ -3,6 +3,7 @@ Arrangement_on_surface_2 BGL Constrained_triangulation_3 Kernel_23 +Linear_cell_complex Manual Mesh_2 Mesh_3